zephyr/doc/kernel/common/common_atomic.rst
Allan Stephens 0be860ad1a doc: Add information about atomic APIs
Describes atomic operations, including concepts, examples,
and APIs.

Change-Id: I701435508ae179623cf983590802040b35b0f286
Signed-off-by: Allan Stephens <allan.stephens@windriver.com>
2016-02-05 20:15:21 -05:00

96 lines
4.4 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`.
+---------------------------------------+-------------------------------------+
| Call | Description |
+=======================================+=====================================+
| :c:func:`atomic_get()` | Reads an atomic variable. |
+---------------------------------------+-------------------------------------+
| :c:func:`atomic_set()` | Writes an atomic variable. |
+---------------------------------------+-------------------------------------+
| :c:func:`atomic_clear()` | Zeroes an atomic variable. |
+---------------------------------------+-------------------------------------+
| | :c:func:`atomic_add()` | Performs an arithmetic operation |
| | :c:func:`atomic_sub()` | on an atomic variable. |
| | :c:func:`atomic_inc()` | |
| | :c:func:`atomic_dec()` | |
+---------------------------------------+-------------------------------------+
| | :c:func:`atomic_and()` | Performs a logical operation |
| | :c:func:`atomic_or()` | on an atomic variable. |
| | :c:func:`atomic_xor()` | |
| | :c:func:`atomic_nand()` | |
+---------------------------------------+-------------------------------------+
| :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. |
+---------------------------------------+-------------------------------------+