Ada Reference Manual (Ada 2022) — Legal Information

# C.6.2 The Package System.Atomic_Operations.Exchange

1/5
The language-defined generic package System.Atomic_Operations.Exchange provides the following operations:
2/5
To atomically compare the value of two atomic objects, and update the first atomic object with a desired value if both objects were found to be equal, or otherwise update the second object with the value of the first object.
3/5
To atomically update the value of an atomic object, and then return the value that the atomic object had just prior to the update.

#### Static Semantics

4/5
The generic library package System.Atomic_Operations.Exchange has the following declaration:
5/5
generic
type Atomic_Type is private with Atomic;
package System.Atomic_Operations.Exchange
with Pure, Nonblocking is
6/5
function Atomic_Exchange (Item : aliased in out Atomic_Type;
Value : Atomic_Type) return Atomic_Type
with Convention => Intrinsic;
7/5
function Atomic_Compare_And_Exchange
(Item : aliased in out Atomic_Type;
Prior : aliased in out Atomic_Type;
Desired : Atomic_Type) return Boolean
with Convention => Intrinsic;
8/5
function Is_Lock_Free (Item : aliased Atomic_Type) return Boolean
with Convention => Intrinsic;
9/5
end System.Atomic_Operations.Exchange;
10/5
Atomic_Exchange atomically assigns the value of Value to Item, and returns the previous value of Item.
11/5
Atomic_Compare_And_Exchange first evaluates the value of Prior. Atomic_Compare_And_Exchange then performs the following steps as part of a single indivisible operation:
12/5
evaluates the value of Item;
13/5
compares the value of Item with the value of Prior;
14/5
if equal, assigns Item the value of Desired;
15/5
otherwise, makes no change to the value of Item.
16/5
After these steps, if the value of Item and Prior did not match, Prior is assigned the original value of Item, and the function returns False. Otherwise, Prior is unaffected and the function returns True.

#### Examples

17/5
Example of a spin lock using Atomic_Exchange:
18/5
type Atomic_Boolean is new Boolean with Atomic;
package Exchange is new
Atomic_Operations.Exchange (Atomic_Type => Atomic_Boolean);
19/5
Lock : aliased Atomic_Boolean := False;
20/5
...
21/5
begin -- Some critical section, trying to get the lock:
22/5
-- Obtain the lock
while Exchange.Atomic_Exchange (Item => Lock, Value => True) loop
null;
end loop;
23/5
... -- Do stuff
24/5
Lock := False; -- Release the lock
end;

Ada 2005 and 2012 Editions sponsored in part by Ada-Europe