C++ Logo

std-discussion

Advanced search

std::atomic_ref lifetime

From: Артём Колпаков <ddvamp007_at_[hidden]>
Date: Thu, 28 Jul 2022 22:34:26 +0300
Good day.
My name is Artyom. Sorry, English is not my native language and I hope
there are no mistakes here. I believe this email has been sent to the C++
community, which will be able to help me (If I misunderstood the purpose of
this address, where should I ask a question.).

To the topic. In the following sentence of the standard: "The lifetime
([basic.life]) of an object referenced by *ptr shall exceed the lifetime of
all atomic_­refs that reference the object.
<http://eel.is/c++draft/atomics.ref.generic.general#3.sentence-1>", I can't
understand why, instead of lifetime restrictions, do not prohibit the use
of std::atomic_ref after the lifetime of the referenced object ends (like
dangling references). This is inconvenient, because before deleting an
object, you have to delete atomic_ref. Even more, the restriction from the
standard does not allow, as it seems to me, to use valid programs.
I'll give you an example.

struct Node {
    std::atomic<Node *> next = nullptr;
    SomeOpaqueType value;
};

Two threads have a ptr pointer to an instance of Node in dynamic memory.
Both threads execute

if (ptr->next.exchange(ptr)) {
    use(ptr->value);
    delete ptr;
}

The first thread will get nullptr and forget about ptr when the last one
processes it.
It would be great to make the next intrusive not atomic, and when atomicity
is needed, create std::atomic_ref.

template <typename T>
struct IntrusiveNode {
    T *next = nullptr;
};

struct Node : IntrusiveNode<Node> {
    SomeOpaqueType value;
};

{
    std::atomic_ref next{ptr->next};
    if (not next.exchange(ptr)) {
        return;
    }
}
use(ptr->value);
delete ptr;

The example looks clumsy and it is not always possible to do this. Even
more, in this example, this is not possible due to the wording of the
standard: there is no guarantee that at the time of deletion, in another
thread, the lifetime of std::atomic_ref has already ended.
Is the wording of the standard incorrect, or is it motivated by something?

Thank you for your attention.
Artyom Kolpakov

Received on 2022-07-28 19:34:44