blob: 73d4dc1c1c7a9dfb79f4aa2e2b1bf8c248d405c1 [file] [log] [blame]
Louis Dionne9bd93882021-11-17 16:25:01 -05001//===----------------------------------------------------------------------===//
Howard Hinnant6185ace2013-09-21 01:49:28 +00002//
Chandler Carruthd2012102019-01-19 10:56:40 +00003// 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 Hinnant6185ace2013-09-21 01:49:28 +00006//
7//===----------------------------------------------------------------------===//
8
Arthur O'Dwyercf9bf392022-02-11 13:00:39 -05009#include <__config>
10
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +000011#ifndef _LIBCPP_HAS_NO_THREADS
12
Arthur O'Dwyercf9bf392022-02-11 13:00:39 -050013#include <shared_mutex>
Michał Górny8d676fb2019-12-02 11:49:20 +010014#if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)
Arthur O'Dwyercf9bf392022-02-11 13:00:39 -050015# pragma comment(lib, "pthread")
Petr Hosek99575aa2019-05-30 01:34:41 +000016#endif
Howard Hinnant6185ace2013-09-21 01:49:28 +000017
18_LIBCPP_BEGIN_NAMESPACE_STD
19
Marshall Clowac28c3d2015-06-30 14:04:14 +000020// Shared Mutex Base
21__shared_mutex_base::__shared_mutex_base()
Howard Hinnant6185ace2013-09-21 01:49:28 +000022 : __state_(0)
23{
24}
25
26// Exclusive ownership
27
28void
Marshall Clowac28c3d2015-06-30 14:04:14 +000029__shared_mutex_base::lock()
Howard Hinnant6185ace2013-09-21 01:49:28 +000030{
31 unique_lock<mutex> lk(__mut_);
32 while (__state_ & __write_entered_)
33 __gate1_.wait(lk);
34 __state_ |= __write_entered_;
35 while (__state_ & __n_readers_)
36 __gate2_.wait(lk);
37}
38
39bool
Marshall Clowac28c3d2015-06-30 14:04:14 +000040__shared_mutex_base::try_lock()
Howard Hinnant6185ace2013-09-21 01:49:28 +000041{
42 unique_lock<mutex> lk(__mut_);
43 if (__state_ == 0)
44 {
45 __state_ = __write_entered_;
46 return true;
47 }
48 return false;
49}
50
51void
Marshall Clowac28c3d2015-06-30 14:04:14 +000052__shared_mutex_base::unlock()
Howard Hinnant6185ace2013-09-21 01:49:28 +000053{
54 lock_guard<mutex> _(__mut_);
55 __state_ = 0;
56 __gate1_.notify_all();
57}
58
59// Shared ownership
60
61void
Marshall Clowac28c3d2015-06-30 14:04:14 +000062__shared_mutex_base::lock_shared()
Howard Hinnant6185ace2013-09-21 01:49:28 +000063{
64 unique_lock<mutex> lk(__mut_);
65 while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)
66 __gate1_.wait(lk);
67 unsigned num_readers = (__state_ & __n_readers_) + 1;
68 __state_ &= ~__n_readers_;
69 __state_ |= num_readers;
70}
71
72bool
Marshall Clowac28c3d2015-06-30 14:04:14 +000073__shared_mutex_base::try_lock_shared()
Howard Hinnant6185ace2013-09-21 01:49:28 +000074{
75 unique_lock<mutex> lk(__mut_);
76 unsigned num_readers = __state_ & __n_readers_;
77 if (!(__state_ & __write_entered_) && num_readers != __n_readers_)
78 {
79 ++num_readers;
80 __state_ &= ~__n_readers_;
81 __state_ |= num_readers;
82 return true;
83 }
84 return false;
85}
86
87void
Marshall Clowac28c3d2015-06-30 14:04:14 +000088__shared_mutex_base::unlock_shared()
Howard Hinnant6185ace2013-09-21 01:49:28 +000089{
90 lock_guard<mutex> _(__mut_);
91 unsigned num_readers = (__state_ & __n_readers_) - 1;
92 __state_ &= ~__n_readers_;
93 __state_ |= num_readers;
94 if (__state_ & __write_entered_)
95 {
96 if (num_readers == 0)
97 __gate2_.notify_one();
98 }
99 else
100 {
101 if (num_readers == __n_readers_ - 1)
102 __gate1_.notify_one();
103 }
104}
105
106
Marshall Clowac28c3d2015-06-30 14:04:14 +0000107// Shared Timed Mutex
108// These routines are here for ABI stability
Nikolas Klauser79567e32022-09-02 16:19:07 +0200109shared_timed_mutex::shared_timed_mutex() : __base_() {}
110void shared_timed_mutex::lock() { return __base_.lock(); }
111bool shared_timed_mutex::try_lock() { return __base_.try_lock(); }
112void shared_timed_mutex::unlock() { return __base_.unlock(); }
113void shared_timed_mutex::lock_shared() { return __base_.lock_shared(); }
114bool shared_timed_mutex::try_lock_shared() { return __base_.try_lock_shared(); }
115void shared_timed_mutex::unlock_shared() { return __base_.unlock_shared(); }
Marshall Clowac28c3d2015-06-30 14:04:14 +0000116
Howard Hinnant6185ace2013-09-21 01:49:28 +0000117_LIBCPP_END_NAMESPACE_STD
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000118
119#endif // !_LIBCPP_HAS_NO_THREADS