Atomic operations provided by GCC

Source: Internet
Author: User

GCC provides the built-in function of the __sync_* series from 4.1.2 to provide atomic operations for addition and subtraction and logical operations.

The statement is as follows:

Type __sync_fetch_and_add (type *ptr, type value, ...)
Type __sync_fetch_and_sub (type *ptr, type value, ...)
Type __sync_fetch_and_or (type *ptr, type value, ...)
Type __sync_fetch_and_and (type *ptr, type value, ...)
Type __sync_fetch_and_xor (type *ptr, type value, ...)
Type __sync_fetch_and_nand (type *ptr, type value, ...)


Type __sync_add_and_fetch (type *ptr, type value, ...)
Type __sync_sub_and_fetch (type *ptr, type value, ...)
Type __sync_or_and_fetch (type *ptr, type value, ...)
Type __sync_and_and_fetch (type *ptr, type value, ...)
Type __sync_xor_and_fetch (type *ptr, type value, ...)
Type __sync_nand_and_fetch (type *ptr, type value, ...)



The difference between these two sets of functions is that the first group returns the value before the update, and the second group returns the updated value.

The type can be 1,2,4 or 8-byte-length int, i.e.:


int8_t/uint8_t
int16_t/uint16_t
int32_t/uint32_t
int64_t/uint64_t


The following extensible parameters (...) Used to indicate which variables require memory barrier, because the current GCC implementation is full barrier (similar to the MB () in Linux kernel, which means that all memory operations before this operation will not be reordered after this operation), so you can skip this parameter.


BOOL __sync_bool_compare_and_swap (Type *ptr, type Oldval type newval, ...)
Type __sync_val_compare_and_swap (Type *ptr, type Oldval type newval, ...)



These two functions provide an atomic comparison and exchange, and if *ptr = = Oldval, the newval is written to *ptr,
The first function returns true in the case of equality and writing.
The value of the second function before the return operation.

__sync_synchronize (...)


Issue a full barrier.

About the memory barrier,cpu will sort our instructions, generally improving the efficiency of the program, but sometimes it may lead to the results we do not want to get, for example, we have a hardware device, it has 4 registers, when you send an operation command, A register is stored in your operation instructions (such as read), two registers are parameters (such as the address and size), the last register is the control register, after all the parameters are set to send instructions to it, the device begins to read the parameters, execute the command, the program may be as follows:

Write1 (dev.register_size,size);
Write1 (DEV.REGISTER_ADDR,ADDR);
Write1 (Dev.register_cmd,read);
Write1 (Dev.register_control,go);


If the last write1 is replaced by the first few statements, then it is definitely not what we expect, so we can add a memory barrier before the last statement, forcing the CPU to execute the previous write before executing the last one:


Write1 (dev.register_size,size);
Write1 (DEV.REGISTER_ADDR,ADDR);
Write1 (Dev.register_cmd,read);
__sync_synchronize ();
Write1 (Dev.register_control,go);


There are several types of memory barrier:
Acquire barrier: It is not allowed to move memory read instructions after barrier to barrier (kernel () in Linux WMB).
Release Barrier: The memory read instruction before barrier is not allowed to be moved after barrier ($ () in Linux kernel).
Full Barrier: The collection of the two barrier (MB () in Linux kernel).


There are two other functions:

Type __sync_lock_test_and_set (type *ptr, type value, ...)
Set *ptr to value and return the values before the *ptr operation.

void __sync_lock_release (Type *ptr, ...)
Place the *ptr 0


Sample program:


#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>

static int count = 0;


void *test_func (void *arg)
{
int i=0;
for (I=0;i<20000;++i) {
__sync_fetch_and_add (&count,1);
}
return NULL;
}

int main (int argc, const char *argv[])
{
pthread_t ID[20];
int i = 0;

for (I=0;i<20;++i) {
Pthread_create (&id[i],null,test_func,null);
}

for (I=0;i<20;++i) {
Pthread_join (Id[i],null);
}

printf ("%d\n", count);
return 0;
}

Reference:

1. Http://refspecs.freestandards.org/elf/IA64-SysV-psABI.pdf Section 7.4

2. Http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html#Atomic-Builtins

Atomic operations provided by GCC

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.