Linux v69820.1blu.de 4.15.0 #1 SMP Mon Sep 30 15:36:27 MSK 2024 x86_64
Apache/2.4.58
Server IP : 195.90.215.149 & Your IP : 216.73.216.250
Domains :
Cant Read [ /etc/named.conf ]
User : www-data
Terminal
Auto Root
Create File
Create Folder
Localroot Suggester
Backdoor Destroyer
Readme
/
usr /
include /
c++ /
13 /
bits /
Delete
Unzip
Name
Size
Permission
Date
Action
algorithmfwd.h
24.17
KB
-rw-r--r--
2025-12-18 20:59
align.h
3.62
KB
-rw-r--r--
2025-12-18 20:59
alloc_traits.h
29.53
KB
-rw-r--r--
2025-12-18 20:59
allocated_ptr.h
3.25
KB
-rw-r--r--
2025-12-18 20:59
allocator.h
8.66
KB
-rw-r--r--
2025-12-18 20:59
atomic_base.h
58.7
KB
-rw-r--r--
2025-12-18 20:59
atomic_futex.h
12.08
KB
-rw-r--r--
2025-12-18 20:59
atomic_lockfree_defines.h
2.3
KB
-rw-r--r--
2025-12-18 20:59
atomic_timed_wait.h
13.18
KB
-rw-r--r--
2025-12-18 20:59
atomic_wait.h
12.41
KB
-rw-r--r--
2025-12-18 20:59
basic_ios.h
15.75
KB
-rw-r--r--
2025-12-18 20:59
basic_ios.tcc
5.67
KB
-rw-r--r--
2025-12-18 20:59
basic_string.h
156.46
KB
-rw-r--r--
2025-12-18 20:59
basic_string.tcc
30.3
KB
-rw-r--r--
2025-12-18 20:59
boost_concept_check.h
29.13
KB
-rw-r--r--
2025-12-18 20:59
c++0x_warning.h
1.44
KB
-rw-r--r--
2025-12-18 20:59
char_traits.h
29.05
KB
-rw-r--r--
2025-12-18 20:59
charconv.h
3.58
KB
-rw-r--r--
2025-12-18 20:59
chrono.h
47.06
KB
-rw-r--r--
2025-12-18 20:59
chrono_io.h
76.97
KB
-rw-r--r--
2025-12-18 20:59
codecvt.h
24.9
KB
-rw-r--r--
2025-12-18 20:59
concept_check.h
3.32
KB
-rw-r--r--
2025-12-18 20:59
cow_string.h
130.97
KB
-rw-r--r--
2025-12-18 20:59
cpp_type_traits.h
14.51
KB
-rw-r--r--
2025-12-18 20:59
cxxabi_forced.h
1.77
KB
-rw-r--r--
2025-12-18 20:59
cxxabi_init_exception.h
2.17
KB
-rw-r--r--
2025-12-18 20:59
deque.tcc
41.38
KB
-rw-r--r--
2025-12-18 20:59
enable_special_members.h
12.16
KB
-rw-r--r--
2025-12-18 20:59
erase_if.h
2.09
KB
-rw-r--r--
2025-12-18 20:59
exception.h
2.41
KB
-rw-r--r--
2025-12-18 20:59
exception_defines.h
1.61
KB
-rw-r--r--
2025-12-18 20:59
exception_ptr.h
8.05
KB
-rw-r--r--
2025-12-18 20:59
forward_list.h
49.92
KB
-rw-r--r--
2025-12-18 20:59
forward_list.tcc
13.71
KB
-rw-r--r--
2025-12-18 20:59
fs_dir.h
17.26
KB
-rw-r--r--
2025-12-18 20:59
fs_fwd.h
10.66
KB
-rw-r--r--
2025-12-18 20:59
fs_ops.h
10.49
KB
-rw-r--r--
2025-12-18 20:59
fs_path.h
41.47
KB
-rw-r--r--
2025-12-18 20:59
fstream.tcc
32.64
KB
-rw-r--r--
2025-12-18 20:59
functexcept.h
4.02
KB
-rw-r--r--
2025-12-18 20:59
functional_hash.h
8.79
KB
-rw-r--r--
2025-12-18 20:59
gslice.h
5.39
KB
-rw-r--r--
2025-12-18 20:59
gslice_array.h
7.71
KB
-rw-r--r--
2025-12-18 20:59
hash_bytes.h
2.1
KB
-rw-r--r--
2025-12-18 20:59
hashtable.h
88.71
KB
-rw-r--r--
2025-12-18 20:59
hashtable_policy.h
63.92
KB
-rw-r--r--
2025-12-18 20:59
indirect_array.h
7.72
KB
-rw-r--r--
2025-12-18 20:59
invoke.h
6.08
KB
-rw-r--r--
2025-12-18 20:59
ios_base.h
31.51
KB
-rw-r--r--
2025-12-18 20:59
istream.tcc
31.79
KB
-rw-r--r--
2025-12-18 20:59
iterator_concepts.h
33.72
KB
-rw-r--r--
2025-12-18 20:59
list.tcc
17.63
KB
-rw-r--r--
2025-12-18 20:59
locale_classes.h
24.79
KB
-rw-r--r--
2025-12-18 20:59
locale_classes.tcc
10.61
KB
-rw-r--r--
2025-12-18 20:59
locale_conv.h
18.74
KB
-rw-r--r--
2025-12-18 20:59
locale_facets.h
91.72
KB
-rw-r--r--
2025-12-18 20:59
locale_facets.tcc
40.42
KB
-rw-r--r--
2025-12-18 20:59
locale_facets_nonio.h
69.1
KB
-rw-r--r--
2025-12-18 20:59
locale_facets_nonio.tcc
55.69
KB
-rw-r--r--
2025-12-18 20:59
localefwd.h
5.8
KB
-rw-r--r--
2025-12-18 20:59
mask_array.h
7.77
KB
-rw-r--r--
2025-12-18 20:59
max_size_type.h
22
KB
-rw-r--r--
2025-12-18 20:59
memory_resource.h
15.73
KB
-rw-r--r--
2025-12-18 20:59
memoryfwd.h
2.47
KB
-rw-r--r--
2025-12-18 20:59
mofunc_impl.h
7.45
KB
-rw-r--r--
2025-12-18 20:59
move.h
6.51
KB
-rw-r--r--
2025-12-18 20:59
move_only_function.h
6.12
KB
-rw-r--r--
2025-12-18 20:59
nested_exception.h
7.51
KB
-rw-r--r--
2025-12-18 20:59
new_allocator.h
7.27
KB
-rw-r--r--
2025-12-18 20:59
node_handle.h
11.08
KB
-rw-r--r--
2025-12-18 20:59
ostream.tcc
11.83
KB
-rw-r--r--
2025-12-18 20:59
ostream_insert.h
3.98
KB
-rw-r--r--
2025-12-18 20:59
parse_numbers.h
7.8
KB
-rw-r--r--
2025-12-18 20:59
postypes.h
7.33
KB
-rw-r--r--
2025-12-18 20:59
predefined_ops.h
9.94
KB
-rw-r--r--
2025-12-18 20:59
ptr_traits.h
8.29
KB
-rw-r--r--
2025-12-18 20:59
quoted_string.h
5.01
KB
-rw-r--r--
2025-12-18 20:59
random.h
178.84
KB
-rw-r--r--
2025-12-18 20:59
random.tcc
103.48
KB
-rw-r--r--
2025-12-18 20:59
range_access.h
11.67
KB
-rw-r--r--
2025-12-18 20:59
ranges_algo.h
128.65
KB
-rw-r--r--
2025-12-18 20:59
ranges_algobase.h
18.37
KB
-rw-r--r--
2025-12-18 20:59
ranges_base.h
28.82
KB
-rw-r--r--
2025-12-18 20:59
ranges_cmp.h
5.9
KB
-rw-r--r--
2025-12-18 20:59
ranges_uninitialized.h
17.71
KB
-rw-r--r--
2025-12-18 20:59
ranges_util.h
24.96
KB
-rw-r--r--
2025-12-18 20:59
refwrap.h
13.27
KB
-rw-r--r--
2025-12-18 20:59
regex.h
104.32
KB
-rw-r--r--
2025-12-18 20:59
regex.tcc
16.1
KB
-rw-r--r--
2025-12-18 20:59
regex_automaton.h
10.55
KB
-rw-r--r--
2025-12-18 20:59
regex_automaton.tcc
7.6
KB
-rw-r--r--
2025-12-18 20:59
regex_compiler.h
15.92
KB
-rw-r--r--
2025-12-18 20:59
regex_compiler.tcc
18.48
KB
-rw-r--r--
2025-12-18 20:59
regex_constants.h
14.54
KB
-rw-r--r--
2025-12-18 20:59
regex_error.h
5.35
KB
-rw-r--r--
2025-12-18 20:59
regex_executor.h
8.81
KB
-rw-r--r--
2025-12-18 20:59
regex_executor.tcc
18.49
KB
-rw-r--r--
2025-12-18 20:59
regex_scanner.h
6.88
KB
-rw-r--r--
2025-12-18 20:59
regex_scanner.tcc
14.59
KB
-rw-r--r--
2025-12-18 20:59
requires_hosted.h
1.36
KB
-rw-r--r--
2025-12-18 20:59
semaphore_base.h
7.7
KB
-rw-r--r--
2025-12-18 20:59
shared_ptr.h
38.14
KB
-rw-r--r--
2025-12-18 20:59
shared_ptr_atomic.h
22.79
KB
-rw-r--r--
2025-12-18 20:59
shared_ptr_base.h
65.18
KB
-rw-r--r--
2025-12-18 20:59
slice_array.h
9.39
KB
-rw-r--r--
2025-12-18 20:59
specfun.h
46.07
KB
-rw-r--r--
2025-12-18 20:59
sstream.tcc
9.91
KB
-rw-r--r--
2025-12-18 20:59
std_abs.h
4.63
KB
-rw-r--r--
2025-12-18 20:59
std_function.h
23.12
KB
-rw-r--r--
2025-12-18 20:59
std_mutex.h
6.69
KB
-rw-r--r--
2025-12-18 20:59
std_thread.h
9.84
KB
-rw-r--r--
2025-12-18 20:59
stl_algo.h
212.39
KB
-rw-r--r--
2025-12-18 20:59
stl_algobase.h
74.97
KB
-rw-r--r--
2025-12-18 20:59
stl_bvector.h
41.58
KB
-rw-r--r--
2025-12-18 20:59
stl_construct.h
8.47
KB
-rw-r--r--
2025-12-18 20:59
stl_deque.h
76.34
KB
-rw-r--r--
2025-12-18 20:59
stl_function.h
43.97
KB
-rw-r--r--
2025-12-18 20:59
stl_heap.h
20.31
KB
-rw-r--r--
2025-12-18 20:59
stl_iterator.h
92.81
KB
-rw-r--r--
2025-12-18 20:59
stl_iterator_base_funcs.h
8.75
KB
-rw-r--r--
2025-12-18 20:59
stl_iterator_base_types.h
9.48
KB
-rw-r--r--
2025-12-18 20:59
stl_list.h
70.62
KB
-rw-r--r--
2025-12-18 20:59
stl_map.h
54.86
KB
-rw-r--r--
2025-12-18 20:59
stl_multimap.h
42.71
KB
-rw-r--r--
2025-12-18 20:59
stl_multiset.h
36.87
KB
-rw-r--r--
2025-12-18 20:59
stl_numeric.h
14.25
KB
-rw-r--r--
2025-12-18 20:59
stl_pair.h
36.43
KB
-rw-r--r--
2025-12-18 20:59
stl_queue.h
28.06
KB
-rw-r--r--
2025-12-18 20:59
stl_raw_storage_iter.h
3.91
KB
-rw-r--r--
2025-12-18 20:59
stl_relops.h
4.47
KB
-rw-r--r--
2025-12-18 20:59
stl_set.h
37.13
KB
-rw-r--r--
2025-12-18 20:59
stl_stack.h
13.71
KB
-rw-r--r--
2025-12-18 20:59
stl_tempbuf.h
8.67
KB
-rw-r--r--
2025-12-18 20:59
stl_tree.h
72.06
KB
-rw-r--r--
2025-12-18 20:59
stl_uninitialized.h
35.63
KB
-rw-r--r--
2025-12-18 20:59
stl_vector.h
68.88
KB
-rw-r--r--
2025-12-18 20:59
stream_iterator.h
8.2
KB
-rw-r--r--
2025-12-18 20:59
streambuf.tcc
4.58
KB
-rw-r--r--
2025-12-18 20:59
streambuf_iterator.h
15.57
KB
-rw-r--r--
2025-12-18 20:59
string_view.tcc
7
KB
-rw-r--r--
2025-12-18 20:59
stringfwd.h
2.56
KB
-rw-r--r--
2025-12-18 20:59
this_thread_sleep.h
3.21
KB
-rw-r--r--
2025-12-18 20:59
uniform_int_dist.h
13
KB
-rw-r--r--
2025-12-18 20:59
unique_lock.h
6.16
KB
-rw-r--r--
2025-12-18 20:59
unique_ptr.h
35.62
KB
-rw-r--r--
2025-12-18 20:59
unordered_map.h
75.11
KB
-rw-r--r--
2025-12-18 20:59
unordered_set.h
61.7
KB
-rw-r--r--
2025-12-18 20:59
uses_allocator.h
6.91
KB
-rw-r--r--
2025-12-18 20:59
uses_allocator_args.h
8.53
KB
-rw-r--r--
2025-12-18 20:59
utility.h
8.12
KB
-rw-r--r--
2025-12-18 20:59
valarray_after.h
22.74
KB
-rw-r--r--
2025-12-18 20:59
valarray_array.h
20.8
KB
-rw-r--r--
2025-12-18 20:59
valarray_array.tcc
7.08
KB
-rw-r--r--
2025-12-18 20:59
valarray_before.h
18.69
KB
-rw-r--r--
2025-12-18 20:59
vector.tcc
31.5
KB
-rw-r--r--
2025-12-18 20:59
Save
Rename
// shared_ptr atomic access -*- C++ -*- // Copyright (C) 2014-2023 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/shared_ptr_atomic.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{memory} */ #ifndef _SHARED_PTR_ATOMIC_H #define _SHARED_PTR_ATOMIC_H 1 #include <bits/atomic_base.h> // Annotations for the custom locking in atomic<shared_ptr<T>>. #if defined _GLIBCXX_TSAN && __has_include(<sanitizer/tsan_interface.h>) #include <sanitizer/tsan_interface.h> #define _GLIBCXX_TSAN_MUTEX_DESTROY(X) \ __tsan_mutex_destroy(X, __tsan_mutex_not_static) #define _GLIBCXX_TSAN_MUTEX_TRY_LOCK(X) \ __tsan_mutex_pre_lock(X, __tsan_mutex_not_static|__tsan_mutex_try_lock) #define _GLIBCXX_TSAN_MUTEX_TRY_LOCK_FAILED(X) __tsan_mutex_post_lock(X, \ __tsan_mutex_not_static|__tsan_mutex_try_lock_failed, 0) #define _GLIBCXX_TSAN_MUTEX_LOCKED(X) \ __tsan_mutex_post_lock(X, __tsan_mutex_not_static, 0) #define _GLIBCXX_TSAN_MUTEX_PRE_UNLOCK(X) __tsan_mutex_pre_unlock(X, 0) #define _GLIBCXX_TSAN_MUTEX_POST_UNLOCK(X) __tsan_mutex_post_unlock(X, 0) #define _GLIBCXX_TSAN_MUTEX_PRE_SIGNAL(X) __tsan_mutex_pre_signal(X, 0) #define _GLIBCXX_TSAN_MUTEX_POST_SIGNAL(X) __tsan_mutex_post_signal(X, 0) #else #define _GLIBCXX_TSAN_MUTEX_DESTROY(X) #define _GLIBCXX_TSAN_MUTEX_TRY_LOCK(X) #define _GLIBCXX_TSAN_MUTEX_TRY_LOCK_FAILED(X) #define _GLIBCXX_TSAN_MUTEX_LOCKED(X) #define _GLIBCXX_TSAN_MUTEX_PRE_UNLOCK(X) #define _GLIBCXX_TSAN_MUTEX_POST_UNLOCK(X) #define _GLIBCXX_TSAN_MUTEX_PRE_SIGNAL(X) #define _GLIBCXX_TSAN_MUTEX_POST_SIGNAL(X) #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @addtogroup pointer_abstractions * @relates shared_ptr * @{ */ /// @cond undocumented struct _Sp_locker { _Sp_locker(const _Sp_locker&) = delete; _Sp_locker& operator=(const _Sp_locker&) = delete; #ifdef __GTHREADS explicit _Sp_locker(const void*) noexcept; _Sp_locker(const void*, const void*) noexcept; ~_Sp_locker(); private: unsigned char _M_key1; unsigned char _M_key2; #else explicit _Sp_locker(const void*, const void* = nullptr) { } #endif }; /// @endcond /** * @brief Report whether shared_ptr atomic operations are lock-free. * @param __p A non-null pointer to a shared_ptr object. * @return True if atomic access to @c *__p is lock-free, false otherwise. * @{ */ template<typename _Tp, _Lock_policy _Lp> inline bool atomic_is_lock_free(const __shared_ptr<_Tp, _Lp>*) { #ifdef __GTHREADS return __gthread_active_p() == 0; #else return true; #endif } template<typename _Tp> inline bool atomic_is_lock_free(const shared_ptr<_Tp>* __p) { return std::atomic_is_lock_free<_Tp, __default_lock_policy>(__p); } /// @} /** * @brief Atomic load for shared_ptr objects. * @param __p A non-null pointer to a shared_ptr object. * @return @c *__p * * The memory order shall not be `memory_order_release` or * `memory_order_acq_rel`. * @{ */ template<typename _Tp> inline shared_ptr<_Tp> atomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order) { _Sp_locker __lock{__p}; return *__p; } template<typename _Tp> inline shared_ptr<_Tp> atomic_load(const shared_ptr<_Tp>* __p) { return std::atomic_load_explicit(__p, memory_order_seq_cst); } template<typename _Tp, _Lock_policy _Lp> inline __shared_ptr<_Tp, _Lp> atomic_load_explicit(const __shared_ptr<_Tp, _Lp>* __p, memory_order) { _Sp_locker __lock{__p}; return *__p; } template<typename _Tp, _Lock_policy _Lp> inline __shared_ptr<_Tp, _Lp> atomic_load(const __shared_ptr<_Tp, _Lp>* __p) { return std::atomic_load_explicit(__p, memory_order_seq_cst); } /// @} /** * @brief Atomic store for shared_ptr objects. * @param __p A non-null pointer to a shared_ptr object. * @param __r The value to store. * * The memory order shall not be `memory_order_acquire` or * `memory_order_acq_rel`. * @{ */ template<typename _Tp> inline void atomic_store_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order) { _Sp_locker __lock{__p}; __p->swap(__r); // use swap so that **__p not destroyed while lock held } template<typename _Tp> inline void atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r) { std::atomic_store_explicit(__p, std::move(__r), memory_order_seq_cst); } template<typename _Tp, _Lock_policy _Lp> inline void atomic_store_explicit(__shared_ptr<_Tp, _Lp>* __p, __shared_ptr<_Tp, _Lp> __r, memory_order) { _Sp_locker __lock{__p}; __p->swap(__r); // use swap so that **__p not destroyed while lock held } template<typename _Tp, _Lock_policy _Lp> inline void atomic_store(__shared_ptr<_Tp, _Lp>* __p, __shared_ptr<_Tp, _Lp> __r) { std::atomic_store_explicit(__p, std::move(__r), memory_order_seq_cst); } /// @} /** * @brief Atomic exchange for shared_ptr objects. * @param __p A non-null pointer to a shared_ptr object. * @param __r New value to store in `*__p`. * @return The original value of `*__p` * @{ */ template<typename _Tp> inline shared_ptr<_Tp> atomic_exchange_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order) { _Sp_locker __lock{__p}; __p->swap(__r); return __r; } template<typename _Tp> inline shared_ptr<_Tp> atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r) { return std::atomic_exchange_explicit(__p, std::move(__r), memory_order_seq_cst); } template<typename _Tp, _Lock_policy _Lp> inline __shared_ptr<_Tp, _Lp> atomic_exchange_explicit(__shared_ptr<_Tp, _Lp>* __p, __shared_ptr<_Tp, _Lp> __r, memory_order) { _Sp_locker __lock{__p}; __p->swap(__r); return __r; } template<typename _Tp, _Lock_policy _Lp> inline __shared_ptr<_Tp, _Lp> atomic_exchange(__shared_ptr<_Tp, _Lp>* __p, __shared_ptr<_Tp, _Lp> __r) { return std::atomic_exchange_explicit(__p, std::move(__r), memory_order_seq_cst); } /// @} /** * @brief Atomic compare-and-swap for shared_ptr objects. * @param __p A non-null pointer to a shared_ptr object. * @param __v A non-null pointer to a shared_ptr object. * @param __w A non-null pointer to a shared_ptr object. * @return True if `*__p` was equivalent to `*__v`, false otherwise. * * The memory order for failure shall not be `memory_order_release` or * `memory_order_acq_rel`. * @{ */ template<typename _Tp> bool atomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w, memory_order, memory_order) { shared_ptr<_Tp> __x; // goes out of scope after __lock _Sp_locker __lock{__p, __v}; owner_less<shared_ptr<_Tp>> __less; if (*__p == *__v && !__less(*__p, *__v) && !__less(*__v, *__p)) { __x = std::move(*__p); *__p = std::move(__w); return true; } __x = std::move(*__v); *__v = *__p; return false; } template<typename _Tp> inline bool atomic_compare_exchange_strong(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w) { return std::atomic_compare_exchange_strong_explicit(__p, __v, std::move(__w), memory_order_seq_cst, memory_order_seq_cst); } template<typename _Tp> inline bool atomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w, memory_order __success, memory_order __failure) { return std::atomic_compare_exchange_strong_explicit(__p, __v, std::move(__w), __success, __failure); } template<typename _Tp> inline bool atomic_compare_exchange_weak(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w) { return std::atomic_compare_exchange_weak_explicit(__p, __v, std::move(__w), memory_order_seq_cst, memory_order_seq_cst); } template<typename _Tp, _Lock_policy _Lp> bool atomic_compare_exchange_strong_explicit(__shared_ptr<_Tp, _Lp>* __p, __shared_ptr<_Tp, _Lp>* __v, __shared_ptr<_Tp, _Lp> __w, memory_order, memory_order) { __shared_ptr<_Tp, _Lp> __x; // goes out of scope after __lock _Sp_locker __lock{__p, __v}; owner_less<__shared_ptr<_Tp, _Lp>> __less; if (*__p == *__v && !__less(*__p, *__v) && !__less(*__v, *__p)) { __x = std::move(*__p); *__p = std::move(__w); return true; } __x = std::move(*__v); *__v = *__p; return false; } template<typename _Tp, _Lock_policy _Lp> inline bool atomic_compare_exchange_strong(__shared_ptr<_Tp, _Lp>* __p, __shared_ptr<_Tp, _Lp>* __v, __shared_ptr<_Tp, _Lp> __w) { return std::atomic_compare_exchange_strong_explicit(__p, __v, std::move(__w), memory_order_seq_cst, memory_order_seq_cst); } template<typename _Tp, _Lock_policy _Lp> inline bool atomic_compare_exchange_weak_explicit(__shared_ptr<_Tp, _Lp>* __p, __shared_ptr<_Tp, _Lp>* __v, __shared_ptr<_Tp, _Lp> __w, memory_order __success, memory_order __failure) { return std::atomic_compare_exchange_strong_explicit(__p, __v, std::move(__w), __success, __failure); } template<typename _Tp, _Lock_policy _Lp> inline bool atomic_compare_exchange_weak(__shared_ptr<_Tp, _Lp>* __p, __shared_ptr<_Tp, _Lp>* __v, __shared_ptr<_Tp, _Lp> __w) { return std::atomic_compare_exchange_weak_explicit(__p, __v, std::move(__w), memory_order_seq_cst, memory_order_seq_cst); } /// @} /// @} group pointer_abstractions #if __cplusplus >= 202002L # define __cpp_lib_atomic_shared_ptr 201711L template<typename _Tp> struct atomic; /** * @addtogroup pointer_abstractions * @relates shared_ptr * @{ */ template<typename _Up> static constexpr bool __is_shared_ptr = false; template<typename _Up> static constexpr bool __is_shared_ptr<shared_ptr<_Up>> = true; template<typename _Tp> class _Sp_atomic { using value_type = _Tp; friend struct atomic<_Tp>; // An atomic version of __shared_count<> and __weak_count<>. // Stores a _Sp_counted_base<>* but uses the LSB as a lock. struct _Atomic_count { // Either __shared_count<> or __weak_count<> using __count_type = decltype(_Tp::_M_refcount); // _Sp_counted_base<>* using pointer = decltype(__count_type::_M_pi); // Ensure we can use the LSB as the lock bit. static_assert(alignof(remove_pointer_t<pointer>) > 1); constexpr _Atomic_count() noexcept = default; explicit _Atomic_count(__count_type&& __c) noexcept : _M_val(reinterpret_cast<uintptr_t>(__c._M_pi)) { __c._M_pi = nullptr; } ~_Atomic_count() { auto __val = _M_val.load(memory_order_relaxed); _GLIBCXX_TSAN_MUTEX_DESTROY(&_M_val); __glibcxx_assert(!(__val & _S_lock_bit)); if (auto __pi = reinterpret_cast<pointer>(__val)) { if constexpr (__is_shared_ptr<_Tp>) __pi->_M_release(); else __pi->_M_weak_release(); } } _Atomic_count(const _Atomic_count&) = delete; _Atomic_count& operator=(const _Atomic_count&) = delete; // Precondition: Caller does not hold lock! // Returns the raw pointer value without the lock bit set. pointer lock(memory_order __o) const noexcept { // To acquire the lock we flip the LSB from 0 to 1. auto __current = _M_val.load(memory_order_relaxed); while (__current & _S_lock_bit) { #if __cpp_lib_atomic_wait __detail::__thread_relax(); #endif __current = _M_val.load(memory_order_relaxed); } _GLIBCXX_TSAN_MUTEX_TRY_LOCK(&_M_val); while (!_M_val.compare_exchange_strong(__current, __current | _S_lock_bit, __o, memory_order_relaxed)) { _GLIBCXX_TSAN_MUTEX_TRY_LOCK_FAILED(&_M_val); #if __cpp_lib_atomic_wait __detail::__thread_relax(); #endif __current = __current & ~_S_lock_bit; _GLIBCXX_TSAN_MUTEX_TRY_LOCK(&_M_val); } _GLIBCXX_TSAN_MUTEX_LOCKED(&_M_val); return reinterpret_cast<pointer>(__current); } // Precondition: caller holds lock! void unlock(memory_order __o) const noexcept { _GLIBCXX_TSAN_MUTEX_PRE_UNLOCK(&_M_val); _M_val.fetch_sub(1, __o); _GLIBCXX_TSAN_MUTEX_POST_UNLOCK(&_M_val); } // Swaps the values of *this and __c, and unlocks *this. // Precondition: caller holds lock! void _M_swap_unlock(__count_type& __c, memory_order __o) noexcept { if (__o != memory_order_seq_cst) __o = memory_order_release; auto __x = reinterpret_cast<uintptr_t>(__c._M_pi); _GLIBCXX_TSAN_MUTEX_PRE_UNLOCK(&_M_val); __x = _M_val.exchange(__x, __o); _GLIBCXX_TSAN_MUTEX_POST_UNLOCK(&_M_val); __c._M_pi = reinterpret_cast<pointer>(__x & ~_S_lock_bit); } #if __cpp_lib_atomic_wait // Precondition: caller holds lock! void _M_wait_unlock(memory_order __o) const noexcept { _GLIBCXX_TSAN_MUTEX_PRE_UNLOCK(&_M_val); auto __v = _M_val.fetch_sub(1, memory_order_relaxed); _GLIBCXX_TSAN_MUTEX_POST_UNLOCK(&_M_val); _M_val.wait(__v & ~_S_lock_bit, __o); } void notify_one() noexcept { _GLIBCXX_TSAN_MUTEX_PRE_SIGNAL(&_M_val); _M_val.notify_one(); _GLIBCXX_TSAN_MUTEX_POST_SIGNAL(&_M_val); } void notify_all() noexcept { _GLIBCXX_TSAN_MUTEX_PRE_SIGNAL(&_M_val); _M_val.notify_all(); _GLIBCXX_TSAN_MUTEX_POST_SIGNAL(&_M_val); } #endif private: mutable __atomic_base<uintptr_t> _M_val{0}; static constexpr uintptr_t _S_lock_bit{1}; }; typename _Tp::element_type* _M_ptr = nullptr; _Atomic_count _M_refcount; static typename _Atomic_count::pointer _S_add_ref(typename _Atomic_count::pointer __p) { if (__p) { if constexpr (__is_shared_ptr<_Tp>) __p->_M_add_ref_copy(); else __p->_M_weak_add_ref(); } return __p; } constexpr _Sp_atomic() noexcept = default; explicit _Sp_atomic(value_type __r) noexcept : _M_ptr(__r._M_ptr), _M_refcount(std::move(__r._M_refcount)) { } ~_Sp_atomic() = default; _Sp_atomic(const _Sp_atomic&) = delete; void operator=(const _Sp_atomic&) = delete; value_type load(memory_order __o) const noexcept { __glibcxx_assert(__o != memory_order_release && __o != memory_order_acq_rel); // Ensure that the correct value of _M_ptr is visible after locking., // by upgrading relaxed or consume to acquire. if (__o != memory_order_seq_cst) __o = memory_order_acquire; value_type __ret; auto __pi = _M_refcount.lock(__o); __ret._M_ptr = _M_ptr; __ret._M_refcount._M_pi = _S_add_ref(__pi); _M_refcount.unlock(memory_order_relaxed); return __ret; } void swap(value_type& __r, memory_order __o) noexcept { _M_refcount.lock(memory_order_acquire); std::swap(_M_ptr, __r._M_ptr); _M_refcount._M_swap_unlock(__r._M_refcount, __o); } bool compare_exchange_strong(value_type& __expected, value_type __desired, memory_order __o, memory_order __o2) noexcept { bool __result = true; auto __pi = _M_refcount.lock(memory_order_acquire); if (_M_ptr == __expected._M_ptr && __pi == __expected._M_refcount._M_pi) { _M_ptr = __desired._M_ptr; _M_refcount._M_swap_unlock(__desired._M_refcount, __o); } else { _Tp __sink = std::move(__expected); __expected._M_ptr = _M_ptr; __expected._M_refcount._M_pi = _S_add_ref(__pi); _M_refcount.unlock(__o2); __result = false; } return __result; } #if __cpp_lib_atomic_wait void wait(value_type __old, memory_order __o) const noexcept { auto __pi = _M_refcount.lock(memory_order_acquire); if (_M_ptr == __old._M_ptr && __pi == __old._M_refcount._M_pi) _M_refcount._M_wait_unlock(__o); else _M_refcount.unlock(memory_order_relaxed); } void notify_one() noexcept { _M_refcount.notify_one(); } void notify_all() noexcept { _M_refcount.notify_all(); } #endif }; template<typename _Tp> struct atomic<shared_ptr<_Tp>> { public: using value_type = shared_ptr<_Tp>; static constexpr bool is_always_lock_free = false; bool is_lock_free() const noexcept { return false; } constexpr atomic() noexcept = default; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 3661. constinit atomic<shared_ptr<T>> a(nullptr); should work constexpr atomic(nullptr_t) noexcept : atomic() { } atomic(shared_ptr<_Tp> __r) noexcept : _M_impl(std::move(__r)) { } atomic(const atomic&) = delete; void operator=(const atomic&) = delete; shared_ptr<_Tp> load(memory_order __o = memory_order_seq_cst) const noexcept { return _M_impl.load(__o); } operator shared_ptr<_Tp>() const noexcept { return _M_impl.load(memory_order_seq_cst); } void store(shared_ptr<_Tp> __desired, memory_order __o = memory_order_seq_cst) noexcept { _M_impl.swap(__desired, __o); } void operator=(shared_ptr<_Tp> __desired) noexcept { _M_impl.swap(__desired, memory_order_seq_cst); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 3893. LWG 3661 broke atomic<shared_ptr<T>> a; a = nullptr; void operator=(nullptr_t) noexcept { store(nullptr); } shared_ptr<_Tp> exchange(shared_ptr<_Tp> __desired, memory_order __o = memory_order_seq_cst) noexcept { _M_impl.swap(__desired, __o); return __desired; } bool compare_exchange_strong(shared_ptr<_Tp>& __expected, shared_ptr<_Tp> __desired, memory_order __o, memory_order __o2) noexcept { return _M_impl.compare_exchange_strong(__expected, __desired, __o, __o2); } bool compare_exchange_strong(value_type& __expected, value_type __desired, memory_order __o = memory_order_seq_cst) noexcept { memory_order __o2; switch (__o) { case memory_order_acq_rel: __o2 = memory_order_acquire; break; case memory_order_release: __o2 = memory_order_relaxed; break; default: __o2 = __o; } return compare_exchange_strong(__expected, std::move(__desired), __o, __o2); } bool compare_exchange_weak(value_type& __expected, value_type __desired, memory_order __o, memory_order __o2) noexcept { return compare_exchange_strong(__expected, std::move(__desired), __o, __o2); } bool compare_exchange_weak(value_type& __expected, value_type __desired, memory_order __o = memory_order_seq_cst) noexcept { return compare_exchange_strong(__expected, std::move(__desired), __o); } #if __cpp_lib_atomic_wait void wait(value_type __old, memory_order __o = memory_order_seq_cst) const noexcept { _M_impl.wait(std::move(__old), __o); } void notify_one() noexcept { _M_impl.notify_one(); } void notify_all() noexcept { _M_impl.notify_all(); } #endif private: _Sp_atomic<shared_ptr<_Tp>> _M_impl; }; template<typename _Tp> struct atomic<weak_ptr<_Tp>> { public: using value_type = weak_ptr<_Tp>; static constexpr bool is_always_lock_free = false; bool is_lock_free() const noexcept { return false; } constexpr atomic() noexcept = default; atomic(weak_ptr<_Tp> __r) noexcept : _M_impl(move(__r)) { } atomic(const atomic&) = delete; void operator=(const atomic&) = delete; weak_ptr<_Tp> load(memory_order __o = memory_order_seq_cst) const noexcept { return _M_impl.load(__o); } operator weak_ptr<_Tp>() const noexcept { return _M_impl.load(memory_order_seq_cst); } void store(weak_ptr<_Tp> __desired, memory_order __o = memory_order_seq_cst) noexcept { _M_impl.swap(__desired, __o); } void operator=(weak_ptr<_Tp> __desired) noexcept { _M_impl.swap(__desired, memory_order_seq_cst); } weak_ptr<_Tp> exchange(weak_ptr<_Tp> __desired, memory_order __o = memory_order_seq_cst) noexcept { _M_impl.swap(__desired, __o); return __desired; } bool compare_exchange_strong(weak_ptr<_Tp>& __expected, weak_ptr<_Tp> __desired, memory_order __o, memory_order __o2) noexcept { return _M_impl.compare_exchange_strong(__expected, __desired, __o, __o2); } bool compare_exchange_strong(value_type& __expected, value_type __desired, memory_order __o = memory_order_seq_cst) noexcept { memory_order __o2; switch (__o) { case memory_order_acq_rel: __o2 = memory_order_acquire; break; case memory_order_release: __o2 = memory_order_relaxed; break; default: __o2 = __o; } return compare_exchange_strong(__expected, std::move(__desired), __o, __o2); } bool compare_exchange_weak(value_type& __expected, value_type __desired, memory_order __o, memory_order __o2) noexcept { return compare_exchange_strong(__expected, std::move(__desired), __o, __o2); } bool compare_exchange_weak(value_type& __expected, value_type __desired, memory_order __o = memory_order_seq_cst) noexcept { return compare_exchange_strong(__expected, std::move(__desired), __o); } #if __cpp_lib_atomic_wait void wait(value_type __old, memory_order __o = memory_order_seq_cst) const noexcept { _M_impl.wait(std::move(__old), __o); } void notify_one() noexcept { _M_impl.notify_one(); } void notify_all() noexcept { _M_impl.notify_all(); } #endif private: _Sp_atomic<weak_ptr<_Tp>> _M_impl; }; /// @} group pointer_abstractions #endif // C++20 _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // _SHARED_PTR_ATOMIC_H