blob: 874aceb1b03a96f50f4b65002a68e2f14a04df1c [file] [log] [blame]
Howard Hinnantba898e42013-09-21 01:49:28 +00001//===---------------------- shared_mutex.cpp ------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Jonathan Roelofs8d86b2e2014-09-05 19:45:05 +000010#include "__config"
11#ifndef _LIBCPP_HAS_NO_THREADS
12
Howard Hinnantba898e42013-09-21 01:49:28 +000013#define _LIBCPP_BUILDING_SHARED_MUTEX
14#include "shared_mutex"
15
16_LIBCPP_BEGIN_NAMESPACE_STD
17
Marshall Clowabadb452015-06-30 14:04:14 +000018// Shared Mutex Base
19__shared_mutex_base::__shared_mutex_base()
Howard Hinnantba898e42013-09-21 01:49:28 +000020 : __state_(0)
21{
22}
23
24// Exclusive ownership
25
26void
Marshall Clowabadb452015-06-30 14:04:14 +000027__shared_mutex_base::lock()
Howard Hinnantba898e42013-09-21 01:49:28 +000028{
29 unique_lock<mutex> lk(__mut_);
30 while (__state_ & __write_entered_)
31 __gate1_.wait(lk);
32 __state_ |= __write_entered_;
33 while (__state_ & __n_readers_)
34 __gate2_.wait(lk);
35}
36
37bool
Marshall Clowabadb452015-06-30 14:04:14 +000038__shared_mutex_base::try_lock()
Howard Hinnantba898e42013-09-21 01:49:28 +000039{
40 unique_lock<mutex> lk(__mut_);
41 if (__state_ == 0)
42 {
43 __state_ = __write_entered_;
44 return true;
45 }
46 return false;
47}
48
49void
Marshall Clowabadb452015-06-30 14:04:14 +000050__shared_mutex_base::unlock()
Howard Hinnantba898e42013-09-21 01:49:28 +000051{
52 lock_guard<mutex> _(__mut_);
53 __state_ = 0;
54 __gate1_.notify_all();
55}
56
57// Shared ownership
58
59void
Marshall Clowabadb452015-06-30 14:04:14 +000060__shared_mutex_base::lock_shared()
Howard Hinnantba898e42013-09-21 01:49:28 +000061{
62 unique_lock<mutex> lk(__mut_);
63 while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)
64 __gate1_.wait(lk);
65 unsigned num_readers = (__state_ & __n_readers_) + 1;
66 __state_ &= ~__n_readers_;
67 __state_ |= num_readers;
68}
69
70bool
Marshall Clowabadb452015-06-30 14:04:14 +000071__shared_mutex_base::try_lock_shared()
Howard Hinnantba898e42013-09-21 01:49:28 +000072{
73 unique_lock<mutex> lk(__mut_);
74 unsigned num_readers = __state_ & __n_readers_;
75 if (!(__state_ & __write_entered_) && num_readers != __n_readers_)
76 {
77 ++num_readers;
78 __state_ &= ~__n_readers_;
79 __state_ |= num_readers;
80 return true;
81 }
82 return false;
83}
84
85void
Marshall Clowabadb452015-06-30 14:04:14 +000086__shared_mutex_base::unlock_shared()
Howard Hinnantba898e42013-09-21 01:49:28 +000087{
88 lock_guard<mutex> _(__mut_);
89 unsigned num_readers = (__state_ & __n_readers_) - 1;
90 __state_ &= ~__n_readers_;
91 __state_ |= num_readers;
92 if (__state_ & __write_entered_)
93 {
94 if (num_readers == 0)
95 __gate2_.notify_one();
96 }
97 else
98 {
99 if (num_readers == __n_readers_ - 1)
100 __gate1_.notify_one();
101 }
102}
103
104
Marshall Clowabadb452015-06-30 14:04:14 +0000105// Shared Timed Mutex
106// These routines are here for ABI stability
107shared_timed_mutex::shared_timed_mutex() : __base() {}
108void shared_timed_mutex::lock() { return __base.lock(); }
109bool shared_timed_mutex::try_lock() { return __base.try_lock(); }
110void shared_timed_mutex::unlock() { return __base.unlock(); }
111void shared_timed_mutex::lock_shared() { return __base.lock_shared(); }
112bool shared_timed_mutex::try_lock_shared() { return __base.try_lock_shared(); }
113void shared_timed_mutex::unlock_shared() { return __base.unlock_shared(); }
114
Howard Hinnantba898e42013-09-21 01:49:28 +0000115_LIBCPP_END_NAMESPACE_STD
Jonathan Roelofs8d86b2e2014-09-05 19:45:05 +0000116
117#endif // !_LIBCPP_HAS_NO_THREADS