[libcxx-commits] [libcxx] [libc++] Use public os_sync API instead of private __ulock on newer Apple platforms (PR #202519)
Alastair Harrison via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Jun 20 00:01:55 PDT 2026
aharrison24 wrote:
Just to add a little more context, [p3255](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3255r2.html) proposes to add a `notify_is_always_lock_free` member constant (and potentially `notify_is_always_signal_safe`) to `std::atomic`, `std::atomic_flag` and `std::atomic_ref`, so that users can know whether it is safe to `notify` from a signal handler. Some implementations of `notify` are definitely not signal safe (i.e. when implemented in terms of condition variables), so it's useful to know.
When I spoke to @huixie90, the main point I was making was that with `__ulock_[wake|wait]` you have the option of passing `ULF_NO_ERRNO`, which definitively removes `errno` from the wait and notify paths. By switching to `os_sync_wake_by_address` you lose the ability to opt-out of `errno`, because there is no `ULF_NO_ERRNO` equivalent. The API is defined to always use `errno` for error reporting.
According to [the docs](https://developer.apple.com/documentation/os/os_sync_wake_by_address_any), `os_sync_wake_by_address_...` can fail with `EINVAL`, `ENOENT` or `EDOM`. I _believe_ none of those could happen unless there was an error in the way that the API was being called, so it's probably safe not to check for them. And since `os_sync_wake_by_address_...` is non-blocking then it probably cannot fail with `EINTR`. So calling a notify operation is unlikely to change the state of `errno`.
`os_sync_wait_on_address_...` _can_ fail with `EINTR` or `EFAULT`. Of course this just looks like a spurious wake-up and will be handled just fine. But it does change the state of `errno`. So _if_ someone happened to use an atomic wait in a signal handler (dubious I know, but there are use cases), then they _would_ need to save and restore `errno` to ensure signal safety.
Yes, this is all quite pedantic 😳. It looks to me like if P3255 was adopted then you might need to save the state of `errno` before the call to `os_sync_wait_on_address` and restore it afterwards. Since the `__ulock_wait` path currently doesn't use `ULF_NO_ERRNO` then you'd either need to switch to using that, or do the same save/restore of `errno`.
https://github.com/llvm/llvm-project/pull/202519
More information about the libcxx-commits
mailing list