Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is sample code for atomic_compare_exchange_weak at cppreference correct?

Tags:

At http://en.cppreference.com/w/cpp/atomic/atomic_compare_exchange, the following example code is presented as an example use of std::atomic_compare_exchange_weak:

void append(list* s, node* n)
{
    node* head;
    do {
        head = s->head;
        n->next = head;
    } while(! std::atomic_compare_exchange_weak(s->head, head, n));
}

My understanding is that this has the the effect of comparing *(s->head) with head, when what I believe is desired is to compare s->head with head. Should the first argument to std::atomic_compare_exchange_weak in this example be &(s->head), or am I missing something?

UPDATE: The spec for std::atomic_compare_exchange_weak says:

bool atomic_compare_exchange_weak(volatile A* object, C * expected, C desired) noexcept;
bool atomic_compare_exchange_weak(A* object, C * expected, C desired) noexcept;

Effects: Atomically, compares the contents of the memory pointed to by object...for equality with that in expected...

I took this to mean that *object was compared with expected, but further research suggests that the actual meaning is that *object is compared with *expected (i.e., that "in expected" means "pointed to by expected"). This would imply that the answer to my original question is "no, there is no need to take the address of s->head in the example code at cppreference". But the fact that object must point to a std::atomic<T> and expected must point to a T makes it hard for me to figure out how to correct the code at cppreference so that it will compile. We want to compare the head of the list with a copy of the head of the list, but if the head of the list is of type std::atomic<T>*, the copy would have to be of type T* if the call to std::atomic_compare_exchange_weak is to compile, and I can't find a way to assign a std::atomic<T>* to a T* without a reinterpret_cast. Even then, the third parameter to std::atomic_compare_exchange_weak would need to be of type T, but the example at cppreference shows both the second and third parameters to be of the same type. This suggests to me that the example at cppreference is broken. I tried to fix it, but I was stymied by the need to use a reinterpret_cast that just feels wrong.

Interestingly, in my attempts to figure this stuff out, I checked out the msdn page for std::atomic_compare_exchange_weak, and I was dismayed to see that that page displays the prototypes for std::atomic_compare_exchange_*strong*!

Can somebody post plausible code that uses std::atomic_compare_exchange_weak to insert a node at the front of a singly-linked list? There's no need to worry about the ABA problem or do anything fancy. I'd just like to see skeletal code that compiles.