3.2 Atomic Mode and Uninterruptible Mode
| import: ffi/atomic | package: rhombus-ffi-lib |
Atomic mode evaluates a Rhombus expression without switching among Rhombus coroutine threads and with limited support for synchronizable events. An atomic computation in this sense is not atomic with respect to parallel threads, but only to coroutine threads. Asynchronous break exceptions (in the sense of Thread.break) are also disabled in atomic mode.
Atomic mode is unsafe, because the Rhombus scheduler is not able to operate while execution is in atomic mode: (1) the scheduler cannot switch coroutine threads or poll certain kinds of events, which can lead to deadlock or starvation of other threads; and (2) calling a scheduler-related function in atomic mode has unspecified behavior, where misuse is not necessarily caught with a check. Functions that are directly scheduler-related include Thread, Thread.sleep, and Evt.sync. Beware that other operations can involve such synchronization, such as writing to an output port or using a mutable map. Even if an output target is known to be free of synchronization, beware that values can have arbitrary printing procedures attached through Printable. Successful use of atomic mode requires a detailed knowledge of any implementation that might be reached during atomic mode to ensure that it terminates and does not involve synchronization.
Uninterruptible mode is related to atomic mode. It is also unsafe and practically the same as atomic mode in a coroutine thread, but uninterruptible mode does not force a parallel thread to synchronize with all coroutine threads. Uninterruptible mode also allows the use of uncontested semaphores and mutable maps.
function | |||
| |||
| |||
function | |||
| |||
| |||
expression | |||
|
The atomic.atomically form uses try with atomic.start_atomic as an ~initially clause and atomic.end_atomic as a ~finally clause.
function | |||
| |||
| |||
function | |||
| |||
| |||
expression | |||
|