26 explicit MutexDatum(size_t way_size,
const Equal& equal = Equal{}) : set(way_size, {}, equal) {}
46class ItemMutex final {
48 using HashAndKey =
utils::CachedHash<Key>;
52 ItemMutex(MutexDatum& md, HashAndKey&& key);
60 template <
typename Rep,
typename Period>
61 bool try_lock_for(std::chrono::duration<Rep, Period>);
63 template <
typename Clock,
typename Duration>
64 bool try_lock_until(std::chrono::time_point<Clock, Duration>);
67 bool TryFinishLocking();
70 const HashAndKey key_;
84class MutexSet final : Hash {
86 explicit MutexSet(size_t ways = 1, size_t way_size = 1,
const Hash& hash = Hash{},
const Equal& equal = Equal{});
94 using MutexDatum =
typename ItemMutex<Key, Equal>::MutexDatum;
95 utils::FixedArray<MutexDatum> mutex_data_;
98template <
typename Key,
typename Hash,
typename Equal>
99MutexSet<Key, Hash, Equal>::MutexSet(size_t ways, size_t way_size,
const Hash& hash,
const Equal& equal)
102template <
typename Key,
typename Hash,
typename Equal>
104 const auto hash_value = Hash::operator()(key);
105 const auto size = mutex_data_.size();
108 const auto way = hash_value % size;
109 const auto new_hash = hash_value / size;
111 return ItemMutex<Key, Equal>(mutex_data_[way], {new_hash, std::move(key)});
114template <
typename Key,
typename Equal>
115ItemMutex<Key, Equal>::ItemMutex(MutexDatum& md, HashAndKey&& key) : md_(md), key_(std::move(key)) {}
117template <
typename Key,
typename Equal>
118void ItemMutex<Key, Equal>::lock() {
119 engine::TaskCancellationBlocker blocker;
120 std::unique_lock<engine::Mutex> lock(md_.mutex);
122 [[maybe_unused]]
auto is_locked = md_.cv.Wait(lock, [
this] {
return TryFinishLocking(); });
126template <
typename Key,
typename Equal>
127void ItemMutex<Key, Equal>::unlock() {
128 std::unique_lock lock(md_.mutex);
131 [[maybe_unused]]
auto node = md_.set.extract(key_);
150template <
typename Key,
typename Equal>
151bool ItemMutex<Key, Equal>::try_lock() {
152 std::unique_lock<engine::Mutex> lock(md_.mutex);
153 return TryFinishLocking();
156template <
typename Key,
typename Equal>
157template <
typename Rep,
typename Period>
158bool ItemMutex<Key, Equal>::try_lock_for(std::chrono::duration<Rep, Period> duration) {
159 std::unique_lock<engine::Mutex> lock(md_.mutex);
160 return md_.cv.WaitFor(lock, duration, [
this] {
return TryFinishLocking(); });
163template <
typename Key,
typename Equal>
164template <
typename Clock,
typename Duration>
165bool ItemMutex<Key, Equal>::try_lock_until(std::chrono::time_point<Clock, Duration> time_point) {
166 std::unique_lock<engine::Mutex> lock(md_.mutex);
167 return md_.cv.WaitUntil(lock, time_point, [
this] {
return TryFinishLocking(); });
170template <
typename Key,
typename Equal>
171bool ItemMutex<Key, Equal>::TryFinishLocking() {
172 return md_.set.insert(key_).second;