]> git.proxmox.com Git - ceph.git/blame - ceph/src/common/ceph_atomic.h
import quincy beta 17.1.0
[ceph.git] / ceph / src / common / ceph_atomic.h
CommitLineData
9f95a23c
TL
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
24namespace 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);
20effc67 45 return *this;
9f95a23c
TL
46 }
47 operator T() const noexcept {
48 return value;
49 }
50
51 // We need to differentiate with SFINAE as std::atomic offers beefier
52 // interface for integral types.
20effc67
TL
53
54 template<class TT=T>
55 std::enable_if_t<!std::is_enum_v<TT> && std::is_integral_v<TT>, TT> operator++() {
9f95a23c
TL
56 return ++value;
57 }
20effc67
TL
58 template<class TT=T>
59 std::enable_if_t<!std::is_enum_v<TT> && std::is_integral_v<TT>, TT> operator++(int) {
9f95a23c
TL
60 return value++;
61 }
20effc67
TL
62 template<class TT=T>
63 std::enable_if_t<!std::is_enum_v<TT> && std::is_integral_v<TT>, TT> operator--() {
9f95a23c
TL
64 return --value;
65 }
20effc67
TL
66 template<class TT=T>
67 std::enable_if_t<!std::is_enum_v<TT> && std::is_integral_v<TT>, TT> operator--(int) {
9f95a23c
TL
68 return value--;
69 }
20effc67
TL
70 template<class TT=T>
71 std::enable_if_t<!std::is_enum_v<TT> && std::is_integral_v<TT>, TT> operator+=(const dummy_atomic& b) {
9f95a23c
TL
72 value += b;
73 return value;
74 }
20effc67
TL
75 template<class TT=T>
76 std::enable_if_t<!std::is_enum_v<TT> && std::is_integral_v<TT>, TT> operator-=(const dummy_atomic& b) {
9f95a23c
TL
77 value -= b;
78 return value;
79 }
80
81 static constexpr bool is_always_lock_free = true;
82 };
83
84 template <class T> using atomic = dummy_atomic<T>;
85} // namespace ceph
86
87#else // WITH_SEASTAR
88
89namespace ceph {
90 template <class T> using atomic = ::std::atomic<T>;
91} // namespace ceph
92
93#endif // WITH_SEASTAR