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

Chan.recv seems to remove domain from pool #126

Open
nikolaushuber opened this issue Apr 23, 2024 · 1 comment
Open

Chan.recv seems to remove domain from pool #126

nikolaushuber opened this issue Apr 23, 2024 · 1 comment

Comments

@nikolaushuber
Copy link

I have written a small example to test the interaction of Chan.recv and task pools:

module T = Domainslib.Task 
module C = Domainslib.Chan 
let num_domains = Sys.argv.(1) |> int_of_string 

let print_mutex = Mutex.create () 

let print s = 
  Mutex.lock print_mutex; 
  print_endline s; 
  Mutex.unlock print_mutex

let ping = C.make_bounded 1 
let pong = C.make_bounded 1 
let pang = C.make_unbounded ()  


let run_async name p () = 
  let rec f () : unit = 
    C.recv p; 
    print name;
    C.send pang (); 
    f () 
  in 
  f () 

let () = 
  let pool = T.setup_pool ~num_domains:(num_domains - 1) () in  
  T.run pool (fun _ -> 
    let _ = T.async pool (run_async "A" ping) in 
    let _ = T.async pool (run_async "B" pong) in 


    while true do 
      C.send ping (); 
      C.send pong (); 
      C.recv pang
    done
  ); 
  T.teardown_pool pool 

The output of the program above depends on the input parameter num_domains. When called with 1, the program immediately blocks. When called with 2, it outputs "A" "A" and then blocks. If called with >= 3 it runs indefinitely, as expected. It seems to me, that a call to Chan.recv on an empty channel effectively blocks and removes the current domain from the pool.

Is that the expected behaviour?

@polytypic
Copy link
Contributor

I haven't gone through all the details, but I believe the problem is that Chan uses Stdlib Mutex and Condition to block. The problem with those is that they prevent other fibers (spawned with async) from running. Ideally your example would be able to run with just one domain (like the example I posted on discuss using Kcas). In the future, perhaps, domainslib internals get rewritten using something like Picos and everything will just work™️. 😄

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

No branches or pull requests

2 participants