Remember that this version of swap is not a fully atomic operation. As long as the value of b
is atomically copied to a
, the value of a
can copy another modification to the value of b
another thread. In other words, assignment b
not atomic with respect to other threads. Thus, you may encounter a situation where a == 1
and b == 2
, and after the built-in gcc you get a == 2
and the return value is 1
, but now another thread changed the value of b
- 3
, and you write this value in b
with a value of 1
. Thus, although you may have βtechnicallyβ swapped the values, you did not do this atomically ... another thread touched the value of b
between the return from the built-in gcc atom and the purpose of this return is b
. Looking in terms of assembly, you have something like the following:
lea RAX, qword ptr [RDI]
Honestly, you cannot swap atomically without locking from two separate memory locations without a hardware operation, such as DCAS or weak load-related / save-storage, or perhaps using some other method such as transactional memory ( which itself tends to use fine-grained blocking).
Secondly, since your function is written right now, if you want your atomic operation to have both receive and release semantics, yes you will either have to place it in __sync_lock_release
, or you are going to need to add a complete memory barrier via __sync_synchronize
. Otherwise, it will only get semantics on __sync_lock_test_and_set
. However, it does not atomically swap two separate memory cells with each other ...
Jason
source share