For Development HEAD DRAFTSearch (procedure/syntax/module):

11.62 srfi.230 - アトミックな操作

Module: srfi.230

This srfi defines a set of data types and operations that perform certain dereference and modification operations atomically. The interface is similar to C++’s atomic operation library.

The srfi also defines sevaral relaxed memory order constraints. In the current Gauche operations, those operation involves VM-level procedure calls and all operations are done with sequentially consistent order, no matter what memory-order argument is. Other Scheme implementations that inline-compiles these operations may emit more efficient code with relaxed memory orders.

Gauche’s implementation does utilize lock-free atomic operations, so they may still faster than using mutexes (see Mutex).

Memory order

Macro: memory-order symbol

[SRFI-230]{srfi.230} If symbol must be one of the following symbols specifying memory order: relaxed, aquire, release, aquire-release, or sequentially-consistent, it is returned as is. Otherwise, a syntax error is thrown. This can be used instaed of quote to statically check the validity of the symbol.

In Gauche’s current implementation, all atomic operations are done in sequentially-consistent, no matter what memory order you specify. Portable code may use more relaxed order and expect it runs more efficiently on other implementations.

Function: memory-order? obj

[SRFI-230]{srfi.230} Returns #t if obj is one of the valid symbols as memory order, #f otherwise.

Atomic flag

An atomic flag is a storage that holds a boolean value. The initial value is #f. Referencing the flag can only be done with atomic-flag-test-and-set!, which turns the value to #t.

Function: make-atomic-flag

[SRFI-230]{srfi.230} Returns a newly created atomic flag. Its value is #f.

Function: atomic-flag? obj

[SRFI-230]{srfi.230} Returns #t if obj is an atomic flag, #f otherwise.

Function: atomic-flag-test-and-set! flag :optional memory-order

[SRFI-230]{srfi.230} Set flag’s value to #t and returns its previous value, atomically.

Gauche uses sequentially consistent order regardless of the memory-order argument.

Function: atomic-flag-clear! flag :optional memory-order

[SRFI-230]{srfi.230} Reset flag’s value to #f.

Gauche uses sequentially consistent order regardless of the memory-order argument.

Atomic box

An atomic box is a storage that holds a Scheme value.

Function: make-atomic-box val

[SRFI-230]{srfi.230} Creates a new atomic box whose value is val.

Function: atomic-box? obj

[SRFI-230]{srfi.230} Returns #t if obj is an atomic box, #f otherwise.

Function: atomic-box-ref abox :optional memory-order

[SRFI-230]{srfi.230} Returns the content of atomic box abox.

Gauche uses sequentially consistent order regardless of the memory-order argument.

Function: atomic-box-set! abox val :optional memory-order

[SRFI-230]{srfi.230} Sets val as the content of atomic box abox, and returns an undefined value.

Gauche uses sequentially consistent order regardless of the memory-order argument.

Function: atomic-box-swap! abox val :optional memory-order

[SRFI-230]{srfi.230} Sets val as the content of atomic box abox, and returns the previous content, atomically.

Gauche uses sequentially consistent order regardless of the memory-order argument.

