105 lines
2.8 KiB
ReStructuredText
105 lines
2.8 KiB
ReStructuredText
.. _atomic_services:
|
|
|
|
Atomic Services
|
|
###############
|
|
|
|
Concepts
|
|
********
|
|
|
|
The kernel supports an atomic 32-bit data type called :c:type:`atomic_t`.
|
|
A variable of this type can be read and modified by any task, fiber, or ISR
|
|
in an uninterruptible manner. This guarantees that the desired operation
|
|
will not be interfered with due to the scheduling of a higher priority context,
|
|
even if the higher priority context manipulates the same variable.
|
|
|
|
Purpose
|
|
*******
|
|
|
|
Use the atomic services to implement critical section processing that only
|
|
requires the manipulation of a single 32-bit data item.
|
|
|
|
.. note::
|
|
Using an atomic variable is typically far more efficient than using
|
|
other techniques to implement critical sections such as using
|
|
a microkernel mutex, offloading the processing to a fiber, or
|
|
locking interrupts.
|
|
|
|
Usage
|
|
*****
|
|
|
|
Example: Implementing an Uninterruptible Counter
|
|
================================================
|
|
This code shows how a function can keep track of the number of times
|
|
it has been invoked. Since the count is incremented atomically, there is
|
|
no risk that it will become corrupted in mid-increment if the routine is
|
|
interrupted by the scheduling of a higher priority context that also
|
|
calls the routine.
|
|
|
|
.. code-block:: c
|
|
|
|
atomic_t call_count;
|
|
|
|
int call_counting_routine(void)
|
|
{
|
|
/* increment invocation counter */
|
|
atomic_inc(&call_count);
|
|
|
|
/* do rest of routine's processing */
|
|
...
|
|
}
|
|
|
|
APIs
|
|
****
|
|
|
|
The following atomic operation APIs are provided by :file:`atomic.h`:
|
|
|
|
:c:func:`atomic_get()`
|
|
Reads an atomic variable.
|
|
|
|
:c:func:`atomic_set()`
|
|
Writes an atomic variable.
|
|
|
|
:c:func:`atomic_clear()`
|
|
Clears an atomic variable.
|
|
|
|
:c:func:`atomic_add()`
|
|
Performs an addition operation on an atomic variable.
|
|
|
|
:c:func:`atomic_sub()`
|
|
Performs a subtraction operation on an atomic variable.
|
|
|
|
:c:func:`atomic_inc()`
|
|
Performs an increment operation on an atomic variable.
|
|
|
|
:c:func:`atomic_dec()`
|
|
Performs a decrement operation on an atomic variable.
|
|
|
|
:c:func:`atomic_and()`
|
|
Perform an "and" operation on an atomic variable.
|
|
|
|
:c:func:`atomic_or()`
|
|
Perform an "or" operation on an atomic variable.
|
|
|
|
:c:func:`atomic_xor()`
|
|
Perform a "xor" operation on an atomic variable.
|
|
|
|
:c:func:`atomic_nand()`
|
|
Perform a "nand" operation on an atomic variable.
|
|
|
|
:c:func:`atomic_cas()`
|
|
Performs compare-and-set operation on an atomic variable.
|
|
|
|
:c:func:`atomic_set_bit()`
|
|
Sets specified bit of an atomic variable to 1.
|
|
|
|
:c:func:`atomic_clear_bit()`
|
|
Sets specified bit of an atomic variable to 0.
|
|
|
|
:c:func:`atomic_test_bit()`
|
|
Reads specified bit of an atomic variable.
|
|
|
|
:c:func:`atomic_test_and_set_bit()`
|
|
Reads specified bit of an atomic variable and sets it to 1.
|
|
|
|
:c:func:`atomic_test_and_clear_bit()`
|
|
Reads specified bit of an atomic variable and sets it to 0. |