最近在用户态下突然需要用到原子变量,又不想自己编译boost,思来索去,无意中竟发现gcc还有这一组内置函数.
//先做操作,再返回变化后的值 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);
按照官方文档的说法,
GCC will allow any integral scalar or pointer type that is 1, 2, 4, or 8 bytes in length. 16-byte integral types are also allowed if `__int128‘ (see __int128) is supported by the architecture.
也就是说至少支持长度为 1,2,4,8的整形。
简单的测试了一下,发现不用include任何头文件,gcc编译时会自动替换成对应的汇编代码。
int main() { int a = 100; __sync_fetch_and_add(&a,1); return a; }
看了下生成的汇编是这样的:
.file "funtest.c" .text .globl main .type main, @function main: .LFB0: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movl $100, -4(%rbp) lock addl $1, -4(%rbp) //__sync_fetch_and_add(&a,1);对应的指令 movl -4(%rbp), %eax popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE0: .size main, .-main .ident "GCC: (Debian 4.7.2-5) 4.7.2" .section .note.GNU-stack,"",@progbits
参考链接
原文:http://my.oschina.net/u/1183791/blog/324028