]> git.proxmox.com Git - ceph.git/blob - ceph/src/common/ceph_atomic.h
import 15.2.0 Octopus source
[ceph.git] / ceph / src / common / ceph_atomic.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #pragma once
5
6 #include <atomic>
7
8 // What and why
9 // ============
10 //
11 // ceph::atomic – thin wrapper to differentiate behavior of atomics.
12 //
13 // Not all users of the common truly need costly atomic operations to
14 // synchronize data between CPUs and threads. Some, like crimson-osd,
15 // stick to shared-nothing approach. Enforcing issue of atomics in
16 // such cases is wasteful – on x86 any locked instruction works actually
17 // like a full memory barrier stalling execution till CPU's store and
18 // load buffers are drained.
19
20 #if defined(WITH_SEASTAR) && !defined(WITH_BLUESTORE)
21
22 #include <type_traits>
23
24 namespace ceph {
25 template <class T>
26 class dummy_atomic {
27 T value;
28
29 public:
30 dummy_atomic() = default;
31 dummy_atomic(const dummy_atomic&) = delete;
32 dummy_atomic(T value) : value(std::move(value)) {
33 }
34 bool is_lock_free() const noexcept {
35 return true;
36 }
37 void store(T desired, std::memory_order) noexcept {
38 value = std::move(desired);
39 }
40 T load(std::memory_order = std::memory_order_seq_cst) const noexcept {
41 return value;
42 }
43 T operator=(T desired) noexcept {
44 value = std::move(desired);
45 }
46 operator T() const noexcept {
47 return value;
48 }
49
50 // We need to differentiate with SFINAE as std::atomic offers beefier
51 // interface for integral types.
52 std::enable_if_t<std::is_integral_v<T>, T> operator++() {
53 return ++value;
54 }
55 std::enable_if_t<std::is_integral_v<T>, T> operator++(int) {
56 return value++;
57 }
58 std::enable_if_t<std::is_integral_v<T>, T> operator--() {
59 return --value;
60 }
61 std::enable_if_t<std::is_integral_v<T>, T> operator--(int) {
62 return value--;
63 }
64 std::enable_if_t<std::is_integral_v<T>, T> operator+=(const dummy_atomic& b) {
65 value += b;
66 return value;
67 }
68 std::enable_if_t<std::is_integral_v<T>, T> operator-=(const dummy_atomic& b) {
69 value -= b;
70 return value;
71 }
72
73 static constexpr bool is_always_lock_free = true;
74 };
75
76 template <class T> using atomic = dummy_atomic<T>;
77 } // namespace ceph
78
79 #else // WITH_SEASTAR
80
81 namespace ceph {
82 template <class T> using atomic = ::std::atomic<T>;
83 } // namespace ceph
84
85 #endif // WITH_SEASTAR