Line data Source code
1 : // Copyright 2013 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include "src/base/platform/mutex.h"
6 :
7 : #include <errno.h>
8 :
9 : namespace v8 {
10 : namespace base {
11 :
12 : #if V8_OS_POSIX
13 :
14 : static V8_INLINE void InitializeNativeHandle(pthread_mutex_t* mutex) {
15 : int result;
16 : #if defined(DEBUG)
17 : // Use an error checking mutex in debug mode.
18 : pthread_mutexattr_t attr;
19 : result = pthread_mutexattr_init(&attr);
20 : DCHECK_EQ(0, result);
21 : result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
22 : DCHECK_EQ(0, result);
23 : result = pthread_mutex_init(mutex, &attr);
24 : DCHECK_EQ(0, result);
25 : result = pthread_mutexattr_destroy(&attr);
26 : #else
27 : // Use a fast mutex (default attributes).
28 20680435 : result = pthread_mutex_init(mutex, nullptr);
29 : #endif // defined(DEBUG)
30 : DCHECK_EQ(0, result);
31 20680435 : USE(result);
32 : }
33 :
34 :
35 : static V8_INLINE void InitializeRecursiveNativeHandle(pthread_mutex_t* mutex) {
36 : pthread_mutexattr_t attr;
37 62425 : int result = pthread_mutexattr_init(&attr);
38 : DCHECK_EQ(0, result);
39 62423 : result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
40 : DCHECK_EQ(0, result);
41 62424 : result = pthread_mutex_init(mutex, &attr);
42 : DCHECK_EQ(0, result);
43 62424 : result = pthread_mutexattr_destroy(&attr);
44 : DCHECK_EQ(0, result);
45 62425 : USE(result);
46 : }
47 :
48 :
49 : static V8_INLINE void DestroyNativeHandle(pthread_mutex_t* mutex) {
50 20360138 : int result = pthread_mutex_destroy(mutex);
51 : DCHECK_EQ(0, result);
52 20360149 : USE(result);
53 : }
54 :
55 :
56 : static V8_INLINE void LockNativeHandle(pthread_mutex_t* mutex) {
57 227671261 : int result = pthread_mutex_lock(mutex);
58 : DCHECK_EQ(0, result);
59 227772474 : USE(result);
60 : }
61 :
62 :
63 : static V8_INLINE void UnlockNativeHandle(pthread_mutex_t* mutex) {
64 227666590 : int result = pthread_mutex_unlock(mutex);
65 : DCHECK_EQ(0, result);
66 227751519 : USE(result);
67 : }
68 :
69 :
70 : static V8_INLINE bool TryLockNativeHandle(pthread_mutex_t* mutex) {
71 4 : int result = pthread_mutex_trylock(mutex);
72 4 : if (result == EBUSY) {
73 : return false;
74 : }
75 : DCHECK_EQ(0, result);
76 : return true;
77 : }
78 :
79 :
80 20680435 : Mutex::Mutex() {
81 20680435 : InitializeNativeHandle(&native_handle_);
82 : #ifdef DEBUG
83 : level_ = 0;
84 : #endif
85 20680420 : }
86 :
87 :
88 40595429 : Mutex::~Mutex() {
89 20297728 : DestroyNativeHandle(&native_handle_);
90 : DCHECK_EQ(0, level_);
91 20297701 : }
92 :
93 :
94 205789114 : void Mutex::Lock() {
95 205789114 : LockNativeHandle(&native_handle_);
96 : AssertUnheldAndMark();
97 205865361 : }
98 :
99 :
100 205784398 : void Mutex::Unlock() {
101 : AssertHeldAndUnmark();
102 205784398 : UnlockNativeHandle(&native_handle_);
103 205842130 : }
104 :
105 :
106 0 : bool Mutex::TryLock() {
107 0 : if (!TryLockNativeHandle(&native_handle_)) {
108 : return false;
109 : }
110 : AssertUnheldAndMark();
111 0 : return true;
112 : }
113 :
114 :
115 62425 : RecursiveMutex::RecursiveMutex() {
116 62425 : InitializeRecursiveNativeHandle(&native_handle_);
117 : #ifdef DEBUG
118 : level_ = 0;
119 : #endif
120 62424 : }
121 :
122 :
123 124820 : RecursiveMutex::~RecursiveMutex() {
124 62410 : DestroyNativeHandle(&native_handle_);
125 : DCHECK_EQ(0, level_);
126 62410 : }
127 :
128 :
129 21882147 : void RecursiveMutex::Lock() {
130 21882147 : LockNativeHandle(&native_handle_);
131 : #ifdef DEBUG
132 : DCHECK_LE(0, level_);
133 : level_++;
134 : #endif
135 21882323 : }
136 :
137 :
138 21882192 : void RecursiveMutex::Unlock() {
139 : #ifdef DEBUG
140 : DCHECK_LT(0, level_);
141 : level_--;
142 : #endif
143 21882192 : UnlockNativeHandle(&native_handle_);
144 21882328 : }
145 :
146 :
147 4 : bool RecursiveMutex::TryLock() {
148 8 : if (!TryLockNativeHandle(&native_handle_)) {
149 : return false;
150 : }
151 : #ifdef DEBUG
152 : DCHECK_LE(0, level_);
153 : level_++;
154 : #endif
155 4 : return true;
156 : }
157 :
158 1242379 : SharedMutex::SharedMutex() { pthread_rwlock_init(&native_handle_, nullptr); }
159 :
160 2484756 : SharedMutex::~SharedMutex() {
161 1242378 : int result = pthread_rwlock_destroy(&native_handle_);
162 : DCHECK_EQ(0, result);
163 : USE(result);
164 1242378 : }
165 :
166 796568 : void SharedMutex::LockShared() {
167 796568 : int result = pthread_rwlock_rdlock(&native_handle_);
168 : DCHECK_EQ(0, result);
169 : USE(result);
170 800812 : }
171 :
172 1250461 : void SharedMutex::LockExclusive() {
173 1250461 : int result = pthread_rwlock_wrlock(&native_handle_);
174 : DCHECK_EQ(0, result);
175 : USE(result);
176 1250464 : }
177 :
178 800369 : void SharedMutex::UnlockShared() {
179 2050833 : int result = pthread_rwlock_unlock(&native_handle_);
180 : DCHECK_EQ(0, result);
181 : USE(result);
182 800843 : }
183 :
184 1250464 : void SharedMutex::UnlockExclusive() {
185 : // Same code as {UnlockShared} on POSIX.
186 : UnlockShared();
187 1250460 : }
188 :
189 0 : bool SharedMutex::TryLockShared() {
190 0 : return pthread_rwlock_tryrdlock(&native_handle_) == 0;
191 : }
192 :
193 0 : bool SharedMutex::TryLockExclusive() {
194 0 : return pthread_rwlock_trywrlock(&native_handle_) == 0;
195 : }
196 :
197 : #elif V8_OS_WIN
198 :
199 : Mutex::Mutex() : native_handle_(SRWLOCK_INIT) {
200 : #ifdef DEBUG
201 : level_ = 0;
202 : #endif
203 : }
204 :
205 :
206 : Mutex::~Mutex() {
207 : DCHECK_EQ(0, level_);
208 : }
209 :
210 :
211 : void Mutex::Lock() {
212 : AcquireSRWLockExclusive(&native_handle_);
213 : AssertUnheldAndMark();
214 : }
215 :
216 :
217 : void Mutex::Unlock() {
218 : AssertHeldAndUnmark();
219 : ReleaseSRWLockExclusive(&native_handle_);
220 : }
221 :
222 :
223 : bool Mutex::TryLock() {
224 : if (!TryAcquireSRWLockExclusive(&native_handle_)) {
225 : return false;
226 : }
227 : AssertUnheldAndMark();
228 : return true;
229 : }
230 :
231 :
232 : RecursiveMutex::RecursiveMutex() {
233 : InitializeCriticalSection(&native_handle_);
234 : #ifdef DEBUG
235 : level_ = 0;
236 : #endif
237 : }
238 :
239 :
240 : RecursiveMutex::~RecursiveMutex() {
241 : DeleteCriticalSection(&native_handle_);
242 : DCHECK_EQ(0, level_);
243 : }
244 :
245 :
246 : void RecursiveMutex::Lock() {
247 : EnterCriticalSection(&native_handle_);
248 : #ifdef DEBUG
249 : DCHECK_LE(0, level_);
250 : level_++;
251 : #endif
252 : }
253 :
254 :
255 : void RecursiveMutex::Unlock() {
256 : #ifdef DEBUG
257 : DCHECK_LT(0, level_);
258 : level_--;
259 : #endif
260 : LeaveCriticalSection(&native_handle_);
261 : }
262 :
263 :
264 : bool RecursiveMutex::TryLock() {
265 : if (!TryEnterCriticalSection(&native_handle_)) {
266 : return false;
267 : }
268 : #ifdef DEBUG
269 : DCHECK_LE(0, level_);
270 : level_++;
271 : #endif
272 : return true;
273 : }
274 :
275 : SharedMutex::SharedMutex() : native_handle_(SRWLOCK_INIT) {}
276 :
277 : SharedMutex::~SharedMutex() {}
278 :
279 : void SharedMutex::LockShared() { AcquireSRWLockShared(&native_handle_); }
280 :
281 : void SharedMutex::LockExclusive() { AcquireSRWLockExclusive(&native_handle_); }
282 :
283 : void SharedMutex::UnlockShared() { ReleaseSRWLockShared(&native_handle_); }
284 :
285 : void SharedMutex::UnlockExclusive() {
286 : ReleaseSRWLockExclusive(&native_handle_);
287 : }
288 :
289 : bool SharedMutex::TryLockShared() {
290 : return TryAcquireSRWLockShared(&native_handle_);
291 : }
292 :
293 : bool SharedMutex::TryLockExclusive() {
294 : return TryAcquireSRWLockExclusive(&native_handle_);
295 : }
296 :
297 : #endif // V8_OS_POSIX
298 :
299 : } // namespace base
300 : } // namespace v8
|