]> git.proxmox.com Git - ceph.git/blame - ceph/src/common/ceph_mutex.h
import ceph quincy 17.2.4
[ceph.git] / ceph / src / common / ceph_mutex.h
CommitLineData
11fdf7f2
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
9f95a23c
TL
6#include <utility>
7#include "common/containers.h"
8
11fdf7f2
TL
9// What and why
10// ============
11//
12// For general code making use of mutexes, use these ceph:: types.
13// The key requirement is that you make use of the ceph::make_mutex()
14// and make_recursive_mutex() factory methods, which take a string
15// naming the mutex for the purposes of the lockdep debug variant.
16
9f95a23c 17#if defined(WITH_SEASTAR) && !defined(WITH_ALIEN)
11fdf7f2
TL
18
19namespace ceph {
20 // an empty class satisfying the mutex concept
21 struct dummy_mutex {
22 void lock() {}
23 bool try_lock() {
24 return true;
25 }
26 void unlock() {}
9f95a23c
TL
27 void lock_shared() {}
28 void unlock_shared() {}
29 };
30
31 struct dummy_shared_mutex : dummy_mutex {
32 void lock_shared() {}
33 void unlock_shared() {}
11fdf7f2
TL
34 };
35
36 using mutex = dummy_mutex;
37 using recursive_mutex = dummy_mutex;
9f95a23c 38 using shared_mutex = dummy_shared_mutex;
11fdf7f2
TL
39 // in seastar, we should use a difference interface for enforcing the
40 // semantics of condition_variable
41
42 template <typename ...Args>
43 dummy_mutex make_mutex(Args&& ...args) {
44 return {};
45 }
46
47 template <typename ...Args>
48 recursive_mutex make_recursive_mutex(Args&& ...args) {
49 return {};
50 }
51
9f95a23c
TL
52 template <typename ...Args>
53 shared_mutex make_shared_mutex(Args&& ...args) {
54 return {};
55 }
56
11fdf7f2
TL
57 #define ceph_mutex_is_locked(m) true
58 #define ceph_mutex_is_locked_by_me(m) true
59}
60
9f95a23c 61#else // defined (WITH_SEASTAR) && !defined(WITH_ALIEN)
11fdf7f2
TL
62//
63// For legacy Mutex users that passed recursive=true, use
64// ceph::make_recursive_mutex. For legacy Mutex users that passed
65// lockdep=false, use std::mutex directly.
66
67#ifdef CEPH_DEBUG_MUTEX
68
69// ============================================================================
70// debug (lockdep-capable, various sanity checks and asserts)
71// ============================================================================
2a845540
TL
72//
73// Note: this is known to cause deadlocks on Windows because
74// of the winpthreads shared mutex implementation.
11fdf7f2
TL
75
76#include "common/condition_variable_debug.h"
77#include "common/mutex_debug.h"
78#include "common/shared_mutex_debug.h"
79
80namespace ceph {
81 typedef ceph::mutex_debug mutex;
82 typedef ceph::mutex_recursive_debug recursive_mutex;
83 typedef ceph::condition_variable_debug condition_variable;
84 typedef ceph::shared_mutex_debug shared_mutex;
85
86 // pass arguments to mutex_debug ctor
87 template <typename ...Args>
88 mutex make_mutex(Args&& ...args) {
89 return {std::forward<Args>(args)...};
90 }
91
92 // pass arguments to recursive_mutex_debug ctor
93 template <typename ...Args>
94 recursive_mutex make_recursive_mutex(Args&& ...args) {
95 return {std::forward<Args>(args)...};
96 }
97
98 // pass arguments to shared_mutex_debug ctor
99 template <typename ...Args>
100 shared_mutex make_shared_mutex(Args&& ...args) {
101 return {std::forward<Args>(args)...};
102 }
103
104 // debug methods
105 #define ceph_mutex_is_locked(m) ((m).is_locked())
9f95a23c
TL
106 #define ceph_mutex_is_not_locked(m) (!(m).is_locked())
107 #define ceph_mutex_is_rlocked(m) ((m).is_rlocked())
108 #define ceph_mutex_is_wlocked(m) ((m).is_wlocked())
11fdf7f2 109 #define ceph_mutex_is_locked_by_me(m) ((m).is_locked_by_me())
9f95a23c 110 #define ceph_mutex_is_not_locked_by_me(m) (!(m).is_locked_by_me())
11fdf7f2
TL
111}
112
113#else
114
115// ============================================================================
116// release (fast and minimal)
117// ============================================================================
118
119#include <condition_variable>
120#include <mutex>
11fdf7f2 121
2a845540
TL
122// The winpthreads shared mutex implementation is broken.
123// We'll use boost::shared_mutex instead.
124// https://github.com/msys2/MINGW-packages/issues/3319
125#if __MINGW32__
126#include <boost/thread/shared_mutex.hpp>
127#else
128#include <shared_mutex>
129#endif
11fdf7f2
TL
130
131namespace ceph {
132
133 typedef std::mutex mutex;
134 typedef std::recursive_mutex recursive_mutex;
135 typedef std::condition_variable condition_variable;
2a845540
TL
136
137#if __MINGW32__
138 typedef boost::shared_mutex shared_mutex;
139#else
11fdf7f2 140 typedef std::shared_mutex shared_mutex;
2a845540 141#endif
11fdf7f2
TL
142
143 // discard arguments to make_mutex (they are for debugging only)
144 template <typename ...Args>
2a845540 145 mutex make_mutex(Args&& ...args) {
11fdf7f2
TL
146 return {};
147 }
148 template <typename ...Args>
2a845540 149 recursive_mutex make_recursive_mutex(Args&& ...args) {
11fdf7f2
TL
150 return {};
151 }
152 template <typename ...Args>
2a845540 153 shared_mutex make_shared_mutex(Args&& ...args) {
11fdf7f2
TL
154 return {};
155 }
156
157 // debug methods. Note that these can blindly return true
158 // because any code that does anything other than assert these
159 // are true is broken.
160 #define ceph_mutex_is_locked(m) true
9f95a23c
TL
161 #define ceph_mutex_is_not_locked(m) true
162 #define ceph_mutex_is_rlocked(m) true
163 #define ceph_mutex_is_wlocked(m) true
11fdf7f2 164 #define ceph_mutex_is_locked_by_me(m) true
9f95a23c
TL
165 #define ceph_mutex_is_not_locked_by_me(m) true
166
11fdf7f2
TL
167}
168
169#endif // CEPH_DEBUG_MUTEX
170
171#endif // WITH_SEASTAR
9f95a23c
TL
172
173namespace ceph {
174
175template <class LockT,
176 class LockFactoryT>
177ceph::containers::tiny_vector<LockT> make_lock_container(
178 const std::size_t num_instances,
179 LockFactoryT&& lock_factory)
180{
181 return {
182 num_instances, [&](const std::size_t i, auto emplacer) {
183 // this will be called `num_instances` times
184 new (emplacer.data()) LockT {lock_factory(i)};
185 }
186 };
187}
188} // namespace ceph
189