Skip to content

Commit 42ba740

Browse files
authored
[libc++] Implement C++20 atomic_ref (llvm#76647)
Implement the std::atomic_ref class template by reusing atomic_base_impl. Based on the work from https://reviews.llvm.org/D72240
1 parent 2e7365e commit 42ba740

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+3888
-30
lines changed

libcxx/docs/ReleaseNotes/19.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ Implemented Papers
5353
- P2387R3 - Pipe support for user-defined range adaptors
5454
- P2713R1 - Escaping improvements in ``std::format``
5555
- P2231R1 - Missing ``constexpr`` in ``std::optional`` and ``std::variant``
56+
- P0019R8 - ``std::atomic_ref``
5657

5758
Improvements and New Features
5859
-----------------------------

libcxx/docs/Status/Cxx20Papers.csv

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"`P0905R1 <https://wg21.link/P0905R1>`__","CWG","Symmetry for spaceship","Jacksonville","|Complete|","7.0","|spaceship|"
2727
"`P0966R1 <https://wg21.link/P0966R1>`__","LWG","``string::reserve``\ Should Not Shrink","Jacksonville","|Complete| [#note-P0966]_","12.0"
2828
"","","","","","",""
29-
"`P0019R8 <https://wg21.link/P0019R8>`__","LWG","Atomic Ref","Rapperswil","",""
29+
"`P0019R8 <https://wg21.link/P0019R8>`__","LWG","Atomic Ref","Rapperswil","|Complete|","19.0"
3030
"`P0458R2 <https://wg21.link/P0458R2>`__","LWG","Checking for Existence of an Element in Associative Containers","Rapperswil","|Complete|","13.0"
3131
"`P0475R1 <https://wg21.link/P0475R1>`__","LWG","LWG 2511: guaranteed copy elision for piecewise construction","Rapperswil","|Complete|",""
3232
"`P0476R2 <https://wg21.link/P0476R2>`__","LWG","Bit-casting object representations","Rapperswil","|Complete|","14.0"
@@ -125,7 +125,7 @@
125125
"`P1612R1 <https://wg21.link/P1612R1>`__","LWG","Relocate Endian's Specification","Cologne","|Complete|","10.0"
126126
"`P1614R2 <https://wg21.link/P1614R2>`__","LWG","The Mothership has Landed","Cologne","|In Progress|",""
127127
"`P1638R1 <https://wg21.link/P1638R1>`__","LWG","basic_istream_view::iterator should not be copyable","Cologne","|Complete|","16.0","|ranges|"
128-
"`P1643R1 <https://wg21.link/P1643R1>`__","LWG","Add wait/notify to atomic_ref","Cologne","",""
128+
"`P1643R1 <https://wg21.link/P1643R1>`__","LWG","Add wait/notify to atomic_ref","Cologne","|Complete|","19.0"
129129
"`P1644R0 <https://wg21.link/P1644R0>`__","LWG","Add wait/notify to atomic<shared_ptr>","Cologne","",""
130130
"`P1650R0 <https://wg21.link/P1650R0>`__","LWG","Output std::chrono::days with 'd' suffix","Cologne","|Complete|","16.0"
131131
"`P1651R0 <https://wg21.link/P1651R0>`__","LWG","bind_front should not unwrap reference_wrapper","Cologne","|Complete|","13.0"

libcxx/include/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ set(files
224224
__atomic/atomic_flag.h
225225
__atomic/atomic_init.h
226226
__atomic/atomic_lock_free.h
227+
__atomic/atomic_ref.h
227228
__atomic/atomic_sync.h
228229
__atomic/check_memory_order.h
229230
__atomic/contention_t.h
@@ -232,6 +233,7 @@ set(files
232233
__atomic/is_always_lock_free.h
233234
__atomic/kill_dependency.h
234235
__atomic/memory_order.h
236+
__atomic/to_gcc_order.h
235237
__availability
236238
__bit/bit_cast.h
237239
__bit/bit_ceil.h

libcxx/include/__atomic/atomic_ref.h

Lines changed: 360 additions & 0 deletions
Large diffs are not rendered by default.

libcxx/include/__atomic/atomic_sync.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <__atomic/contention_t.h>
1313
#include <__atomic/cxx_atomic_impl.h>
1414
#include <__atomic/memory_order.h>
15+
#include <__atomic/to_gcc_order.h>
1516
#include <__availability>
1617
#include <__chrono/duration.h>
1718
#include <__config>

libcxx/include/__atomic/check_memory_order.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,8 @@
2727
_LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || __f == memory_order_acq_rel, \
2828
"memory order argument to atomic operation is invalid")
2929

30+
#define _LIBCPP_CHECK_WAIT_MEMORY_ORDER(__m) \
31+
_LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || __m == memory_order_acq_rel, \
32+
"memory order argument to atomic operation is invalid")
33+
3034
#endif // _LIBCPP___ATOMIC_CHECK_MEMORY_ORDER_H

libcxx/include/__atomic/cxx_atomic_impl.h

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define _LIBCPP___ATOMIC_CXX_ATOMIC_IMPL_H
1111

1212
#include <__atomic/memory_order.h>
13+
#include <__atomic/to_gcc_order.h>
1314
#include <__config>
1415
#include <__memory/addressof.h>
1516
#include <__type_traits/is_assignable.h>
@@ -54,32 +55,6 @@ struct __cxx_atomic_base_impl {
5455
_Tp __a_value;
5556
};
5657

57-
_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) {
58-
// Avoid switch statement to make this a constexpr.
59-
return __order == memory_order_relaxed
60-
? __ATOMIC_RELAXED
61-
: (__order == memory_order_acquire
62-
? __ATOMIC_ACQUIRE
63-
: (__order == memory_order_release
64-
? __ATOMIC_RELEASE
65-
: (__order == memory_order_seq_cst
66-
? __ATOMIC_SEQ_CST
67-
: (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL : __ATOMIC_CONSUME))));
68-
}
69-
70-
_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) {
71-
// Avoid switch statement to make this a constexpr.
72-
return __order == memory_order_relaxed
73-
? __ATOMIC_RELAXED
74-
: (__order == memory_order_acquire
75-
? __ATOMIC_ACQUIRE
76-
: (__order == memory_order_release
77-
? __ATOMIC_RELAXED
78-
: (__order == memory_order_seq_cst
79-
? __ATOMIC_SEQ_CST
80-
: (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE : __ATOMIC_CONSUME))));
81-
}
82-
8358
template <typename _Tp>
8459
_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val) {
8560
__cxx_atomic_assign_volatile(__a->__a_value, __val);
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
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+
#ifndef _LIBCPP___ATOMIC_TO_GCC_ORDER_H
10+
#define _LIBCPP___ATOMIC_TO_GCC_ORDER_H
11+
12+
#include <__atomic/memory_order.h>
13+
#include <__config>
14+
15+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16+
# pragma GCC system_header
17+
#endif
18+
19+
_LIBCPP_BEGIN_NAMESPACE_STD
20+
21+
#if defined(__ATOMIC_RELAXED) && defined(__ATOMIC_CONSUME) && defined(__ATOMIC_ACQUIRE) && \
22+
defined(__ATOMIC_RELEASE) && defined(__ATOMIC_ACQ_REL) && defined(__ATOMIC_SEQ_CST)
23+
24+
_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) {
25+
// Avoid switch statement to make this a constexpr.
26+
return __order == memory_order_relaxed
27+
? __ATOMIC_RELAXED
28+
: (__order == memory_order_acquire
29+
? __ATOMIC_ACQUIRE
30+
: (__order == memory_order_release
31+
? __ATOMIC_RELEASE
32+
: (__order == memory_order_seq_cst
33+
? __ATOMIC_SEQ_CST
34+
: (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL : __ATOMIC_CONSUME))));
35+
}
36+
37+
_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) {
38+
// Avoid switch statement to make this a constexpr.
39+
return __order == memory_order_relaxed
40+
? __ATOMIC_RELAXED
41+
: (__order == memory_order_acquire
42+
? __ATOMIC_ACQUIRE
43+
: (__order == memory_order_release
44+
? __ATOMIC_RELAXED
45+
: (__order == memory_order_seq_cst
46+
? __ATOMIC_SEQ_CST
47+
: (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE : __ATOMIC_CONSUME))));
48+
}
49+
50+
#endif
51+
52+
_LIBCPP_END_NAMESPACE_STD
53+
54+
#endif // _LIBCPP___ATOMIC_TO_GCC_ORDER_H

libcxx/include/atomic

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,7 @@ template <class T>
599599
#include <__atomic/atomic_flag.h>
600600
#include <__atomic/atomic_init.h>
601601
#include <__atomic/atomic_lock_free.h>
602+
#include <__atomic/atomic_ref.h>
602603
#include <__atomic/atomic_sync.h>
603604
#include <__atomic/check_memory_order.h>
604605
#include <__atomic/contention_t.h>

0 commit comments

Comments
 (0)