Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should we have a way to create a task that can escape the global sync scope? #26855

Open
bradcray opened this issue Mar 6, 2025 · 2 comments

Comments

@bradcray
Copy link
Member

bradcray commented Mar 6, 2025

[loosely related to https://github.com//issues/16424]

@jabraham17 ran into an interesting pattern today in which:

  • they have a data structure that creates a daemon task that spends most of its life blocked on a sync var
  • the structure's deinit routine tells the daemon task to stop running
  • the data structure is user-facing, and intended to be used at any scope
  • however, using it at module scope results in a hang today because program teardown is:
    • sync on all tasks, waiting for them to finish
    • then run module deinitialization
  • this causes a hang because the sync blocks waiting for the daemon to finish, but it won't finish until the module deinit

We briefly discussed whether reversing the order of module deinit and the global sync would fix the issue, and while it would, it could cause problems for other programs, like:

var A: [1..1000] real;

begin { sleep(10 minutes);  A = 1; }

since we could deinitialize 'A' before the task accesses A, causing a memory fault.

This led us to discuss the possibility of annotating a task as being exempt from the traditional global sync, such that program teardown would look like:

  • sync on all tasks other than these that are exempty
  • run module initialization
  • either:
    • sync on all remaining tasks
    • assert that there are no remaining tasks and print an error if there are (implying that some library or data structure didn't clean itself up properly
@mppf
Copy link
Member

mppf commented Mar 6, 2025

A potential workaround to handle this is to create an actual pthread for the suspended task. (I think that might be a good strategy for @jabraham17's current challenges).

FWIW, I like the idea of de-registering a task / making it exempt from sync. However, that is complicated when it comes to program termination. We have to a) know that de-registered tasks have been told to wrap up and b) know that wrap-up has completed for all de-registered tasks. Potentially, we could make these issues be the user's problem in these cases.

@bradcray
Copy link
Member Author

bradcray commented Mar 6, 2025

A potential workaround to handle this is to create an actual pthread for the suspended task.

Yeah, I should've mentioned that Paul suggested this on the walk home last night, and I believe Jade is planning to give it a try today.

We have to a) know that de-registered tasks have been told to wrap up and b) know that wrap-up has completed for all de-registered tasks. Potentially, we could make these issues be the user's problem in these cases.

I'd consider (a) to be the user's problem, and was imagining the proposed "additional outer sync / assert" to help ensure (b) (where lack of progress or an assertion failure would be a user's, or library writer's problem as well—but at least we could alert them to the issue rather than just hanging mysteriously).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants