Skip to content

Commit ccfb5fe

Browse files
committed
[libc++] Extract a clean base support API for std::atomic
This doesn't change the operations that std::atomic is based on, but it reorganizes the C11 / GCC implementation split to make it clearer what's the base support layer and what's not.
1 parent 820403c commit ccfb5fe

File tree

5 files changed

+409
-260
lines changed

5 files changed

+409
-260
lines changed

libcxx/include/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,13 @@ set(files
212212
__atomic/atomic_sync.h
213213
__atomic/check_memory_order.h
214214
__atomic/contention_t.h
215-
__atomic/cxx_atomic_impl.h
216215
__atomic/fence.h
217216
__atomic/is_always_lock_free.h
218217
__atomic/kill_dependency.h
219218
__atomic/memory_order.h
219+
__atomic/support/c11.h
220+
__atomic/support/gcc.h
221+
__atomic/support.h
220222
__atomic/to_gcc_order.h
221223
__bit/bit_cast.h
222224
__bit/bit_ceil.h

libcxx/include/__atomic/support.h

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
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_SUPPORT_H
10+
#define _LIBCPP___ATOMIC_SUPPORT_H
11+
12+
#include <__config>
13+
#include <__type_traits/is_trivially_copyable.h>
14+
15+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16+
# pragma GCC system_header
17+
#endif
18+
19+
//
20+
// This file implements base support for atomics on the platform.
21+
//
22+
// The following operations and types must be implemented (where _Atmc
23+
// is __cxx_atomic_base_impl for readability):
24+
//
25+
// clang-format off
26+
//
27+
// template <class _Tp>
28+
// struct __cxx_atomic_base_impl;
29+
//
30+
// #define __cxx_atomic_is_lock_free(__size)
31+
//
32+
// void __cxx_atomic_thread_fence(memory_order __order) noexcept;
33+
// void __cxx_atomic_signal_fence(memory_order __order) noexcept;
34+
//
35+
// template <class _Tp>
36+
// void __cxx_atomic_init(_Atmc<_Tp> volatile* __a, _Tp __val) noexcept;
37+
// template <class _Tp>
38+
// void __cxx_atomic_init(_Atmc<_Tp>* __a, _Tp __val) noexcept;
39+
//
40+
// template <class _Tp>
41+
// void __cxx_atomic_store(_Atmc<_Tp> volatile* __a, _Tp __val, memory_order __order) noexcept;
42+
// template <class _Tp>
43+
// void __cxx_atomic_store(_Atmc<_Tp>* __a, _Tp __val, memory_order __order) noexcept;
44+
//
45+
// template <class _Tp>
46+
// _Tp __cxx_atomic_load(_Atmc<_Tp> const volatile* __a, memory_order __order) noexcept;
47+
// template <class _Tp>
48+
// _Tp __cxx_atomic_load(_Atmc<_Tp> const* __a, memory_order __order) noexcept;
49+
//
50+
// template <class _Tp>
51+
// void __cxx_atomic_load_inplace(_Atmc<_Tp> const volatile* __a, _Tp* __dst, memory_order __order) noexcept;
52+
// template <class _Tp>
53+
// void __cxx_atomic_load_inplace(_Atmc<_Tp> const* __a, _Tp* __dst, memory_order __order) noexcept;
54+
//
55+
// template <class _Tp>
56+
// _Tp __cxx_atomic_exchange(_Atmc<_Tp> volatile* __a, _Tp __value, memory_order __order) noexcept;
57+
// template <class _Tp>
58+
// _Tp __cxx_atomic_exchange(_Atmc<_Tp>* __a, _Tp __value, memory_order __order) noexcept;
59+
//
60+
// template <class _Tp>
61+
// bool __cxx_atomic_compare_exchange_strong(_Atmc<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) noexcept;
62+
// template <class _Tp>
63+
// bool __cxx_atomic_compare_exchange_strong(_Atmc<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) noexcept;
64+
//
65+
// template <class _Tp>
66+
// bool __cxx_atomic_compare_exchange_weak(_Atmc<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) noexcept;
67+
// template <class _Tp>
68+
// bool __cxx_atomic_compare_exchange_weak(_Atmc<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) noexcept;
69+
//
70+
// template <class _Tp>
71+
// _Tp __cxx_atomic_fetch_add(_Atmc<_Tp> volatile* __a, _Tp __delta, memory_order __order) noexcept;
72+
// template <class _Tp>
73+
// _Tp __cxx_atomic_fetch_add(_Atmc<_Tp>* __a, _Tp __delta, memory_order __order) noexcept;
74+
//
75+
// template <class _Tp>
76+
// _Tp* __cxx_atomic_fetch_add(_Atmc<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) noexcept;
77+
// template <class _Tp>
78+
// _Tp* __cxx_atomic_fetch_add(_Atmc<_Tp*>* __a, ptrdiff_t __delta, memory_order __order) noexcept;
79+
//
80+
// template <class _Tp>
81+
// _Tp __cxx_atomic_fetch_sub(_Atmc<_Tp> volatile* __a, _Tp __delta, memory_order __order) noexcept;
82+
// template <class _Tp>
83+
// _Tp __cxx_atomic_fetch_sub(_Atmc<_Tp>* __a, _Tp __delta, memory_order __order) noexcept;
84+
// template <class _Tp>
85+
// _Tp* __cxx_atomic_fetch_sub(_Atmc<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) noexcept;
86+
// template <class _Tp>
87+
// _Tp* __cxx_atomic_fetch_sub(_Atmc<_Tp*>* __a, ptrdiff_t __delta, memory_order __order) noexcept;
88+
//
89+
// template <class _Tp>
90+
// _Tp __cxx_atomic_fetch_and(_Atmc<_Tp> volatile* __a, _Tp __pattern, memory_order __order) noexcept;
91+
// template <class _Tp>
92+
// _Tp __cxx_atomic_fetch_and(_Atmc<_Tp>* __a, _Tp __pattern, memory_order __order) noexcept;
93+
//
94+
// template <class _Tp>
95+
// _Tp __cxx_atomic_fetch_or(_Atmc<_Tp> volatile* __a, _Tp __pattern, memory_order __order) noexcept;
96+
// template <class _Tp>
97+
// _Tp __cxx_atomic_fetch_or(_Atmc<_Tp>* __a, _Tp __pattern, memory_order __order) noexcept;
98+
// template <class _Tp>
99+
// _Tp __cxx_atomic_fetch_xor(_Atmc<_Tp> volatile* __a, _Tp __pattern, memory_order __order) noexcept;
100+
// template <class _Tp>
101+
// _Tp __cxx_atomic_fetch_xor(_Atmc<_Tp>* __a, _Tp __pattern, memory_order __order) noexcept;
102+
//
103+
// clang-format on
104+
//
105+
106+
#if _LIBCPP_HAS_GCC_ATOMIC_IMP
107+
# include <__atomic/support/gcc.h>
108+
#elif _LIBCPP_HAS_C_ATOMIC_IMP
109+
# include <__atomic/support/c11.h>
110+
#endif
111+
112+
_LIBCPP_BEGIN_NAMESPACE_STD
113+
114+
template <typename _Tp, typename _Base = __cxx_atomic_base_impl<_Tp> >
115+
struct __cxx_atomic_impl : public _Base {
116+
static_assert(is_trivially_copyable<_Tp>::value, "std::atomic<T> requires that 'T' be a trivially copyable type");
117+
118+
_LIBCPP_HIDE_FROM_ABI __cxx_atomic_impl() _NOEXCEPT = default;
119+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp __value) _NOEXCEPT : _Base(__value) {}
120+
};
121+
122+
_LIBCPP_END_NAMESPACE_STD
123+
124+
#endif // _LIBCPP___ATOMIC_SUPPORT_H

0 commit comments

Comments
 (0)