Every Modern OS provides today some atomic operations:
Interlocked*
API<machine/atomic.h>
<atomic.h>
<libkern/OSAtomic.h>
Anything like that for Linux?
Issues:
__sync_*
are not supported on all platforms (ARM) and are not supported by the Intel compiler.<asm/atomic.h>
should not be used in user space and I haven't successfully used it at all. Also, I'm not sure if it would work with Intel compiler.Any suggestions?
I know that there are many related questions but some of them point to __sync*
which is not feasible for me (ARM) and some point to asm/atomic.h
.
Maybe there is an inline assembly library that does this for GCC (ICC supports gcc assembly)?
Edit:
There is a very partial solution for add operations only (allows implementing atomic counter but not lock free-structures that require CAS):
If you use libstc++
(Intel Compiler uses libstdc++
) then you can use __gnu_cxx::__exchange_and_add
that defined in <ext/atomicity.h>
or <bits/atomicity.h>
. Depends on compiler version.
However I'd still like to see something that supports CAS.
Linux uses atomic counters to count various things including IO errors, dropped packets, CPU cycles used, and various other simple statistics.
Atomic operations on the other hand provide instructions which complete in one instruction cycle. Since atomic instructions complete in one single instruction cycle, they are not interrupted by other CPUs trying to access the same memory location.
In C, _Atomic is used as a type specifier. It is used to avoid the race condition if more than one thread attempts to update a variable simultaneously. It is defined in the stdatomic.
This is an integer data type. Objects of this type are always accessed atomically. In practice, you can assume that int is atomic.
Projects are using this:
http://packages.debian.org/source/sid/libatomic-ops
If you want simple operations such as CAS, can't you just just use the arch-specific implementations out of the kernel, and do arch checks in user-space with autotools/cmake? As far as licensing goes, although the kernel is GPL, I think it's arguable that the inline assembly for these operations is provided by Intel/AMD, not that the kernel has a license on them. They just happen to be in an easily accessible form in the kernel source.
Recent standards (from 2011) of C & C++ now specify atomic operations:
stdatomic.h
std::atomic
Regardless, your platform or compiler may not support these newer headers & features.
Darn. I was going to suggest the GCC primitives, then you said they were off limits. :-)
In that case, I would do an #ifdef
for each architecture/compiler combination you care about and code up the inline asm. And maybe check for __GNUC__
or some similar macro and use the GCC primitives if they are available, because it feels so much more right to use those. :-)
You are going to have a lot of duplication and it might be difficult to verify correctness, but this seems to be the way a lot of projects do this, and I've had good results with it.
Some gotchas that have bit me in the past: when using GCC, don't forget "asm volatile
" and clobbers for "memory"
and "cc"
, etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With