From 04eafb04b1bc3fcd2e45339b0b6fa4cc8c725915 Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Fri, 9 Jun 2023 17:42:36 -0400 Subject: [PATCH] TLS: some documentation --- src/thread_local.ml | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/thread_local.ml b/src/thread_local.ml index 06d54bcb..9578ffdf 100644 --- a/src/thread_local.ml +++ b/src/thread_local.ml @@ -2,7 +2,7 @@ module A = Opentelemetry_atomic.Atomic type key = int -let get_key_ () : key = Thread.id (Thread.self ()) +let[@inline] get_key_ () : key = Thread.id (Thread.self ()) module Key_map_ = Map.Make (struct type t = key @@ -11,10 +11,17 @@ module Key_map_ = Map.Make (struct end) type 'a t = 'a ref Key_map_.t A.t +(** The TLS variable is made of a global atomic reference + (which has very low contention: it's modified only when a + thread is started/stopped). + + Inside that atomic variable, is a map from thread ID to a mutable [ref] + holding the actual data. Because this [ref] is only ever accessed + by the thread with this given ID, it's safe to modify. *) let create () : _ t = A.make Key_map_.empty -let get_exn (self : _ t) = +let[@inline] get_exn (self : _ t) = let m = A.get self in let key = get_key_ () in !(Key_map_.find key m) @@ -30,7 +37,7 @@ let[@inline] remove_ref_ self key : unit = let m' = Key_map_.remove key m in not (A.compare_and_set self m m') do - () + Thread.yield () done (* get or associate a reference to [key], and return it. @@ -48,7 +55,7 @@ let get_or_create_ref_ (self : _ t) key ~v : _ ref * _ option = let m' = Key_map_.add key r m in not (A.compare_and_set self m m') do - () + Thread.yield () done; r, None