From 942a56c87979d27cafe5a495e46fffac55a8688c Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Wed, 17 Dec 2025 15:51:07 -0500 Subject: [PATCH] use mutex again to protect rand_bytes state shard over 8 distinct random generators, though. --- src/core/rand_bytes.ml | 31 +++++++++++++++++++---------- src/{client => util}/util_mutex.ml | 0 src/{client => util}/util_mutex.mli | 0 3 files changed, 20 insertions(+), 11 deletions(-) rename src/{client => util}/util_mutex.ml (100%) rename src/{client => util}/util_mutex.mli (100%) diff --git a/src/core/rand_bytes.ml b/src/core/rand_bytes.ml index c90c1a72..8b831556 100644 --- a/src/core/rand_bytes.ml +++ b/src/core/rand_bytes.ml @@ -1,38 +1,47 @@ -let initialized_ = Atomic.make false +open struct + let rand = Array.init 8 (fun _ -> Random.State.make_self_init ()) -let[@inline never] actually_init () = Random.self_init () + let mutex = Array.init 8 (fun _ -> Mutex.create ()) -let[@inline] maybe_init () = - if not (Atomic.exchange initialized_ true) then actually_init () + let ( let@ ) = ( @@ ) +end + +(** What rand state do we use? *) +let[@inline] shard () : int = Thread.id (Thread.self ()) land 0b111 let default_rand_bytes_8 () : bytes = - maybe_init (); + let shard = shard () in + let@ () = Util_mutex.protect mutex.(shard) in + let rand = rand.(shard) in + let b = Bytes.create 8 in for i = 0 to 1 do (* rely on the stdlib's [Random] being thread-or-domain safe *) - let r = Random.bits () in + let r = Random.State.bits rand in (* 30 bits, of which we use 24 *) Bytes.set b (i * 3) (Char.chr (r land 0xff)); Bytes.set b ((i * 3) + 1) (Char.chr ((r lsr 8) land 0xff)); Bytes.set b ((i * 3) + 2) (Char.chr ((r lsr 16) land 0xff)) done; - let r = Random.bits () in + let r = Random.State.bits rand in Bytes.set b 6 (Char.chr (r land 0xff)); Bytes.set b 7 (Char.chr ((r lsr 8) land 0xff)); b let default_rand_bytes_16 () : bytes = - maybe_init (); + let shard = shard () in + let@ () = Util_mutex.protect mutex.(shard) in + let rand = rand.(shard) in + let b = Bytes.create 16 in for i = 0 to 4 do - (* rely on the stdlib's [Random] being thread-or-domain safe *) - let r = Random.bits () in + let r = Random.State.bits rand in (* 30 bits, of which we use 24 *) Bytes.set b (i * 3) (Char.chr (r land 0xff)); Bytes.set b ((i * 3) + 1) (Char.chr ((r lsr 8) land 0xff)); Bytes.set b ((i * 3) + 2) (Char.chr ((r lsr 16) land 0xff)) done; - let r = Random.bits () in + let r = Random.State.bits rand in Bytes.set b 15 (Char.chr (r land 0xff)); (* last byte *) b diff --git a/src/client/util_mutex.ml b/src/util/util_mutex.ml similarity index 100% rename from src/client/util_mutex.ml rename to src/util/util_mutex.ml diff --git a/src/client/util_mutex.mli b/src/util/util_mutex.mli similarity index 100% rename from src/client/util_mutex.mli rename to src/util/util_mutex.mli