Documentation for sub cas, assembled from the following types:
multi sub cas(atomicint is rw, int , int )multi sub cas(atomicint is rw, Int() , Int() )multi sub cas(atomicint is rw, )
Performs an atomic compare and swap of the native integer value in location
$target. The first two forms have semantics like:
my int = ;if ==return ;
Except it is performed as a single hardware-supported atomic instruction, as if all memory access to
$target were blocked while it took place. Therefore it is safe to attempt the operation from multiple threads without any other synchronization. For example:
my atomicint = 0;await startxx 4
Will reliably only ever print
Master! one time, as only one of the threads will be successful in changing the 0 into a 1.
$value will be coerced to
Int and unboxed if needed. An exception will be thrown if the value cannot be represented as a 64-bit integer. If the size of
atomicint is only 32 bits then the values will be silently truncated to this size.
The third form, taking a code object, will first do an atomic fetch of the current value and invoke the code object with it. It will then try to do an atomic compare and swap of the target, using the value passed to the code object as
$expected and the result of the code object as
$value. If this fails, it will read the latest value, and retry, until a CAS operation succeeds. Therefore, an atomic multiply of an
$i by 2 could be implemented as:
cas , -> int
If another thread changed the value while
$current * 2 was being calculated then the block would be called again with the latest value for a further attempt, and this would be repeated until success.