Atomic Operations

Describes the new atomic operations added to euser.dll and the kernel.

An atomic operation is an operation that comprises two or more conditions. When an atomic operation is executed and all conditions are met it results in success; when one or more conditions are not met it results in failure. The new atomic operations added to euser.dll and the kernel replace the existing ones. The existing operation format is preserved __e32_atomic_xxx_yyyZ

In the above format:

  • z specifies the size of the data type being operated on

  • yyy specifies the type of memory ordering that is to be enforced (with memory barriers)

  • xxx specifies the operation that is to be performed.

The following table outlines the types of memory ordering and operations available.

Memory Ordering (yyy)
Name Description
rlx Relaxed memory ordering. In this type of ordering there is no fixed order in which the atomic operation is observed in relation to other memory operations.
acq Acquire semantics. In this type of memory ordering a memory barrier is placed after the atomic operation.
rel Release semantics. In this type of ordering a memory barrier is executed before the atomic operation.
ord Fully ordered. In this type of ordering a memory barrier is executed before and after the atomic operation.
Operation (xxx)
Name Description
load Reads the contents of a location.
store Writes to a location
swp Swaps the contents of a specified memory location with a given parameter.
add Adds a value to the contents of the specified memory location.
and Logical AND.
ior Logical OR.
xor Logical XOR.
axo AND then XOR
cas Compare and Set

Compare the contents of the specified memory location with another specified location. If the contents of both locations have the same value, the contents of the original location is set to a specified value.

tau Threshold and add unsigned

If the contents of a specified memory location is greater than the specified threshold, then add the contents with one parameter, otherwise add the contents to another. For this operation, all the parameters are unsigned.

tas Threshold and add signed

If the contents of a specified memory location is greater than the specified threshold, then add the contents with one parameter, otherwise add the contents to another. For this operation, all the parameters are signed.

The meaning of each parameter, depends on the operation (xxx) (the argument order is from left to right) :

Operation (xxx) First argument Second Argument Third Argument Fourth Argument
load address of the data N/A N/A N/A
store address of the data Data to be stored. N/A N/A
swp address of the data Data to be swapped. N/A N/A
cas address of the data Address of the data to be compared. New contents of the address specified in the first parameter, if the comparison is true. N/A
add address of the data Data to be added. N/A N/A
and address of the data Data to be used in the AND operation . N/A N/A
ior address of the data Data to be used in the OR operation. N/A N/A
xor address of the data Data to be used in the XOR operation. N/A N/A
axo address of the data Data to be used in the AND operation. Data to be used in the XOR operation. N/A
tau address of the data Value of the threshold. See note 1. See note 2.
tas address of the data Value of the threshold. See note 1. See note 2.
Note:

1. Value to add if the value of the data pointed to by the address in the first parameter, is equal to or greater than the threshold value

2. Value to add if the value of the data pointed to by the address in the first parameter, is less than the threshold.

Example

An example of an atomic operation in use is :

              if (__e32_atomic_tas_ord32(&buffer.iDisplayDriverCount, 1, -1, 0) == 1)
                  {
                      // All drivers disconnected, deallocate memory.
                      ...
                  }

In the above example we use a fully ordered memory to compare a threshold value of 1. If the value of &buffer.iDisplayDriverCount is greater than or equal to 1 then it is added with -1 and the final value of &buffer.iDisplayDriverCount is returned. If the value of &buffer.iDisplayDriverCount is not greater than or equal to 1, the value of &buffer.iDisplayDriverCount is added with 0 and returned. The driver are disconnected when the returned value is equal to 1.

Related concepts
SMP - Overview