ExtCore
ExtCore copied to clipboard
added reference cells with atomic/interlocked semantics
Proposal
This PR introduces atomic cells (similar to F# ref cells), that enable thread-safe atomic operations - based on Interlocked and Volatile capabilities, without expensive locking (with caveats regarding float/int64 on 32 bit machines) - for following types: int, int64, float, float32, bool (via int mapping) and reference types.
API
API is modeled to look like standard F# 'a ref cells: see tests for examples.
let a = Atomic.int 1 // atomic cell for int type
let b = Atomic.int64 1L // atomic cell for int64 type
let c = Atomic.float 1.0 // atomic cell for float type
let d = Atomic.float32 1.0f // atomic cell for float32 type
let e = Atomic.bool true // atomic cell for bool type
let f = Atomic.ref Map.empty // atomic cell for reference type
let x = Atomic.inc a // atomically increments cell's content and returns it
let y = Atomic.dec b // atomically decrements cell's content and returns it
if a |> Atomic.cas 1 2 then
print "Successfully managed to swap cell's value"
else
print "Didn't swap cell's value: current and expected values differ"
/// Atomically updates content of the cell using given function.
/// In case of clash (multiple concurrent updates) it will retry until succeeded.
/// Returns a value stored directly before an update.
let oldValue = f |> Atomic.update (Map.add "key" "value")
open ExtCore.Atomic.Operators
let oldValue = f := newValue // replaces internal value of atomic cell, returning the previous one
let value = !f // unwraps the atomic cell, returning a stored value