blob: 49a51e02712276f91fcb9d07c714f809fbe5bd2c [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
Arthur O'Dwyerbbb0f2c2022-02-11 18:00:399#include <__config>
10
Jonathan Roelofsb3fcc672014-09-05 19:45:0511#ifndef _LIBCPP_HAS_NO_THREADS
12
Louis Dionne2d7eb9c2023-07-04 15:19:1013# include <mutex>
14# include <shared_mutex>
15# if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)
16# pragma comment(lib, "pthread")
17# endif
Howard Hinnantead6f162013-09-21 01:49:2818
19_LIBCPP_BEGIN_NAMESPACE_STD
20
Marshall Clowf69ae472015-06-30 14:04:1421// Shared Mutex Base
Louis Dionne2d7eb9c2023-07-04 15:19:1022__shared_mutex_base::__shared_mutex_base() : __state_(0) {}
Howard Hinnantead6f162013-09-21 01:49:2823
24// Exclusive ownership
25
Louis Dionne2d7eb9c2023-07-04 15:19:1026void __shared_mutex_base::lock() {
27 unique_lock<mutex> lk(__mut_);
28 while (__state_ & __write_entered_)
29 __gate1_.wait(lk);
30 __state_ |= __write_entered_;
31 while (__state_ & __n_readers_)
32 __gate2_.wait(lk);
Howard Hinnantead6f162013-09-21 01:49:2833}
34
Louis Dionne2d7eb9c2023-07-04 15:19:1035bool __shared_mutex_base::try_lock() {
36 unique_lock<mutex> lk(__mut_);
37 if (__state_ == 0) {
38 __state_ = __write_entered_;
39 return true;
40 }
41 return false;
Howard Hinnantead6f162013-09-21 01:49:2842}
43
Louis Dionne2d7eb9c2023-07-04 15:19:1044void __shared_mutex_base::unlock() {
45 lock_guard<mutex> _(__mut_);
46 __state_ = 0;
47 __gate1_.notify_all();
Howard Hinnantead6f162013-09-21 01:49:2848}
49
50// Shared ownership
51
Louis Dionne2d7eb9c2023-07-04 15:19:1052void __shared_mutex_base::lock_shared() {
53 unique_lock<mutex> lk(__mut_);
54 while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)
55 __gate1_.wait(lk);
56 unsigned num_readers = (__state_ & __n_readers_) + 1;
57 __state_ &= ~__n_readers_;
58 __state_ |= num_readers;
59}
60
61bool __shared_mutex_base::try_lock_shared() {
62 unique_lock<mutex> lk(__mut_);
63 unsigned num_readers = __state_ & __n_readers_;
64 if (!(__state_ & __write_entered_) && num_readers != __n_readers_) {
65 ++num_readers;
Howard Hinnantead6f162013-09-21 01:49:2866 __state_ &= ~__n_readers_;
67 __state_ |= num_readers;
Louis Dionne2d7eb9c2023-07-04 15:19:1068 return true;
69 }
70 return false;
Howard Hinnantead6f162013-09-21 01:49:2871}
72
Louis Dionne2d7eb9c2023-07-04 15:19:1073void __shared_mutex_base::unlock_shared() {
74 lock_guard<mutex> _(__mut_);
75 unsigned num_readers = (__state_ & __n_readers_) - 1;
76 __state_ &= ~__n_readers_;
77 __state_ |= num_readers;
78 if (__state_ & __write_entered_) {
79 if (num_readers == 0)
80 __gate2_.notify_one();
81 } else {
82 if (num_readers == __n_readers_ - 1)
83 __gate1_.notify_one();
84 }
Howard Hinnantead6f162013-09-21 01:49:2885}
86
Marshall Clowf69ae472015-06-30 14:04:1487// Shared Timed Mutex
88// These routines are here for ABI stability
Nikolas Klauser84fc2c32022-09-02 14:19:0789shared_timed_mutex::shared_timed_mutex() : __base_() {}
Louis Dionne2d7eb9c2023-07-04 15:19:1090void shared_timed_mutex::lock() { return __base_.lock(); }
Nikolas Klauser84fc2c32022-09-02 14:19:0791bool shared_timed_mutex::try_lock() { return __base_.try_lock(); }
Louis Dionne2d7eb9c2023-07-04 15:19:1092void shared_timed_mutex::unlock() { return __base_.unlock(); }
Nikolas Klauser84fc2c32022-09-02 14:19:0793void shared_timed_mutex::lock_shared() { return __base_.lock_shared(); }
94bool shared_timed_mutex::try_lock_shared() { return __base_.try_lock_shared(); }
95void shared_timed_mutex::unlock_shared() { return __base_.unlock_shared(); }
Marshall Clowf69ae472015-06-30 14:04:1496
Howard Hinnantead6f162013-09-21 01:49:2897_LIBCPP_END_NAMESPACE_STD
Jonathan Roelofsb3fcc672014-09-05 19:45:0598
99#endif // !_LIBCPP_HAS_NO_THREADS