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

Support spawning blocking Riot processes #67

Open
leostera opened this issue Mar 14, 2024 · 2 comments
Open

Support spawning blocking Riot processes #67

leostera opened this issue Mar 14, 2024 · 2 comments
Labels
enhancement New feature or request help wanted Extra attention is needed
Milestone

Comments

@leostera
Copy link
Collaborator

In many cases we want to execute some work that does not play well with Riot's scheduling, that wouldn't play well with work-stealing, that needs to use libraries that don't play well with Riot's IO, or that simply need to aggressively busy-wait to meet certain real-time deadlines (like rendering a frame within 16ms).

For those use-cases, spawn, spawn_pinned, and process_flag (Priority High) are not suitable solutions since they all expect the process to not starve the scheduler, to be friendly to work-stealing, and to use Riot's IO layer.

Instead, we'd like to implement spawn_blocking fn which will create a new process, like any other process, but allocate an entire OS thread to execute it.

The signature of this function would be identical to spawn:

val spanw_blocking : (unit -> unit) -> Pid.t

Implementation Notes

To do this, we'd start by adding the signature to the riot.mli file, and working backwards from there until we reach the imports.ml module where spawn and spawn_pinned are defined. This function should probably call into a function like Pool.spawn_blocking that will do the work of setting up a new scheduler just for this process, and updating the list of domains in the global pool variable.

Then we'd want the pool type inside the scheduler.ml module to be extended to include a list of Domains that have been spawned for these blocking processes:

type pool = {
 (* ... *)
 blocking_processes: unit Domain.t list Atomic.t;
}

It is important that we make this list atomic to make sure that multiple processes spawning new blocking processes from different scheduling threads do not override the domain handlers.

The final set of changes could look a little bit like this, but this list is not a set of requirements and other implementations are welcome:

  • new spawn_blocking function with its signature and documentation on Riot.mli
  • new Pool.spawn_blocking function that uses a new Blocking_scheduler in a new Domain
  • new blocking_processes attribute on the pool type to keep track of new domains
  • new Blocking_scheduler that wraps a Scheduler and adds logic for removing the domains from the blocking_processes domain list

Hope this helps!

@leostera leostera added enhancement New feature or request help wanted Extra attention is needed labels Mar 14, 2024
@leostera leostera added this to the riot/phase-1 milestone Mar 14, 2024
@omnisci3nce
Copy link

omnisci3nce commented Mar 15, 2024

Do you have any ideas what might make a good small test I can add or an example of it working correctly to test its behaviour in the repo?

@leostera
Copy link
Collaborator Author

Hmm, off the top of my head we could spin up a blocking process to run some function (eg. count up to max int in a hot loop), and set up a receive (with timeout) on the main process so we terminate the test when the blocking process sends the max int value back in.

I don't think its a particularly good test, but at least it'd exercise that we can have a blocking process running work, and regular processes doing work at the same time.

@leostera leostera modified the milestones: riot/phase-1, 0.0.9 Mar 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants