C++ Logo

std-discussion

Advanced search

Re: Synchronization of atomic notify and wait

From: Andrey Semashev <andrey.semashev_at_[hidden]>
Date: Tue, 26 Jul 2022 11:26:55 +0300
On 7/26/22 08:45, Thiago Macieira via Std-Discussion wrote:
> On Monday, 25 July 2022 19:02:14 PDT Andrey Semashev via Std-Discussion wrote:
>> On 7/26/22 03:49, Thiago Macieira via Std-Discussion wrote:
>>> On Monday, 25 July 2022 17:26:56 PDT Ryan Nicholl wrote:
>>>> 64 bit wait is just two 32bit waits right next to each other... not
>>>> complicated with waitv. So yes, waitv allows any size wait.
>>>
>>> Right, for 64-bit you could do that. But you couldn't do a half 32-bit
>>> wait to support uint16_t or, for that matter, a quarter-word wait to wait
>>> on an atomic<bool> or atomic_flag.
>>
>> You can, with masking. It may upset sanitizers and cause excessive
>> spurious wakeups, but it'll work. I was under impression that
>> gcc/libstdc++ used masking when small enough atomics were not supported
>> natively and I'd be surprised if they didn't do this for wait/notify.
>
> Do you mean by using FUTEX_WAIT_BITSET?

No, I meant this:

1. Load an aligned 32-bit word that contains the smaller (e.g. 8-bit)
atomic.
2. Shift and mask it to get rid of the excess bits.
3. Perform the operation.
4. Shift and merge the modified value with the original excess bits so
that the excess bits are unchanged.
5. Perform a 32-bit CAS.
6. Goto #2 if failed.

But now that I think of it, it may not work if the target supports
smaller than 32-bit atomics but not futex. The architecture may not
synchronize overlapping atomic operations on different addresses and/or
of different sizes. Even x86 formally has this restriction, even though
I think it works in practice and is being used in used at least in glibc
(though I'm not totally sure). So, in general, it may not work
efficiently (i.e. you would have to implement smaller atomics with
32-bit ones even though smaller atomics are directly supported by the
hardware).

Received on 2022-07-26 08:27:00