Skip to content

Commit acfb349

Browse files
committed
comments
1 parent 3959e16 commit acfb349

File tree

5 files changed

+76
-15
lines changed

5 files changed

+76
-15
lines changed

libcxx/docs/ReleaseNotes/22.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ Improvements and New Features
8282
- The ``std::{generate, generate_n}`` and ``std::ranges::generate_n`` algorithms have been optimized for segmented
8383
iterators, resulting in a performance improvement for ``std::deque<short>`` and
8484
``std::join_view<vector<vector<short>>>`` iterators.
85+
- ``std::atomic::wait`` has been refactored to accept more types to use platform native wait functions directly.
86+
This is guarded behind the ABI Macro ``_LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE``.
8587

8688
Deprecations and Removals
8789
-------------------------

libcxx/include/__atomic/atomic_sync.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <__type_traits/has_unique_object_representation.h>
2222
#include <__type_traits/invoke.h>
2323
#include <__type_traits/is_same.h>
24+
#include <__type_traits/is_trivially_copyable.h>
2425
#include <__type_traits/void_t.h>
2526
#include <__utility/declval.h>
2627
#include <cstring>
@@ -139,7 +140,8 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __has_native_atomic_wait_impl(size_t __size
139140

140141
template <class _Tp>
141142
concept __has_native_atomic_wait =
142-
has_unique_object_representations_v<_Tp> && __has_native_atomic_wait_impl(sizeof(_Tp));
143+
has_unique_object_representations_v<_Tp> && is_trivially_copyable_v<_Tp> &&
144+
__has_native_atomic_wait_impl(sizeof(_Tp));
143145

144146
# else // _LIBCPP_ABI_ATOMIC_WAIT_NATIVE_BY_SIZE
145147

libcxx/lib/abi/CHANGELOG.TXT

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,6 @@ New entries should be added directly below the "Version" header.
1616
Version 22.0
1717
------------
1818

19-
* [libc++] Remove __time_get_storage::{__analyze,init} from the ABI
20-
21-
These functions have never been used outside the dylib, so there is no point in exporting them.
22-
23-
All platforms
24-
-------------
25-
Symbol removed: _ZNSt3__118__time_get_storageIcE4initERKNS_5ctypeIcEE
26-
Symbol removed: _ZNSt3__118__time_get_storageIcE9__analyzeEcRKNS_5ctypeIcEE
27-
Symbol removed: _ZNSt3__118__time_get_storageIwE4initERKNS_5ctypeIwEE
28-
Symbol removed: _ZNSt3__118__time_get_storageIwE9__analyzeEcRKNS_5ctypeIwEE
29-
3019
* [libc++] Allows any types of size 4 and 8 to use native platform ulock_wait
3120

3221
This patch added symbols for platform wait functions with the size of the type
@@ -41,6 +30,17 @@ Version 22.0
4130
Symbol added: __ZNSt3__126__atomic_notify_all_nativeILm8EEEvPKv
4231
Symbol added: __ZNSt3__132__atomic_notify_one_global_tableEPKv
4332

33+
* [libc++] Remove __time_get_storage::{__analyze,init} from the ABI
34+
35+
These functions have never been used outside the dylib, so there is no point in exporting them.
36+
37+
All platforms
38+
-------------
39+
Symbol removed: _ZNSt3__118__time_get_storageIcE4initERKNS_5ctypeIcEE
40+
Symbol removed: _ZNSt3__118__time_get_storageIcE9__analyzeEcRKNS_5ctypeIcEE
41+
Symbol removed: _ZNSt3__118__time_get_storageIwE4initERKNS_5ctypeIwEE
42+
Symbol removed: _ZNSt3__118__time_get_storageIwE9__analyzeEcRKNS_5ctypeIwEE
43+
4444
------------
4545
Version 21.0
4646
------------

libcxx/src/atomic.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -240,10 +240,10 @@ __contention_wait(__cxx_atomic_contention_t* __waiter_count, void const* __addre
240240
__cxx_atomic_fetch_sub(__waiter_count, __cxx_contention_t(1), memory_order_release);
241241
}
242242

243-
#if defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)
244-
static constexpr size_t __cache_line_size = std::hardware_constructive_interference_size;
245-
#elif defined(__APPLE__) && defined(__aarch64__)
243+
#if defined(__APPLE__) && defined(__aarch64__)
246244
static constexpr size_t __cache_line_size = 128;
245+
#elif defined(__cpp_lib_hardware_interference_size)
246+
static constexpr size_t __cache_line_size = std::hardware_constructive_interference_size;
247247
#else
248248
static constexpr size_t __cache_line_size = 64;
249249
#endif
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: no-threads
10+
// UNSUPPORTED: c++03, c++11, c++14, c++17
11+
12+
// This is a stress test for std::atomic::wait for lost wake ups.
13+
14+
// <atomic>
15+
16+
#include <atomic>
17+
#include <functional>
18+
#include <thread>
19+
#include <vector>
20+
21+
#include "make_test_thread.h"
22+
23+
constexpr int num_waiters = 8;
24+
constexpr int num_iterations = 10'000;
25+
26+
void wait(std::atomic<int>& waiter_ready, const std::atomic<int>& state) {
27+
for (int i = 0; i < num_iterations; ++i) {
28+
auto old_state = state.load(std::memory_order_acquire);
29+
waiter_ready.fetch_add(1, std::memory_order_acq_rel);
30+
state.wait(old_state, std::memory_order_acquire);
31+
}
32+
}
33+
34+
void notify(std::atomic<int>& waiter_ready, std::atomic<int>& state) {
35+
for (int i = 0; i < num_iterations; ++i) {
36+
while (waiter_ready.load(std::memory_order_acquire) < num_waiters) {
37+
std::this_thread::yield();
38+
}
39+
waiter_ready.store(0, std::memory_order_release);
40+
state.fetch_add(1, std::memory_order_acq_rel);
41+
state.notify_all();
42+
}
43+
}
44+
45+
int main(int, char**) {
46+
for (int run = 0; run < 20; ++run) {
47+
std::atomic<int> waiter_ready(0);
48+
std::atomic<int> state(0);
49+
std::vector<std::jthread> threads;
50+
for (int i = 0; i < 8; ++i)
51+
threads.push_back(support::make_test_jthread(wait, std::ref(waiter_ready), std::cref(state)));
52+
53+
threads.push_back(support::make_test_jthread(notify, std::ref(waiter_ready), std::ref(state)));
54+
}
55+
56+
return 0;
57+
}

0 commit comments

Comments
 (0)