-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathco_rwmutex.cpp
136 lines (118 loc) · 2.53 KB
/
co_rwmutex.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include "co_rwmutex.h"
#include "co_mutex.h"
#include "scheduler.h"
namespace co
{
class CoRWMutex::CoRWMutexImpl
{
CoMutex mtx_;
atomic_t<int> readers_c_{0};
public:
ReadView r_view;
WriteView w_view;
CoRWMutexImpl()
: r_view(*this), w_view(*this)
{}
void r_lock()
{
for (;;)
{
++readers_c_;
if (!mtx_.is_lock()) break ;
--readers_c_;
g_Scheduler.SleepSwitch(0);
}
}
bool r_try_lock()
{
++readers_c_;
if (mtx_.is_lock()) {
--readers_c_;
return false;
}
return true;
}
bool r_is_lock()
{
return mtx_.is_lock();
}
void r_unlock()
{
int rc = --readers_c_;
(void)rc;
assert(rc >= 0);
}
void w_lock()
{
mtx_.lock();
while (readers_c_)
g_Scheduler.SleepSwitch(0);
}
bool w_try_lock()
{
if (!mtx_.try_lock()) return false;
if (readers_c_) {
mtx_.unlock();
return false;
}
return true;
}
bool w_is_lock()
{
return mtx_.is_lock();
}
void w_unlock()
{
mtx_.unlock();
}
};
CoRWMutex::ReadView::ReadView(CoRWMutexImpl & ref)
: ref_(ref)
{}
void CoRWMutex::ReadView::lock()
{
ref_.r_lock();
}
bool CoRWMutex::ReadView::try_lock()
{
return ref_.r_try_lock();
}
bool CoRWMutex::ReadView::is_lock()
{
return ref_.r_is_lock();
}
void CoRWMutex::ReadView::unlock()
{
ref_.r_unlock();
}
CoRWMutex::WriteView::WriteView(CoRWMutexImpl & ref)
: ref_(ref)
{}
void CoRWMutex::WriteView::lock()
{
ref_.w_lock();
}
bool CoRWMutex::WriteView::try_lock()
{
return ref_.w_try_lock();
}
bool CoRWMutex::WriteView::is_lock()
{
return ref_.w_is_lock();
}
void CoRWMutex::WriteView::unlock()
{
ref_.w_unlock();
}
CoRWMutex::CoRWMutex()
: impl_(new CoRWMutexImpl)
{}
CoRWMutex::ReadView& CoRWMutex::reader()
{
return impl_->r_view;
}
CoRWMutex::WriteView& CoRWMutex::writer()
{
return impl_->w_view;
}
} //namespace co