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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With