@@ -24,48 +24,60 @@ void srw_lock_low::init()
24
24
{
25
25
DBUG_ASSERT (!is_locked_or_waiting ());
26
26
pthread_mutex_init (&mutex, nullptr );
27
- pthread_cond_init (&cond, nullptr );
27
+ pthread_cond_init (&cond_shared, nullptr );
28
+ pthread_cond_init (&cond_exclusive, nullptr );
28
29
}
29
30
30
31
void srw_lock_low::destroy ()
31
32
{
32
33
DBUG_ASSERT (!is_locked_or_waiting ());
33
34
pthread_mutex_destroy (&mutex);
34
- pthread_cond_destroy (&cond);
35
+ pthread_cond_destroy (&cond_shared);
36
+ pthread_cond_destroy (&cond_exclusive);
35
37
}
36
38
37
- inline void srw_lock_low::wait (uint32_t l)
39
+ inline void srw_lock_low::writer_wait (uint32_t l)
38
40
{
39
41
pthread_mutex_lock (&mutex);
40
42
if (value () == l)
41
- pthread_cond_wait (&cond , &mutex);
43
+ pthread_cond_wait (&cond_exclusive , &mutex);
42
44
pthread_mutex_unlock (&mutex);
43
45
}
44
46
45
- inline void srw_lock_low::wake_one ( )
47
+ inline void srw_lock_low::readers_wait ( uint32_t l )
46
48
{
47
49
pthread_mutex_lock (&mutex);
48
- pthread_cond_signal (&cond);
50
+ if (value () == l)
51
+ pthread_cond_wait (&cond_shared, &mutex);
49
52
pthread_mutex_unlock (&mutex);
50
53
}
51
54
52
- inline void srw_lock_low::wake_all ()
55
+ inline void srw_lock_low::writer_wake ()
53
56
{
54
57
pthread_mutex_lock (&mutex);
55
- pthread_cond_broadcast (&cond);
58
+ uint32_t l= value ();
59
+ if (l & WRITER)
60
+ DBUG_ASSERT (!(l & ~WRITER_PENDING));
61
+ else
62
+ {
63
+ pthread_cond_broadcast (&cond_exclusive);
64
+ if (!(l & WRITER_PENDING))
65
+ pthread_cond_broadcast (&cond_shared);
66
+ }
56
67
pthread_mutex_unlock (&mutex);
57
68
}
69
+ # define readers_wake writer_wake
58
70
#else
59
71
static_assert (4 == sizeof (rw_lock), "ABI");
60
72
# ifdef _WIN32
61
73
# include < synchapi.h>
62
74
63
- inline void srw_lock_low::wait (uint32_t l)
75
+ inline void srw_lock_low::writer_wait (uint32_t l)
64
76
{
65
77
WaitOnAddress (word (), &l, 4 , INFINITE);
66
78
}
67
- inline void srw_lock_low::wake_one () { WakeByAddressSingle (word ()); }
68
- inline void srw_lock_low::wake_all () { WakeByAddressAll (word ()); }
79
+ inline void srw_lock_low::writer_wake () { WakeByAddressSingle (word ()); }
80
+ inline void srw_lock_low::readers_wake () { WakeByAddressAll (word ()); }
69
81
# else
70
82
# ifdef __linux__
71
83
# include < linux/futex.h>
@@ -81,10 +93,14 @@ inline void srw_lock_low::wake_all() { WakeByAddressAll(word()); }
81
93
# error "no futex support"
82
94
# endif
83
95
84
- inline void srw_lock_low::wait (uint32_t l) { SRW_FUTEX (word (), WAIT, l); }
85
- inline void srw_lock_low::wake_one () { SRW_FUTEX (word (), WAKE, 1 ); }
86
- inline void srw_lock_low::wake_all () { SRW_FUTEX (word (), WAKE, INT_MAX); }
96
+ inline void srw_lock_low::writer_wait (uint32_t l)
97
+ {
98
+ SRW_FUTEX (word (), WAIT, l);
99
+ }
100
+ inline void srw_lock_low::writer_wake () { SRW_FUTEX (word (), WAKE, 1 ); }
101
+ inline void srw_lock_low::readers_wake () { SRW_FUTEX (word (), WAKE, INT_MAX); }
87
102
# endif
103
+ # define readers_wait writer_wait
88
104
#endif
89
105
90
106
/* * Wait for a read lock.
@@ -99,15 +115,15 @@ void srw_lock_low::read_lock(uint32_t l)
99
115
#ifdef SRW_LOCK_DUMMY
100
116
pthread_mutex_lock (&mutex);
101
117
{
102
- pthread_cond_signal (&cond );
103
- pthread_cond_wait (&cond , &mutex);
118
+ pthread_cond_signal (&cond_exclusive );
119
+ pthread_cond_wait (&cond_shared , &mutex);
104
120
l= value ();
105
121
}
106
122
while (l == WRITER_WAITING);
107
123
pthread_mutex_unlock (&mutex);
108
124
continue ;
109
125
#else
110
- wake_one ();
126
+ writer_wake ();
111
127
#endif
112
128
}
113
129
else
@@ -120,7 +136,7 @@ void srw_lock_low::read_lock(uint32_t l)
120
136
goto wake_writer;
121
137
}
122
138
123
- wait (l);
139
+ readers_wait (l);
124
140
}
125
141
while (!read_trylock (l));
126
142
}
@@ -153,10 +169,10 @@ void srw_lock_low::write_lock()
153
169
else
154
170
DBUG_ASSERT (~WRITER_WAITING & l);
155
171
156
- wait (l);
172
+ writer_wait (l);
157
173
}
158
174
}
159
175
160
- void srw_lock_low::rd_unlock () { if (read_unlock ()) wake_one (); }
176
+ void srw_lock_low::rd_unlock () { if (read_unlock ()) writer_wake (); }
161
177
162
- void srw_lock_low::wr_unlock () { write_unlock (); wake_all (); }
178
+ void srw_lock_low::wr_unlock () { write_unlock (); readers_wake (); }
0 commit comments