blob: 9215ff62af3c560e4fb2b5ef9ed01443d638e87c (
plain) (
blame)
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
|
#pragma once
#include <shared_mutex>
#ifdef OS_LINUX /// Because of futex
#include <base/types.h>
#include <base/defines.h>
#include <atomic>
namespace DB
{
// Faster implementation of `std::shared_mutex` based on a pair of futexes
class TSA_CAPABILITY("SharedMutex") SharedMutex
{
public:
SharedMutex();
~SharedMutex() = default;
SharedMutex(const SharedMutex &) = delete;
SharedMutex & operator=(const SharedMutex &) = delete;
// Exclusive ownership
void lock() TSA_ACQUIRE();
bool try_lock() TSA_TRY_ACQUIRE(true);
void unlock() TSA_RELEASE();
// Shared ownership
void lock_shared() TSA_ACQUIRE_SHARED();
bool try_lock_shared() TSA_TRY_ACQUIRE_SHARED(true);
void unlock_shared() TSA_RELEASE_SHARED();
private:
static constexpr UInt64 readers = (1ull << 32ull) - 1ull; // Lower 32 bits of state
static constexpr UInt64 writers = ~readers; // Upper 32 bits of state
alignas(64) std::atomic<UInt64> state;
std::atomic<UInt32> waiters;
};
}
#else
namespace DB
{
using SharedMutex = std::shared_mutex;
}
#endif
|