mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-12-12 17:32:32 +00:00
53 lines
1.1 KiB
C++
53 lines
1.1 KiB
C++
#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
|