From 7a36783e8b57fe7b52d1cec80f855128d95a4cfd Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Sat, 28 Oct 2023 11:59:20 -0400 Subject: [PATCH] perf: also use the main domain, along with n-1 other ones we always keep a thread alive on the main domain as a worker for new tasks, but other domains can still come and go to manage resources properly in case a pool is started and used only for a short while. --- src/d_pool_.ml | 12 +++++++++--- src/domain_.ml | 2 ++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/d_pool_.ml b/src/d_pool_.ml index fb78535b..d12a4f6a 100644 --- a/src/d_pool_.ml +++ b/src/d_pool_.ml @@ -18,9 +18,7 @@ type worker_state = { including a work queue and a thread refcount; and the domain itself, if any, in a separate option because it might outlive its own state. *) let domains_ : (worker_state option * Domain_.t option) Lock.t array = - (* number of domains we spawn. Note that we spawn n-1 domains - because there already is the main domain running. *) - let n = max 1 (Domain_.recommended_number () - 1) in + let n = max 1 (Domain_.recommended_number ()) in Array.init n (fun _ -> Lock.create (None, None)) (** main work loop for a domain worker. @@ -84,6 +82,14 @@ let work_ idx (st : worker_state) : unit = done; () +(* special case for main domain: we start a worker immediately *) +let () = + assert (Domain_.is_main_domain ()); + let w = { th_count = Atomic_.make 1; q = Bb_queue.create () } in + (* thread that stays alive *) + ignore (Thread.create (fun () -> work_ 0 w) () : Thread.t); + domains_.(0) <- Lock.create (Some w, None) + let[@inline] n_domains () : int = Array.length domains_ let run_on (i : int) (f : unit -> unit) : unit = diff --git a/src/domain_.ml b/src/domain_.ml index 60d1e669..3050282f 100644 --- a/src/domain_.ml +++ b/src/domain_.ml @@ -9,6 +9,7 @@ let get_id (self : t) : int = (Domain.get_id self :> int) let spawn : _ -> t = Domain.spawn let relax = Domain.cpu_relax let join = Domain.join +let is_main_domain = Domain.is_main_domain [@@@ocaml.alert "+unstable"] [@@@else_] @@ -21,5 +22,6 @@ let get_id (self : t) : int = Thread.id self let spawn f : t = Thread.create f () let relax () = Thread.yield () let join = Thread.join +let is_main_domain () = true [@@@endif]