Synchronization and atomic built-ins

Prototype Description
unsigned int __check_lock_mp (const int* addr, int old_value, int new_value); Check Lock on MultiProcessor systems.

Conditionally updates a single word variable atomically. addr specifies the address of the single word variable. old_value specifies the old value to be checked against the value of the single word variable. new_value specifies the new value to be conditionally assigned to the single word variable. The word variable must be aligned on a full word boundary.

Return values:

  1. A return value of false indicates that the single word variable was equal to the old value and has been set to the new value.
  2. A return value of true indicates that the single word variable was not equal to the old value and has been left unchanged.
unsigned int __check_lockd_mp (const long long int* addr, long long int old_value, long long int new_value); Check Lock Doubleword on MultiProcessor systems.

Conditionally updates a double word variable atomically. addr specifies the address of the double word variable. old_value specifies the old value to be checked against the value of the double word variable. new_value specifies the new value to be conditionally assigned to the double word variable. The double word variable must be aligned on a double word boundary.

Return values:

  1. A return value of false indicates that the double word variable was equal to the old value and has been set to the new value.
  2. A return value of true indicates that the double word variable was not equal to the old value and has been left unchanged.
unsigned int __check_lock_up (const int* addr, int old_value, int new_value); Check Lock on UniProcessor systems.

Conditionally updates a single word variable atomically. addr specifies the address of the single word variable. old_value specifies the old value to be checked against the value of the single word variable. new_value specifies the new value to be conditionally assigned to the single word variable. The word variable must be aligned on a full word boundary.

Return values:

  • A return value of false indicates that the single word variable was equal to the old value, and has been set to the new value.
  • A return value of true indicates that the single word variable was not equal to the old value and has been left unchanged.
unsigned int __check_lockd_up (const long long int* addr, long long int old_value, int long long new_value); Check Lock Doubleword on UniProcessor systems.

Conditionally updates a double word variable atomically. addr specifies the address of the double word variable. old_value specifies the old value to be checked against the value of the double word variable. new_value specifies the new value to be conditionally assigned to the double word variable. The double word variable must be aligned on a double word boundary.

Return values:

  • A return value of false indicates that the double word variable was equal to the old value, and has been set to the new value.
  • A return value of true indicates that the double word variable was not equal to the old value and has been left unchanged.
void __clear_lock_mp (const int* addr, int value); Clear Lock on MultiProcessor systems.

Atomic store of the value into the single word variable at the address addr. The word variable must be aligned on a full word boundary.

void __clear_lockd_mp (const long long int* addr, long long int value); Clear Lock Doubleword on MultiProcessor systems.

Atomic store of the value into the double word variable at the address addr. The double word variable must be aligned on a double word boundary.

void __clear_lock_up (const int* addr, int value); Clear Lock on UniProcessor systems.

Atomic store of the value into the single word variable at the address addr. The word variable must be aligned on a full word boundary.

void __clear_lockd_up (const long long int* addr, long long int value); Clear Lock Doubleword on UniProcessor systems.

Atomic store of the value into the double word variable at the address addr. The double word variable must be aligned on a double word boundary.

int __compare_and_swap(volatile int* addr, int* old_val_addr, int new_val); Performs an atomic operation which compares the contents of a single word variable with a stored old value.

If the values are equal, a new value is stored in the single word variable and 1 is returned; otherwise, the single word variable is not updated and 0 is returned. In either case, the contents of the memory location specified by addr are copied into the memory location specified by old_val_addr.

The __compare_and_swap subroutine is useful when a single word value must be updated only if it has not been changed since it was last read. The memory location that is taken as the input parameteraddr must be 4-byte aligned. If __compare_and_swap is used as a locking primitive, insert an isync at the start of any critical sections.

int __compare_and_swaplp(volatile long* addr, long* old_val_addr, long new_val); Performs an atomic operation which compares the contents of a double word variable with a stored old value.

If the values are equal, a new value is stored in the double word variable and 1 is returned; otherwise, the double word variable is not updated and 0 is returned. In either case, the contents of the memory location specified byaddr are copied into the memory location specified by old_val_addr.

The __compare_and_swaplp subroutine is useful when a double word value must be updated only if it has not been changed since it was last read. The memory location that is taken as the input parameteraddr must be 8-byte aligned. If __compare_and_swaplp is used as a locking primitive, insert an isync at the start of any critical sections.

void __eieio(void); Extra name for the existing __iospace_eieio built-in.

Compiler will recognize eieio built-in. Everything except for the name is exactly same as for __iospace_eieio. eieio is consistent with the corresponding PowerPC instruction name.

int __fetch_and_add(volatile int* addr, int val); Increments the single word specified by addr by the amount specified by val in a single atomic operation.

The return value is equal to the original contents of the memory location. The address specified by addr must be 4-byte aligned.

This operation is useful when a counter variable is shared between several threads or processes.

