blob: 2b78c1feb9f539972b19603f39f928ed5d6c01cf [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
David Majnemerf9f95be2014-03-17 20:19:44 +000018shared_timed_mutex::shared_timed_mutex()
Howard Hinnantba898e42013-09-21 01:49:28 +000019 : __state_(0)
20{
21}
22
23// Exclusive ownership
24
25void
David Majnemerf9f95be2014-03-17 20:19:44 +000026shared_timed_mutex::lock()
Howard Hinnantba898e42013-09-21 01:49:28 +000027{
28 unique_lock<mutex> lk(__mut_);
29 while (__state_ & __write_entered_)
30 __gate1_.wait(lk);
31 __state_ |= __write_entered_;
32 while (__state_ & __n_readers_)
33 __gate2_.wait(lk);
34}
35
36bool
David Majnemerf9f95be2014-03-17 20:19:44 +000037shared_timed_mutex::try_lock()
Howard Hinnantba898e42013-09-21 01:49:28 +000038{
39 unique_lock<mutex> lk(__mut_);
40 if (__state_ == 0)
41 {
42 __state_ = __write_entered_;
43 return true;
44 }
45 return false;
46}
47
48void
David Majnemerf9f95be2014-03-17 20:19:44 +000049shared_timed_mutex::unlock()
Howard Hinnantba898e42013-09-21 01:49:28 +000050{
51 lock_guard<mutex> _(__mut_);
52 __state_ = 0;
53 __gate1_.notify_all();
54}
55
56// Shared ownership
57
58void
David Majnemerf9f95be2014-03-17 20:19:44 +000059shared_timed_mutex::lock_shared()
Howard Hinnantba898e42013-09-21 01:49:28 +000060{
61 unique_lock<mutex> lk(__mut_);
62 while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)
63 __gate1_.wait(lk);
64 unsigned num_readers = (__state_ & __n_readers_) + 1;
65 __state_ &= ~__n_readers_;
66 __state_ |= num_readers;
67}
68
69bool
David Majnemerf9f95be2014-03-17 20:19:44 +000070shared_timed_mutex::try_lock_shared()
Howard Hinnantba898e42013-09-21 01:49:28 +000071{
72 unique_lock<mutex> lk(__mut_);
73 unsigned num_readers = __state_ & __n_readers_;
74 if (!(__state_ & __write_entered_) && num_readers != __n_readers_)
75 {
76 ++num_readers;
77 __state_ &= ~__n_readers_;
78 __state_ |= num_readers;
79 return true;
80 }
81 return false;
82}
83
84void
David Majnemerf9f95be2014-03-17 20:19:44 +000085shared_timed_mutex::unlock_shared()
Howard Hinnantba898e42013-09-21 01:49:28 +000086{
87 lock_guard<mutex> _(__mut_);
88 unsigned num_readers = (__state_ & __n_readers_) - 1;
89 __state_ &= ~__n_readers_;
90 __state_ |= num_readers;
91 if (__state_ & __write_entered_)
92 {
93 if (num_readers == 0)
94 __gate2_.notify_one();
95 }
96 else
97 {
98 if (num_readers == __n_readers_ - 1)
99 __gate1_.notify_one();
100 }
101}
102
103
104_LIBCPP_END_NAMESPACE_STD
Jonathan Roelofs8d86b2e2014-09-05 19:45:05 +0000105
106#endif // !_LIBCPP_HAS_NO_THREADS