How to perform atomic operations on Linux that work on x86, arm, GCC and icc?

Artyom picture Artyom · Feb 18, 2010 · Viewed 28.4k times · Source

Every Modern OS provides today some atomic operations:

  • Windows has Interlocked* API
  • FreeBSD has <machine/atomic.h>
  • Solaris has <atomic.h>
  • Mac OS X has <libkern/OSAtomic.h>

Anything like that for Linux?

  • I need it to work on most Linux supported platforms including: x86, x86_64 and arm.
  • I need it to work on at least GCC and Intel Compiler.
  • I need not to use 3rd par library like glib or qt.
  • I need it to work in C++ (C not required)

Issues:

  • GCC atomic builtins __sync_* are not supported on all platforms (ARM) and are not supported by the Intel compiler.
  • AFAIK <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.

Answer

Noah Watkins picture Noah Watkins · Jan 13, 2011

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.