Picos_std_awaitable.Awaitable
An awaitable atomic location.
This module provides a superset of the Stdlib Atomic
API with more or less identical performance. The main difference is that a non-padded awaitable location takes an extra word of memory. Additionally a futex-like API provides the ability to await
until an awaitable location is explicitly signal
ed to potentially have a different value.
Awaitable locations can be used to implement many kinds of synchronization and communication primitives.
val make : ?padded:bool -> 'a -> 'a t
make initial
creates a new awaitable atomic location with the given initial
value.
val make_contended : 'a -> 'a t
make_contended initial
is equivalent to make ~padded:true initial
.
val get : 'a t -> 'a
get awaitable
is essentially equivalent to Atomic.get awaitable
.
val compare_and_set : 'a t -> 'a -> 'a -> bool
compare_and_set awaitable before after
is essentially equivalent to Atomic.compare_and_set awaitable before after
.
val exchange : 'a t -> 'a -> 'a
exchange awaitable after
is essentially equivalent to Atomic.exchange awaitable after
.
val set : 'a t -> 'a -> unit
set awaitable value
is equivalent to exchange awaitable value |> ignore
.
val fetch_and_add : int t -> int -> int
fetch_and_add awaitable delta
is essentially equivalent to Atomic.fetch_and_add awaitable delta
.
val incr : int t -> unit
incr awaitable
is equivalent to fetch_and_add awaitable (+1) |> ignore
.
val decr : int t -> unit
incr awaitable
is equivalent to fetch_and_add awaitable (-1) |> ignore
.
val signal : 'a t -> unit
signal awaitable
tries to wake up one fiber await
in on the awaitable location.
🐌 Generally speaking one should avoid calling signal
too frequently, because the queue of awaiters is stored separately from the awaitable location and it takes a bit of effort to locate it. For example, calling signal
every time a value is added to an empty data structure might not be optimal. In many cases it is faster to explicitly mark the potential presence of awaiters in the data structure and avoid calling signal
when it is definitely known that there are no awaiters.
val broadcast : 'a t -> unit
broadcast awaitable
tries to wake up all fibers await
ing on the awaitable location.
🐌 The same advice as with signal
applies to broadcast
. In addition, it is typically a good idea to avoid potentially waking up large numbers of fibers as it can easily lead to the thundering herd phenomena.
val await : 'a t -> 'a -> unit
await awaitable before
suspends the current fiber until the awaitable is explicitly signal
ed and has a value other than before
.
⚠️ This operation is subject to the ABA problem. An await
for 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.
module Awaiter : sig ... end
Low level interface for more flexible waiting.