-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsynopsis.hpp
59 lines (42 loc) · 1.7 KB
/
synopsis.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#pragma once
#include "mcs_v1/private.hpp"
#include <type_traits>
namespace mcs_v1 {
// mcs.hpp =====================================================================
/// Type of lock holder objects.
struct holder : Private::holder_t {
/// Holder constructor is empty - no initialization is necessary.
holder() = default;
/// Holders are not CopyConstructible.
holder(const holder &) = delete;
/// Holders are not CopyAssignable.
holder &operator=(const holder &) = delete;
};
// Holders are no larger than pointers.
static_assert(sizeof(holder) <= sizeof(void *));
/// Type of lock objects.
struct lock : Private::lock_t {
/// Constructs a lock by zero initializing it.
lock() = default;
/// Locks are not CopyConstructible.
lock(const lock &) = delete;
/// Locks are not CopyAssignable.
lock &operator=(const lock &) = delete;
/// Default maximum spin count before bailing out to atomic wait.
static constexpr unsigned default_max_spin_count = 1000;
/// Acquires the lock. The `holder` must be allocated by the caller, kept
/// alive while the lock is held, and passed to `release` to release the lock.
/// A unique holder per live acquire is required.
void acquire(holder &holder,
unsigned max_spin_count = default_max_spin_count);
/// Releases the lock. The `holder` must be the same instance that was passed
/// in a matching call to `acquire`.
void release(holder &holder);
/// Invokes the action holding the lock.
template <class Action>
std::invoke_result_t<Action>
holding(Action &&action, unsigned max_spin_count = default_max_spin_count);
};
// Locks are no larger than pointers.
static_assert(sizeof(lock) <= sizeof(void *));
} // namespace mcs_v1