shared_mutex.cpp revision 278724
1//===---------------------- 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
10#include "__config"
11#ifndef _LIBCPP_HAS_NO_THREADS
12
13#define _LIBCPP_BUILDING_SHARED_MUTEX
14#include "shared_mutex"
15
16_LIBCPP_BEGIN_NAMESPACE_STD
17
18shared_timed_mutex::shared_timed_mutex()
19    : __state_(0)
20{
21}
22
23// Exclusive ownership
24
25void
26shared_timed_mutex::lock()
27{
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
37shared_timed_mutex::try_lock()
38{
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
49shared_timed_mutex::unlock()
50{
51    lock_guard<mutex> _(__mut_);
52    __state_ = 0;
53    __gate1_.notify_all();
54}
55
56// Shared ownership
57
58void
59shared_timed_mutex::lock_shared()
60{
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
70shared_timed_mutex::try_lock_shared()
71{
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
85shared_timed_mutex::unlock_shared()
86{
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
105
106#endif // !_LIBCPP_HAS_NO_THREADS
107