Module Subatomic.Loc

A Subatomic.Loc.t is the subatomic analog of Atomic.Loc.t, i.e. a subatomic reference to a field of a record.

type !('a : value_or_null) t = 'a Basement.Subatomic.Loc.t
include sig ... end
val sexp_of_t : 'a. ('a -> Sexplib0.Sexp.t) -> 'a t -> Sexplib0.Sexp.t
val unsafe_of_atomic_loc : 'a. 'a Atomic.Loc.t -> 'a t

Convert an Atomic.Loc.t to a Subatomic.Loc.t. Currently, there is no compiler support for subatomic fields, but we can mimic it using atomic fields.

Correct usage of this function is to have a record with an atomic field, and to only ever access that field like

  type t = { mutable field : int [@atomic] }

  let get_field t = Subatomic.Loc.unsafe_of_atomic_loc [%atomic.loc t.field]

Accessing or mutating the field in any other way is unsound.

val get : 'a. 'a t @ local -> 'a

Read the current value of a subatomic.

  • get performs a non-atomic read on an uncontended subatomic.
  • get [@synchro atomic] and Shared.get perform an atomic read on a shared subatomic.
val set : 'a. 'a t @ local -> ('a -> unit) @ local

Update the current value of a subatomic.

  • set performs a non-atomic write on an uncontended subatomic.
  • set [@synchro atomic] and Shared.set perform an atomic write on a shared subatomic.
val exchange : 'a. 'a t @ local -> ('a -> 'a) @ local

Update the current value of a subatomic, and return the previous value.

  • update performs a non-atomic read/write on an uncontended subatomic.
  • update [@synchro atomic] and Shared.update perform an atomic read/write on a shared subatomic.
val compare_and_set : 'a. 'a t @ local -> (if_phys_equal_to:'a -> (replace_with:'a -> Atomic.Compare_failed_or_set_here.t) @ local) @ local

If the current value of the subatomic is phys_equal to if_phys_equal, then update it to replace_with and return Set_here; otherwise, return Compare_failed (with the subatomic left unchanged).

  • compare_and_set performs a non-atomic read/compare/write on an uncontended subatomic.
  • compare_and_set [@synchro atomic] and Shared.compare_and_set perform an atomic read/compare/write on a shared subatomic.
val compare_exchange : 'a. 'a t @ local -> (if_phys_equal_to:'a -> (replace_with:'a -> 'a) @ local) @ local

If the current value of the subatomic is phys_equal to if_phys_equal, then update it to replace_with and return the previous value; otherwise, return current (unchanged) value.

  • compare_exchange performs a non-atomic read/compare/write on an uncontended subatomic.
  • compare_exchange [@synchro atomic] and Shared.compare_exchange perform an atomic read/compare/write on a shared subatomic.
val update : 'a. 'a t @ local -> (pure_f:('a -> 'a) @ local -> unit) @ local

Update t to be the result of pure_f (get t); if t is changed before the whole operation is complete, retry until success. pure_f may be called multiple times, so should be free of side effects.

  • update performs a non-atomic read/compare/write on an uncontended subatomic. pure_f still may be called multiple times due to nonportable threading or if pure_f is not actually pure.
  • update [@synchro atomic] and Shared.update perform an atomic read/compare/write on a shared subatomic.
val get_and_update : 'a. 'a t @ local -> (pure_f:('a -> 'a) @ local -> 'a) @ local

Update t to be the result of pure_f (get t), and return the old value; if t is changed before the whole operation is complete, retry until success. pure_f may be called multiple times, so should be free of side effects.

  • get_and_update performs a non-atomic read/compare/write on an uncontended subatomic. pure_f still may be called multiple times due to nonportable threading or if pure_f is not actually pure.
  • get_and_update [@synchro atomic] and Shared.get_and_update perform an atomic read/compare/write on a shared subatomic.
val fetch_and_add : int t @ local -> (int -> int) @ local

Increments the value of a subatomic by the given value, and return the previous value (before the increment).

  • fetch_and_add performs a non-atomic update on an uncontended subatomic.
  • fetch_and_add [@synchro atomic] and Shared.fetch_and_add perform an atomic update on a shared subatomic.
val add : int t @ local -> (int -> unit) @ local

Add the given value to the subatomic.

  • add performs a non-atomic update on an uncontended subatomic.
  • add [@synchro atomic] and Shared.add perform an atomic update on a shared subatomic.
val sub : int t @ local -> (int -> unit) @ local

Subtract the given value from the subatomic.

  • sub performs a non-atomic update on an uncontended subatomic.
  • sub [@synchro atomic] and Shared.sub perform an atomic update on a shared subatomic.
val logand : int t @ local -> (int -> unit) @ local

Apply bitwise-and of the given value to the subatomic.

  • logand performs a non-atomic update on an uncontended subatomic.
  • logand [@synchro atomic] and Shared.logand perform an atomic update on a shared subatomic.
val logor : int t @ local -> (int -> unit) @ local

Apply bitwise-or of the given value to the subatomic.

  • logor performs a non-atomic update on an uncontended subatomic.
  • logor [@synchro atomic] and Shared.logor perform an atomic update on a shared subatomic.
val logxor : int t @ local -> (int -> unit) @ local

Apply bitwise-xor of the given value to the subatomic.

  • logxor performs a non-atomic update on an uncontended subatomic.
  • logxor [@synchro atomic] and Shared.logxor perform an atomic update on a shared subatomic.
val incr : int t @ local -> unit

Increment a subatomic by 1.

  • incr performs a non-atomic update on an uncontended subatomic.
  • incr [@synchro atomic] and Shared.incr perform an atomic update on a shared subatomic.
val decr : int t @ local -> unit

Decrement a subatomic by 1.

  • decr performs a non-atomic update on an uncontended subatomic.
  • decr [@synchro atomic] and Shared.decr perform an atomic update on a shared subatomic.
module Shared : sig ... end