long __fetch_and_addlp(volatile long* addr, long val); Increments the double word specified by addr by the amount specified by val in a single atomic operation.

The return value is equal to the original contents of the memory location. The address specified by addr must be 8-byte aligned.

This operation is useful when a counter variable is shared between several threads or processes.

unsigned int __fetch_and_and(volatile unsigned int* addr, unsigned int val); Clears bits in the single word specified byaddr by AND-ing that value with the input val parameter, in a single atomic operation.

The return value is equal to the original contents of the memory location. The address specified by addr must be 4-byte aligned.

This operation is useful when a variable containing bit flags is shared between several threads or processes.

unsigned long __fetch_and_andlp(volatile unsigned long* addr, unsigned long val); Clears bits in the double word specified by addr by AND-ing that value with the input val parameter, in a single atomic operation.

The return value is equal to the original contents of the memory location. The address specified by addr must be 8-byte aligned.

This operation is useful when a variable containing bit flags is shared between several threads or processes.

unsigned int __fetch_and_or(volatile unsigned int* addr, unsigned intval); Sets bits in the single word specified by addr by OR-ing that value with the input val parameter, in a single atomic operation.

The return value is equal to the original contents of the memory location. The address specified by addr must be 4-byte aligned.

This operation is useful when a variable containing bit flags is shared between several threads or processes.

unsigned long __fetch_and_orlp(volatile unsigned long* addr, unsigned long val; sets bits in the double word specified by addr by OR-ing that value with the input val parameter, in a single atomic operation.

The return value is equal to the original contents of the memory location. The address specified by addr must be 8-byte aligned. This operation is useful when a variable containing bit flags is shared between several threads or processes.

unsigned int __fetch_and_swap(volatile unsigned int* addr, unsigned intval); Sets the single word specified by addr to the value or the input val parameter and returns the original contents of the memory location, in a single atomic operation.

The address specified by addr must be 4-byte aligned.

This operation is useful when a variable is shared between several threads or processes, and one thread needs to update the value of the variable without losing the value that was originally stored in the location.

unsigned long __fetch_and_swaplp(volatile unsigned long* addr, unsigned long val); Sets the double word specified by addr to the value or the input val parameter and returns the original contents of the memory location, in a single atomic operation.

The address specified by addr must be 8-byte aligned.

This operation is useful when a variable is shared between several threads or processes, and one thread needs to update the value of the variable without losing the value that was originally stored in the location.

void __iospace_eieio(void); Generates an EIEIO instruction
(equivalent to: void __iospace_lwsync(void);) Generates a lwsync instruction
(equivalent to: void __iospace_sync(void);) Generates a sync instruction
void __isync(void); Waits for all previous instructions to complete and then discards any prefetched instructions, causing subsequent instructions to be fetched (or refetched) and executed in the context established by previous instructions.
long __ldarx(volatile long* addr); Generates a Load Double Word And Reserve Indexed (ldarx) instruction.

This instruction can be used in conjunction with a subsequent stwcx. instruction to implement a read-modify-write on a specified memory location. The memory location that is taken as the input parameter addr must be 8-byte aligned. The ldarx and stwcx.' instructions work together to ensure that if the store is successfully performed, no other processor or mechanism has modified the target double word between the time the ldarx instruction is executed and the time thestwcx. instruction completes. The ldarx built-in function returns the value loaded from the memory location specified by addr. This built-in function ensures that no other instructions are reordered with the generated lwarx instruction by the compiler. This has the same effect as inserting __fence built-in functions before and after the ldarx built-in function and can inhibit compiler optimization of surrounding code.

int __lwarx(volatile int* addr); Generates a Load Word And Reserve Indexed (lwarx) instruction.

This instruction can be used in conjunction with a subsequent stwcx. instruction to implement a read-modify-write on a specified memory location. The memory location that is taken as the input parameter addr must be 4-byte aligned. The lwarx and stwcx. instructions work together to ensure that if the store is successfully performed, no other processor or mechanism has modified the target single word between the time the lwarx instruction is executed and the time the stwcx. instruction completes. The lwarx built-in function returns the value loaded from the memory location specified by addr. In 64-bit mode, the compiler returns the sign-extended result of the lwarx instruction. This built-in function ensures that no other instructions are reordered with the generated lwarx instruction by the compiler. This has the same effect as inserting __fence built-in functions before and after the lwarx built-in function and can inhibit compiler optimization of surrounding code

void __lwsync(void) Extra name for the existing __iospace_sync built-in.

Compiler will recognize __lwsync built-in. Everything except for the name is exactly same as for __iospace_sync. __lwsync is consistent with the corresponding PowerPC instruction name. This function is supported only by the PowerPC 970 processor.

Value must be known at compile time.

void __sync(void) Extra name for the existing __iospace_sync built-in.

Compiler will recognize __fence built-in. Everything except for the name is exactly same as for __iospace_sync. __sync is consistent with the corresponding PowerPC instruction name.