blob: 6a5a738a6762faebefd321bdb0c602495e0e748c [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
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +00009#include "__config"
10#ifndef _LIBCPP_HAS_NO_THREADS
11
Howard Hinnant6185ace2013-09-21 01:49:28 +000012#include "shared_mutex"
Michał Górny8d676fb2019-12-02 11:49:20 +010013#if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)
Petr Hosek99575aa2019-05-30 01:34:41 +000014#pragma comment(lib, "pthread")
15#endif
Howard Hinnant6185ace2013-09-21 01:49:28 +000016
17_LIBCPP_BEGIN_NAMESPACE_STD
18
Marshall Clowac28c3d2015-06-30 14:04:14 +000019// Shared Mutex Base
20__shared_mutex_base::__shared_mutex_base()
Howard Hinnant6185ace2013-09-21 01:49:28 +000021 : __state_(0)
22{
23}
24
25// Exclusive ownership
26
27void
Marshall Clowac28c3d2015-06-30 14:04:14 +000028__shared_mutex_base::lock()
Howard Hinnant6185ace2013-09-21 01:49:28 +000029{
30 unique_lock<mutex> lk(__mut_);
31 while (__state_ & __write_entered_)
32 __gate1_.wait(lk);
33 __state_ |= __write_entered_;
34 while (__state_ & __n_readers_)
35 __gate2_.wait(lk);
36}
37
38bool
Marshall Clowac28c3d2015-06-30 14:04:14 +000039__shared_mutex_base::try_lock()
Howard Hinnant6185ace2013-09-21 01:49:28 +000040{
41 unique_lock<mutex> lk(__mut_);
42 if (__state_ == 0)
43 {
44 __state_ = __write_entered_;
45 return true;
46 }
47 return false;
48}
49
50void
Marshall Clowac28c3d2015-06-30 14:04:14 +000051__shared_mutex_base::unlock()
Howard Hinnant6185ace2013-09-21 01:49:28 +000052{
53 lock_guard<mutex> _(__mut_);
54 __state_ = 0;
55 __gate1_.notify_all();
56}
57
58// Shared ownership
59
60void
Marshall Clowac28c3d2015-06-30 14:04:14 +000061__shared_mutex_base::lock_shared()
Howard Hinnant6185ace2013-09-21 01:49:28 +000062{
63 unique_lock<mutex> lk(__mut_);
64 while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)
65 __gate1_.wait(lk);
66 unsigned num_readers = (__state_ & __n_readers_) + 1;
67 __state_ &= ~__n_readers_;
68 __state_ |= num_readers;
69}
70
71bool
Marshall Clowac28c3d2015-06-30 14:04:14 +000072__shared_mutex_base::try_lock_shared()
Howard Hinnant6185ace2013-09-21 01:49:28 +000073{
74 unique_lock<mutex> lk(__mut_);
75 unsigned num_readers = __state_ & __n_readers_;
76 if (!(__state_ & __write_entered_) && num_readers != __n_readers_)
77 {
78 ++num_readers;
79 __state_ &= ~__n_readers_;
80 __state_ |= num_readers;
81 return true;
82 }
83 return false;
84}
85
86void
Marshall Clowac28c3d2015-06-30 14:04:14 +000087__shared_mutex_base::unlock_shared()
Howard Hinnant6185ace2013-09-21 01:49:28 +000088{
89 lock_guard<mutex> _(__mut_);
90 unsigned num_readers = (__state_ & __n_readers_) - 1;
91 __state_ &= ~__n_readers_;
92 __state_ |= num_readers;
93 if (__state_ & __write_entered_)
94 {
95 if (num_readers == 0)
96 __gate2_.notify_one();
97 }
98 else
99 {
100 if (num_readers == __n_readers_ - 1)
101 __gate1_.notify_one();
102 }
103}
104
105
Marshall Clowac28c3d2015-06-30 14:04:14 +0000106// Shared Timed Mutex
107// These routines are here for ABI stability
108shared_timed_mutex::shared_timed_mutex() : __base() {}
109void shared_timed_mutex::lock() { return __base.lock(); }
110bool shared_timed_mutex::try_lock() { return __base.try_lock(); }
111void shared_timed_mutex::unlock() { return __base.unlock(); }
112void shared_timed_mutex::lock_shared() { return __base.lock_shared(); }
113bool shared_timed_mutex::try_lock_shared() { return __base.try_lock_shared(); }
114void shared_timed_mutex::unlock_shared() { return __base.unlock_shared(); }
115
Howard Hinnant6185ace2013-09-21 01:49:28 +0000116_LIBCPP_END_NAMESPACE_STD
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000117
118#endif // !_LIBCPP_HAS_NO_THREADS