blob: 61808337369561992274175766b4a724911ba503 [file] [log] [blame]
Louis Dionneeb8650a2021-11-17 21:25:011//===----------------------------------------------------------------------===//
Howard Hinnantead6f162013-09-21 01:49:282//
Chandler Carruth57b08b02019-01-19 10:56:403// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Howard Hinnantead6f162013-09-21 01:49:286//
7//===----------------------------------------------------------------------===//
8
Louis Dionnecf7d4f52023-11-06 00:08:249#include <mutex>
10#include <shared_mutex>
11#if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)
12# pragma comment(lib, "pthread")
13#endif
Howard Hinnantead6f162013-09-21 01:49:2814
15_LIBCPP_BEGIN_NAMESPACE_STD
16
Marshall Clowf69ae472015-06-30 14:04:1417// Shared Mutex Base
Louis Dionne2d7eb9c2023-07-04 15:19:1018__shared_mutex_base::__shared_mutex_base() : __state_(0) {}
Howard Hinnantead6f162013-09-21 01:49:2819
20// Exclusive ownership
21
Louis Dionne2d7eb9c2023-07-04 15:19:1022void __shared_mutex_base::lock() {
23 unique_lock<mutex> lk(__mut_);
24 while (__state_ & __write_entered_)
25 __gate1_.wait(lk);
26 __state_ |= __write_entered_;
27 while (__state_ & __n_readers_)
28 __gate2_.wait(lk);
Howard Hinnantead6f162013-09-21 01:49:2829}
30
Louis Dionne2d7eb9c2023-07-04 15:19:1031bool __shared_mutex_base::try_lock() {
32 unique_lock<mutex> lk(__mut_);
33 if (__state_ == 0) {
34 __state_ = __write_entered_;
35 return true;
36 }
37 return false;
Howard Hinnantead6f162013-09-21 01:49:2838}
39
Louis Dionne2d7eb9c2023-07-04 15:19:1040void __shared_mutex_base::unlock() {
Brotcrunsherab6c89c2025-01-13 15:16:2341 {
42 lock_guard<mutex> _(__mut_);
43 __state_ = 0;
44 }
Louis Dionne2d7eb9c2023-07-04 15:19:1045 __gate1_.notify_all();
Howard Hinnantead6f162013-09-21 01:49:2846}
47
48// Shared ownership
49
Louis Dionne2d7eb9c2023-07-04 15:19:1050void __shared_mutex_base::lock_shared() {
51 unique_lock<mutex> lk(__mut_);
52 while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)
53 __gate1_.wait(lk);
54 unsigned num_readers = (__state_ & __n_readers_) + 1;
55 __state_ &= ~__n_readers_;
56 __state_ |= num_readers;
57}
58
59bool __shared_mutex_base::try_lock_shared() {
60 unique_lock<mutex> lk(__mut_);
61 unsigned num_readers = __state_ & __n_readers_;
62 if (!(__state_ & __write_entered_) && num_readers != __n_readers_) {
63 ++num_readers;
Howard Hinnantead6f162013-09-21 01:49:2864 __state_ &= ~__n_readers_;
65 __state_ |= num_readers;
Louis Dionne2d7eb9c2023-07-04 15:19:1066 return true;
67 }
68 return false;
Howard Hinnantead6f162013-09-21 01:49:2869}
70
Louis Dionne2d7eb9c2023-07-04 15:19:1071void __shared_mutex_base::unlock_shared() {
Brotcrunsherab6c89c2025-01-13 15:16:2372 unique_lock<mutex> lk(__mut_);
Louis Dionne2d7eb9c2023-07-04 15:19:1073 unsigned num_readers = (__state_ & __n_readers_) - 1;
74 __state_ &= ~__n_readers_;
75 __state_ |= num_readers;
76 if (__state_ & __write_entered_) {
Brotcrunsherab6c89c2025-01-13 15:16:2377 if (num_readers == 0) {
78 lk.unlock();
Louis Dionne2d7eb9c2023-07-04 15:19:1079 __gate2_.notify_one();
Brotcrunsherab6c89c2025-01-13 15:16:2380 }
Louis Dionne2d7eb9c2023-07-04 15:19:1081 } else {
Brotcrunsherab6c89c2025-01-13 15:16:2382 if (num_readers == __n_readers_ - 1) {
83 lk.unlock();
Louis Dionne2d7eb9c2023-07-04 15:19:1084 __gate1_.notify_one();
Brotcrunsherab6c89c2025-01-13 15:16:2385 }
Louis Dionne2d7eb9c2023-07-04 15:19:1086 }
Howard Hinnantead6f162013-09-21 01:49:2887}
88
Marshall Clowf69ae472015-06-30 14:04:1489// Shared Timed Mutex
90// These routines are here for ABI stability
Nikolas Klauser84fc2c32022-09-02 14:19:0791shared_timed_mutex::shared_timed_mutex() : __base_() {}
Louis Dionne2d7eb9c2023-07-04 15:19:1092void shared_timed_mutex::lock() { return __base_.lock(); }
Nikolas Klauser84fc2c32022-09-02 14:19:0793bool shared_timed_mutex::try_lock() { return __base_.try_lock(); }
Louis Dionne2d7eb9c2023-07-04 15:19:1094void shared_timed_mutex::unlock() { return __base_.unlock(); }
Nikolas Klauser84fc2c32022-09-02 14:19:0795void shared_timed_mutex::lock_shared() { return __base_.lock_shared(); }
96bool shared_timed_mutex::try_lock_shared() { return __base_.try_lock_shared(); }
97void shared_timed_mutex::unlock_shared() { return __base_.unlock_shared(); }
Marshall Clowf69ae472015-06-30 14:04:1498
Howard Hinnantead6f162013-09-21 01:49:2899_LIBCPP_END_NAMESPACE_STD