]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/histogram/accumulators/thread_safe.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / histogram / accumulators / thread_safe.hpp
1 // Copyright 2019 Hans Dembinski
2 //
3 // Distributed under the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt
5 // or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7 #ifndef BOOST_HISTOGRAM_ACCUMULATORS_THREAD_SAFE_HPP
8 #define BOOST_HISTOGRAM_ACCUMULATORS_THREAD_SAFE_HPP
9
10 #include <atomic>
11 #include <boost/core/nvp.hpp>
12 #include <boost/histogram/fwd.hpp>
13 #include <type_traits>
14
15 namespace boost {
16 namespace histogram {
17 namespace accumulators {
18
19 // cannot use new mechanism with accumulators::thread_safe
20 template <class T>
21 struct is_thread_safe<thread_safe<T>> : std::true_type {};
22
23 /** Thread-safe adaptor for builtin integral numbers.
24
25 This adaptor uses atomic operations to make concurrent increments and additions safe for
26 the stored value.
27
28 On common computing platforms, the adapted integer has the same size and
29 alignment as underlying type. The atomicity is implemented with a special CPU
30 instruction. On exotic platforms the size of the adapted number may be larger and/or the
31 type may have different alignment, which means it cannot be tightly packed into arrays.
32
33 @tparam T type to adapt, must be an integral type.
34 */
35 template <class T>
36 class [[deprecated("use count<T, true> instead; "
37 "thread_safe<T> will be removed in boost-1.79")]] thread_safe
38 : public std::atomic<T> {
39 public:
40 using value_type = T;
41 using super_t = std::atomic<T>;
42
43 thread_safe() noexcept : super_t(static_cast<T>(0)) {}
44 // non-atomic copy and assign is allowed, because storage is locked in this case
45 thread_safe(const thread_safe& o) noexcept : super_t(o.load()) {}
46 thread_safe& operator=(const thread_safe& o) noexcept {
47 super_t::store(o.load());
48 return *this;
49 }
50
51 thread_safe(value_type arg) : super_t(arg) {}
52 thread_safe& operator=(value_type arg) {
53 super_t::store(arg);
54 return *this;
55 }
56
57 thread_safe& operator+=(const thread_safe& arg) {
58 operator+=(arg.load());
59 return *this;
60 }
61 thread_safe& operator+=(value_type arg) {
62 super_t::fetch_add(arg, std::memory_order_relaxed);
63 return *this;
64 }
65 thread_safe& operator++() {
66 operator+=(static_cast<value_type>(1));
67 return *this;
68 }
69
70 template <class Archive>
71 void serialize(Archive & ar, unsigned /* version */) {
72 auto value = super_t::load();
73 ar& make_nvp("value", value);
74 super_t::store(value);
75 }
76 };
77
78 } // namespace accumulators
79 } // namespace histogram
80 } // namespace boost
81
82 #endif