Atomic operations provided by GCC

Source: Internet
Author: User

 

[Date: 2011-06-17] Source: Linux community Author: franktan
GCC provides the _ sync _ * series of built-in functions 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 the two groups of functions is that the first group returns the value before the update, and the second group returns the updated value.

Type can be 1, 2, 4, or 8-byte int type, that is:
Int8_t/uint8_t
Int16_t/uint16_t
Int32_t/uint32_t
Int64_t/uint64_t

 

The following extensible parameters (...) it is used to indicate which variables need memory barrier, because GCC currently implements full Barrier (similar to the MB () in Linux kernel (), indicates that all memory operations prior to this operation will not be reordered to this operation), so this parameter can be omitted.


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 atomic comparison and exchange. If * PTR = oldval, newval is written to * PTR,
The first function returns true if it is equal and written.
The value of the second function before the return operation.

_ Sync_synchronize (...)

Sends out a full Barrier.

With regard to memory barrier, the CPU sorts our commands, which generally improves program efficiency, but sometimes results in undesirable results. For example, for example, we have a hardware device with four registers. When you issue an operation command, one register stores your operation command (such as read ), the two registers store parameters (such as address and size), and the last register is the control register. After all the parameters are set, it sends a command to the device to start reading the parameters, run the following command: 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 with the first few statements, it is definitely not what we expected. In this case, we can add a memory barrier before the last statement, force 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 );

Memory barrier has several types:
Acquire barrier: it is not allowed to move the memory READ command after barrier to barrier (WMB () in Linux kernel ()).
Release barrier: it is not allowed to move the memory read commands before barriers to barriers (RMB () in Linux kernel ()).
Full barrier: a collection of the preceding two barrier types (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 value before * PTR operation.

Void _ sync_lock_release (type * PTR ,...)
Set * PTR to 0

Example 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;
}

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.