blob: 874aceb1b03a96f50f4b65002a68e2f14a04df1c [file] [log] [blame]
Howard Hinnantead6f162013-09-21 01:49:281//===---------------------- 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 Roelofsb3fcc672014-09-05 19:45:0510#include "__config"
11#ifndef _LIBCPP_HAS_NO_THREADS
12
Howard Hinnantead6f162013-09-21 01:49:2813#define _LIBCPP_BUILDING_SHARED_MUTEX
14#include "shared_mutex"
15
16_LIBCPP_BEGIN_NAMESPACE_STD
17
Marshall Clowf69ae472015-06-30 14:04:1418// Shared Mutex Base
19__shared_mutex_base::__shared_mutex_base()
Howard Hinnantead6f162013-09-21 01:49:2820 : __state_(0)
21{
22}
23
24// Exclusive ownership
25
26void
Marshall Clowf69ae472015-06-30 14:04:1427__shared_mutex_base::lock()
Howard Hinnantead6f162013-09-21 01:49:2828{
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 Clowf69ae472015-06-30 14:04:1438__shared_mutex_base::try_lock()
Howard Hinnantead6f162013-09-21 01:49:2839{
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 Clowf69ae472015-06-30 14:04:1450__shared_mutex_base::unlock()
Howard Hinnantead6f162013-09-21 01:49:2851{
52 lock_guard<mutex> _(__mut_);
53 __state_ = 0;
54 __gate1_.notify_all();
55}
56
57// Shared ownership
58
59void
Marshall Clowf69ae472015-06-30 14:04:1460__shared_mutex_base::lock_shared()
Howard Hinnantead6f162013-09-21 01:49:2861{
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 Clowf69ae472015-06-30 14:04:1471__shared_mutex_base::try_lock_shared()
Howard Hinnantead6f162013-09-21 01:49:2872{
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 Clowf69ae472015-06-30 14:04:1486__shared_mutex_base::unlock_shared()
Howard Hinnantead6f162013-09-21 01:49:2887{
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 Clowf69ae472015-06-30 14:04:14105// 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 Hinnantead6f162013-09-21 01:49:28115_LIBCPP_END_NAMESPACE_STD
Jonathan Roelofsb3fcc672014-09-05 19:45:05116
117#endif // !_LIBCPP_HAS_NO_THREADS