Date: Thu, 15 Jan 2026 20:11:59 +0000
> If you're having in mind a specific usage scenario involving std::latch,
where one of the waiters destroys the latch as soon as it wakes up, then
that would be an error of the user of std::latch.
The standard explicitly says this is allowed and well defined behavior.
where one of the waiters destroys the latch as soon as it wakes up, then
that would be an error of the user of std::latch.
The standard explicitly says this is allowed and well defined behavior.
-- Ryan P. Nicholl Tel: (678)-358-7765 On Wednesday, January 14th, 2026 at 13:00, Andrey Semashev via Std-Proposals <std-proposals_at_[hidden]> wrote: > On 14 Jan 2026 03:55, Ryan P. Nicholl via Std-Proposals wrote: > > > It has come to my attention that it isn't possible to implement data > > structures like std::latch or a uselock using the C++ atomic library > > without undefined behavior. > > > > Namely, std::latch guarantees that count_down doesn't cause a race even > > if there are waiters, this isn't possible to implement on the abstract > > machine unless the notification can be safely executed atomically with > > the value set. Ordinary notify_one has undefined behavior if it races > > with the destructor of the atomic object. > > > I'm not sure what the destructor of the atomic has to do with > count_down. Assuming std::latch implementation is using std::atomic > internally (which is not the only possible implementation), I don't see > why count_down would ever destroy the atomic. > > If you're having in mind a specific usage scenario involving std::latch, > where one of the waiters destroys the latch as soon as it wakes up, then > that would be an error of the user of std::latch. > > > Of course, it's possible to implement std::latch using things like > > SYS_futex, so this isn't impossible to implement per se, only impossible > > to implement using the C++ standard library without relying on undefined > > behavior. > > > > I would propose adding atomic_compare_exchange_and_notify. This would > > have the same behavior as atomic compare_exchange followed by notify, > > except that it doesn't cause undefined behavior if a waiter unblocks on > > the new value and destroys the atomic, which could race with notify. > > > Aside from the issue with the motivating example with std::latch, > blessing only compare_exchange but not other modifying operations seem > unnecessarily specific. > > Note that it is generally impossible to make the modifying operation and > the notifying operation atomic with the currently available futex-like > system APIs. For a lock-free atomic, the modifying operation is > typically one or few instructions that are distinct from a notifying > syscall, and it is always possible that a blocked thread wakes up and > destroys the atomic after the modifying operation has completed but > before the notifying syscall has started. Note that "destroying" may not > be limited to just C++ object model but also include e.g. unmapping > memory location where the atomic was placed. > > Even if you move the modifying operation inside the notifying syscall, > under the lock that presumably protects the in-kernel list of waiters, > that wouldn't help because a thread calling a wait may observe the > modified value of the atomic before blocking and return immediately and > destroy the atomic. > > So the proposed operation doesn't really solve anything. The only thing > that you could ask for is to bless notifying operations by saying they > don't access the atomic and don't need a valid object at its location. > Or not say it (the status quo), which means users must ensure the atomic > object exists at all times while its operations are called. For the > std::latch example, this means users must not destroy it until all > waiters and callers of count_down have returned from the respective > methods (e.g. by using std::shared_ptrstd::latch). > > > -- > Std-Proposals mailing list > Std-Proposals_at_[hidden] > https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
Received on 2026-01-15 20:12:07
