Boost logo

Boost :

Subject: Re: [boost] storing intrusive_ptr in atomic?!
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2013-10-25 08:58:40


On Friday 25 October 2013 16:50:12 you wrote:
> On Friday 25 October 2013 14:35:39 Oliver Kowalke wrote:
> > 2013/10/25 Andrey Semashev <andrey.semashev_at_[hidden]>
> >
> > > That won't work for several reasons. First, as outlined before, you
> > > can't
> > > store intrusive_ptr in atomic<>. Assuming you store T* instead, then you
> > > can't
> > > use nullptr as the first argument because CAS accepts it as an lvalue
> > > reference. Next, the removal of the pointer is not correct because when
> > > CAS
> > > fails the pointer is just loaded from the atomic, so you release the
> > > pointer
> > > and the dangling pointer is left in the array. You have to load e first,
> > > then
> > > make a loop with CAS and only release if it succeeds and the loaded
> > > pointer is
> > > not NULL.
> >
> > array< atomic< T * >, 100 > a{ atomic< T* >( 0) };
>
> That's not correct, it should be:
>
> array< atomic< T * >, 100 > a;
> for (auto& p : a)
> p.store(NULL, memory_order_relaxed);
>
> > T * desired = new T();
> > T * expected = 0;
> > if ( a[index].compare_exchange_strong( expected, desired) ) {
> >
> > // desired added
> >
> > }
> >
> > T * expected1 = 0;
> > T * expected2 = 0;
> > if ( ! a[index].compare_exchange_strong( expected1, expected2) ) {
> >
> > // expected1 is not NULL, expected1 removed == a[index] contains NULL
> >
> > }
>
> No, that's not right. If compare_exchange_strong returns false, the
> operation have failed and a[index] != NULL (at least, that's how
> compare_exchange_strong have left it). It should be:
>
> T* expected = a[index].load(memory_order_acquire);
> while (!a[index].compare_exchange_weak(expected, NULL, memory_order_release,
> memory_order_acquire))
> {
> }
>
> if (expected)
> // The expected value was removed from the array
> else
> // The array element was removed by some other thread

Actually, it can be much simpler:

T* p = a[index].exchange(NULL);
if (expected)
  // The expected value was removed from the array
else
  // The array element was removed by some other thread


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk