Recently on this list, Paul referred to an "atomic integer
swap" and an "atomic pointer swap." This was a new concept
to me (and possibly others), and this e-mail shares what
I've learned.
If you access a variable from multiple threads -- even a
built-in variable like 'int', it is important to control
access to the variable with a mutex, semaphore, or an atomic
operation.
Alexander Sandler, on his blog, wrote a couple of good
articles on the subject:
"Do you need a mutex to protect an int?"
http://www.alexonlinux.com/do-you-need-mutex-to-protect-int
"Multithreaded simple data type access and atomic
variables"
http://www.alexonlinux.com/multithreaded-simple-data-type-access-and-atomic…
The first article contains code that calculates a wrong
answer on multiprocessor machines. I've attached a similar
example that will even fail on a single-processor machine.
There is a wealth of reading material on using Mutexes and
Semaphores. However, information on atomic operations
appears to be sparse and hard-to-follow. So, here's what
I've found:
+ At the moment, there is no built-in support in
C/C++ for atomic operations. You will need to use
a library, compiler extension, or write your own
in assembly code.
+ The GCC compiler has the built-in __sync_*()
functions[1] that provide atomic operations.
Note that the attached example is using this.
+ glib provides the g_atomic_*() functions[2].
+ Qt 4 has the q_atomic_*() functions.[3] While
they are accessible, they are /not/ a part of
their stable, public API.
+ The next version of ISO C++ (code name c++0x)
is expected to have support for atomic operations
(E.g. the std::atomic<T> template) and memory
barriers. It may even require that all built-in
types be atomic.
+ In the x86 instruction set, these are usually
implemented using the 'LOCK' instruction prefix.[5]
When using atomic operations, perhaps the best advice I
found is near the end of Sandler's second article:
"When using atomic variables, some extra
precautions have to be taken.... There is nothing
that prevents you from incrementing value of the
atomic variable with __sync_fetch_and_add() as I
just demonstrated and later in the code doing same
thing with regular ++ operator.
"To address this problem, I strongly suggest
wrapping around atomic functions and variables with
either ADT in C or C++ class."[4]
Peace,
Gabriel
[1]
http://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Atomic-Builtins.html
[2]
http://www.gtk.org/api/2.6/glib/glib-Atomic-Operations.html
[3]
http://doc.trolltech.com/4.3/atomic-operations.html
See also the Qt header file QtCore/qatomic_i386.h, and
its brothers.
[4]
http://www.alexonlinux.com/multithreaded-simple-data-type-access-and-atomic…
[5]
http://siyobik.info/index.php?module=x86&id=159