Await_sync.AwaitableAn awaitable represents an atomic location whose change of value can be awaited upon. Awaitables can be used to implement all kinds of blocking data structures, including locks, condition variables, and blocking queues.
val make :
'a. ?padded:bool @ local ->
('a @ portable contended ->
'a t) @ local @@ portablemake v creates a new awaitable atomic reference with the given initial value v.
The optional padded argument specifies whether to pad the data structure to avoid false sharing. See Atomic.make for a longer explanation.
val get : 'a. 'a t @ local -> 'a @ portable contended @@ portableget t gets the current value of the awaitable atomic reference.
val set :
'a. 'a t @ local ->
('a @ portable contended ->
unit) @ local @@ portableset t v sets a new value v for the awaitable atomic reference.
val exchange :
'a. 'a t @ local ->
('a @ portable contended ->
'a @ portable contended) @ local @@ portableexchange t v sets a new value v for the awaitable atomic reference and returns the current value.
module Compare_failed_or_set_here =
Portable_kernel.Atomic.Compare_failed_or_set_hereval compare_and_set :
'a. 'a t @ local ->
(if_phys_equal_to:'a @ portable contended ->
(replace_with:'a @ portable contended ->
Compare_failed_or_set_here.t) @ local) @ local @@ portablecompare_and_set t ~if_phys_equal_to:seen ~replace_with:v sets the new value of t to v only if its current value is physically equal to seen -- the comparison and the set occur atomically. Returns true if the comparison succeeded (so the set happened) and false otherwise.
val compare_exchange :
'a. 'a t @ local ->
(if_phys_equal_to:'a @ portable contended ->
(replace_with:'a @ portable contended ->
'a @ portable contended) @ local) @ local @@ portablecompare_exchange t ~if_phys_equal_to:seen ~replace_with:v sets the new value of s to v only if its current value is physically equal to seen -- the comparison and the set occur atomically. Returns the previous value.
val fetch_and_add : int t @ local -> (int -> int) @ local @@ portablefetch_and_add t n atomically increments the value of t by n, and returns the current value (before the increment).
val incr : int t @ local -> unit @@ portableincr t atomically increments the value of t by 1.
val decr : int t @ local -> unit @@ portabledecr t atomically decrements the value of t by 1.
val update :
'a. 'a t @ local ->
(pure_f:('a @ portable contended -> 'a @ portable contended) @ local ->
unit) @ local @@ portableupdate t ~pure_f atomically updates t to be the result of pure_f (get t). pure_f may be called multiple times, so should be free of side effects.
val get_and_update :
'a. 'a t @ local ->
(pure_f:('a @ portable contended -> 'a @ portable contended) @ local ->
'a @ portable contended) @ local @@ portableget_and_update t ~pure_f atomically updates t to be the result of pure_f (get t). pure_f may be called multiple times, so should be free of side effects. Returns the old value.
val await :
'a. Await_kernel.Await.t @ local ->
('a t @ local ->
(until_phys_unequal_to:'a @ portable contended ->
[ `Signaled | `Terminated ] await) @ local) @ local @@ portableawait w t ~until_phys_unequal_to:v suspends the caller until the awaitable t is explicitly signaled and/or has a value physically unequal to v.
The return value is Signaled in case the await was woken up due to a signal or broadcast on the awaitable. Otherwise the return value is Terminated.
This operation is subject to the ABA problem. An await for a value other than A may not return after the awaitable is signaled while having the value B, because at a later point the awaitable has again the value A. Furthermore, by the time an await for value other than A returns, the awaitable might already again have the value A.
Atomic operations that change the value of an awaitable do not implicitly wake up awaiters.
await establishes a happens-before relationship with any reads and writes on the current thread that precede it, and the comparison of the current value of the awaitable t with the given value v.
val await_or_cancel :
'a. Await_kernel.Await.t @ local ->
(Await_kernel.Cancellation.t @ local ->
('a t @ local ->
(until_phys_unequal_to:'a @ portable contended ->
[ `Signaled | `Terminated | `Canceled ] await) @ local) @ local) @ local @@ portableawait_or_cancel w c t ~until_phys_unequal_to:v is like await w t ~until_phys_unequal_to:v, but the caller will also be resumed in case the cancellation token c becomes canceled.
The return value is Signaled in case the await was woken up due to a signal or broadcast on the awaitable. Otherwise the return value is either Terminated in case w is terminated, and Canceled in case c is canceled.
val signal : 'a. 'a t @ local -> unit @@ portablesignal t tries to wake up at least one awaiter on the awaitable location t.
val broadcast : 'a. 'a t @ local -> unit @@ portablebroadcast t tries to wake up all the awaiters on the awaitable location t.
module Awaiter : sig ... endAn expert interface that allows an await to be setup separately from suspending the thread of control. This makes it possible to e.g. implement condition variables, which requires setting up the await before unlocking the associated mutex, and also makes it possible to await for one of many things.
module For_testing : sig ... end