How can I implement ABA counter with c 11 CAS?
To atomically update two values simultaneously, create an atomic, adjacent struct. Suppose you use std::atomic
Note that the atomic object should be lock-free, especially for x86 CPUs. Compilers like gcc7 and later might call libatomic instead of using inline lock cmpxchg16b. In such scenarios, consider the following:
Here's an example of C 11 code that exhibits these characteristics:
#include <atomic> #include <stdint.h> using namespace std; struct node { struct alignas(2*sizeof(node*)) counted_ptr { node * ptr; uintptr_t count; // use pointer-sized integers to avoid padding }; // hack to allow reading just the pointer without lock-cmpxchg16b, // but still without any C++ data race struct counted_ptr_separate { atomic<node *> ptr; atomic<uintptr_t> count_separate; // var name emphasizes that accessing this way isn't atomic with ptr }; static_assert(sizeof(atomic<counted_ptr>) == sizeof(counted_ptr_separate), "atomic<counted_ptr> isn't the same size as the separate version; union type-punning will be bogus"); // TODO: write member functions to read next.ptr or read/write next_and_count union { // anonymous union: the members are directly part of struct node alignas(2*sizeof(node*)) atomic<counted_ptr> next_and_count; counted_ptr_separate next; }; };
In summary, atomically modifying two values simultaneously requires careful design, compiler considerations, and alignment optimizations. By following these guidelines, you can implement lock-free ABA counters in C 11 with efficient and correct code.
The above is the detailed content of How can I implement a lock-free ABA counter in C 11 using CAS and minimize performance overhead?. For more information, please follow other related articles on the PHP Chinese website!