(define b (make-atomic-box 'foo))

(atomic-box-swap! box 'bar)   ⇒ foo
(atomic-box-ref box)          ⇒ bar
Function: atomic-box-compare-and-swap! abox expected desired :optional memory-order

[SRFI-230]{srfi.230} Compares the content of atomic box abox and expected. If both are the same (in eq? sense), sets desired as the new value of abox. Returns the previous content. All operations are done atomically.

You can know the content is altered if (eq? return-value expected) is true.

Gauche uses sequentially consistent order regardless of the memory-order argument.

Atomic fxbox

An atomic fxbox is a storage that can hold a fixnum. It provides atomic fetcy-compute-store opertaions as well.

Function: make-atomic-fxbox fxval

[SRFI-230]{srfi.230} Creates a new atomic box whose value is fxval.

Function: atomic-fxbox? obj

[SRFI-230]{srfi.230} Returns #t if obj is an atomic fxbox, #f otherwise.

Function: atomic-fxbox-ref fxbox :optional memory-order

[SRFI-230]{srfi.230} Returns the content of atomic fxbox fxbox.

Gauche uses sequentially consistent order regardless of the memory-order argument.

Function: atomic-fxbox-set! fxbox fxval :optional memory-order

[SRFI-230]{srfi.230} Sets fxval as the content of atomic fxbox fxbox, and returns an undefined value.

Gauche uses sequentially consistent order regardless of the memory-order argument.

Function: atomic-fxbox-swap! fxbox fxval :optional memory-order

[SRFI-230]{srfi.230} Sets fxval as the content of atomic fxbox fxbox, and returns the previous content, atomically.

Gauche uses sequentially consistent order regardless of the memory-order argument.

Function: atomic-fxbox-compare-and-swap! fxbox expected desired :optional memory-order

[SRFI-230]{srfi.230} Compares the content of atomic fxbox fxbox and expected. If both are the same (in eq? sense), sets desired as the new value of fxbox. Returns the previous content. All operations are done atomically.

You can know the content is altered if (eq? return-value expected) is true.

Gauche uses sequentially consistent order regardless of the memory-order argument.

Function: atomic-fxbox+/fetch! fxbox fxval :optional memory-order
Function: atomic-fxbox-/fetch! fxbox fxval :optional memory-order
Function: atomic-fxbo-and/fetch! fxbox fxval :optional memory-order
Function: atomic-fxbo-ior/fetch! fxbox fxval :optional memory-order
Function: atomic-fxbo-xor/fetch! fxbox fxval :optional memory-order

[SRFI-230]{srfi.230} Retrieves the value of atomic fxbox fxbox, calculates (+ prev-val fxval), (- prev-val fxval), (logand prev-val fxval), (logior prev-val fxval), or (logxor prev-val fxval), respectively, then store the result to fxbox, and returns the previsou value. The entire sequence of operations are done atomically.

This does not check the numerical overflow.

Gauche uses sequentially consistent order regardless of the memory-order argument.

Atomic pair

An atomic pair is a storage that can hold two Scheme values, and both can be updated at once atomically.

Function: make-atomic-pair val1 val2

[SRFI-230]{srfi.230} Creates a new atomic pair that has two values, val1 and val2. {srfi.230}

Function: atomic-pair? obj

[SRFI-230]{srfi.230} Returns #t if obj is an atomic pair, #f otherwise.

Function: atomic-pair-ref apair :optional memory-order

[SRFI-230]{srfi.230} Atomically dereference the two values apair holds, and returns them as the two return values.

Gauche uses sequentially consistent order regardless of the memory-order argument.

Function: atomic-pair-set! apair val1 val2 :optional memory-order

[SRFI-230]{srfi.230} Atomically stores val1 and val2 to an atomic pair apair. Returns an undefined value.

Gauche uses sequentially consistent order regardless of the memory-order argument.

Function: atomic-pair-swap! apair val1 val2 :optional memory-order

[SRFI-230]{srfi.230} Atomically stores val1 and val2 to an atomic pair apair and returns the previous values.

Gauche uses sequentially consistent order regardless of the memory-order argument.

Function: atomic-pair-compare-and-swap! abox expected1 expected2 desired1 desired2 :optional memory-order

[SRFI-230]{srfi.230} Compare two values in atomic box abox with expected1 and expected2, respectively. If each corresponding values are the same (in eq? sense), store desired1 and desired2 to abox. Always returns teh original values. The whole operations are done atomically.

You can know the values are altered by comparing returned values and expected values.

Gauche uses sequentially consistent order regardless of the memory-order argument.

Memory synchronization

Function: atomic-fence memory-order

[SRFI-230]{srfi.230} Synchronize memory according to at least memory-order constraints. In the current version of Gauche, regardless of memory-order, the memory is synchronized with sequentially consistent manner.



For Development HEAD DRAFTSearch (procedure/syntax/module):
DRAFT