Ada Programming/Pragmas/Atomic

pragma Atomic (local_name);

Description
Atomic is a representation pragma that can be used with types and variables to specify that the code generated must read and write the type or variable from memory atomically, i.e. as a single/non-interruptible operation. It implies pragma Volatile, the difference is that pragma Atomic is stronger: the compilation must fail if the variable cannot be updated atomically.

This is typically used in the context of interfacing with hardware registers, which must be written atomically and where the compiler must not reorder or suppress any redundant read or write. In some cases it can also be used for tasking, but for communication of Ada tasks it is safer to use protected types or other synchronization primitives.

Example
Device_Status : Status_Register; (Device_Status); Device_Status' .To_Address (16#8010_FF74#);

Compilers
Atomic is a standard pragma since Ada 95, defined in the Systems Programming Annex (Annex C). This is a specialized needs annex, therefore this pragma is not available in those compilers not implementing that annex.

Ada versions

 * Available in Ada 95 and Ada 2005.
 * In Ada 83 pragma Shared produces similar effects than pragma Atomic (but it is obsolescent since Ada 95).

Platforms
Atomic is a portability aid between different platforms. For example, when porting between a 64-bit to a 32-bit architecture, the compiler will detect portability problems thanks to this pragma.

Interfacing
The effects of pragma Atomic can be achieved in C using the type volatile sig_atomic_t, defined in signal.h (called volatile std::sig_atomic_t in C++). It is worth noting that the only values that can be portably stored in this type are 0–127, whereas the Ada pragma doesn't impose any specific limit (other than the type of the atomic object).

However, this C type is rarely known by programmers. Therefore, the C volatile qualifier is the approach widely used both for volatile and atomic data, even if atomic access in required. Thus, when interfacing with existing C code, the programmer must first read the code to understand whether the data needs atomic load and stores or not. If needed, the data should be marked in the Ada side with pragma Atomic or Atomic_Components. Otherwise, pragma Volatile or Volatile_Components should be added instead.

C++11 and C11 incorporated atomic operations and types, but differ from the semantics in Ada and are not compatible.

Wikibook

 * Ada Programming
 * Ada Programming/Pragmas
 * Ada Programming/Pragmas/Volatile
 * Ada Programming/Pragmas/Atomic Components
 * Ada Programming/Pragmas/Volatile Components
 * Ada Programming/Pragmas/Shared (obsolescent)