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 17544809 : result = pthread_mutex_init(mutex, nullptr);
29 : #endif // defined(DEBUG)
30 : DCHECK_EQ(0, result);
31 17544802 : USE(result);
32 : }
33 :
34 :
35 : static V8_INLINE void InitializeRecursiveNativeHandle(pthread_mutex_t* mutex) {
36 : pthread_mutexattr_t attr;
37 62886 : int result = pthread_mutexattr_init(&attr);
38 : DCHECK_EQ(0, result);
39 62886 : result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
40 : DCHECK_EQ(0, result);
41 62886 : result = pthread_mutex_init(mutex, &attr);
42 : DCHECK_EQ(0, result);
43 62886 : result = pthread_mutexattr_destroy(&attr);
44 : DCHECK_EQ(0, result);
45 62887 : USE(result);
46 : }
47 :
48 :
49 : static V8_INLINE void DestroyNativeHandle(pthread_mutex_t* mutex) {
50 17072418 : int result = pthread_mutex_destroy(mutex);
51 : DCHECK_EQ(0, result);
52 17072432 : USE(result);
53 : }
54 :
55 :
56 : static V8_INLINE void LockNativeHandle(pthread_mutex_t* mutex) {
57 356432010 : int result = pthread_mutex_lock(mutex);
58 : DCHECK_EQ(0, result);
59 356570838 : USE(result);
60 : }
61 :
62 :
63 : static V8_INLINE void UnlockNativeHandle(pthread_mutex_t* mutex) {
64 356496229 : int result = pthread_mutex_unlock(mutex);
65 : DCHECK_EQ(0, result);
66 356573360 : 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 17544809 : Mutex::Mutex() {
81 17544809 : InitializeNativeHandle(&native_handle_);
82 : #ifdef DEBUG
83 : level_ = 0;
84 : #endif
85 17544795 : }
86 :
87 :
88 17009547 : Mutex::~Mutex() {
89 17009547 : DestroyNativeHandle(&native_handle_);
90 : DCHECK_EQ(0, level_);
91 17009553 : }
92 :
93 :
94 344639914 : void Mutex::Lock() {
95 344639914 : LockNativeHandle(&native_handle_);
96 : AssertUnheldAndMark();
97 344749961 : }
98 :
99 :
100 344704070 : void Mutex::Unlock() {
101 : AssertHeldAndUnmark();
102 344704070 : UnlockNativeHandle(&native_handle_);
103 344747230 : }
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 62886 : RecursiveMutex::RecursiveMutex() {
116 62886 : InitializeRecursiveNativeHandle(&native_handle_);
117 : #ifdef DEBUG
118 : level_ = 0;
119 : #endif
120 62887 : }
121 :
122 :
123 62871 : RecursiveMutex::~RecursiveMutex() {
124 62871 : DestroyNativeHandle(&native_handle_);
125 : DCHECK_EQ(0, level_);
126 62871 : }
127 :
128 :
129 11792096 : void RecursiveMutex::Lock() {
130 11792096 : LockNativeHandle(&native_handle_);
131 : #ifdef DEBUG
132 : DCHECK_LE(0, level_);
133 : level_++;
134 : #endif
135 11792185 : }
136 :
137 :
138 11792159 : void RecursiveMutex::Unlock() {
139 : #ifdef DEBUG
140 : DCHECK_LT(0, level_);
141 : level_--;
142 : #endif
143 11792159 : UnlockNativeHandle(&native_handle_);
144 11792177 : }
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 : #elif V8_OS_WIN
159 :
160 : Mutex::Mutex() : native_handle_(SRWLOCK_INIT) {
161 : #ifdef DEBUG
162 : level_ = 0;
163 : #endif
164 : }
165 :
166 :
167 : Mutex::~Mutex() {
168 : DCHECK_EQ(0, level_);
169 : }
170 :
171 :
172 : void Mutex::Lock() {
173 : AcquireSRWLockExclusive(&native_handle_);
174 : AssertUnheldAndMark();
175 : }
176 :
177 :
178 : void Mutex::Unlock() {
179 : AssertHeldAndUnmark();
180 : ReleaseSRWLockExclusive(&native_handle_);
181 : }
182 :
183 :
184 : bool Mutex::TryLock() {
185 : if (!TryAcquireSRWLockExclusive(&native_handle_)) {
186 : return false;
187 : }
188 : AssertUnheldAndMark();
189 : return true;
190 : }
191 :
192 :
193 : RecursiveMutex::RecursiveMutex() {
194 : InitializeCriticalSection(&native_handle_);
195 : #ifdef DEBUG
196 : level_ = 0;
197 : #endif
198 : }
199 :
200 :
201 : RecursiveMutex::~RecursiveMutex() {
202 : DeleteCriticalSection(&native_handle_);
203 : DCHECK_EQ(0, level_);
204 : }
205 :
206 :
207 : void RecursiveMutex::Lock() {
208 : EnterCriticalSection(&native_handle_);
209 : #ifdef DEBUG
210 : DCHECK_LE(0, level_);
211 : level_++;
212 : #endif
213 : }
214 :
215 :
216 : void RecursiveMutex::Unlock() {
217 : #ifdef DEBUG
218 : DCHECK_LT(0, level_);
219 : level_--;
220 : #endif
221 : LeaveCriticalSection(&native_handle_);
222 : }
223 :
224 :
225 : bool RecursiveMutex::TryLock() {
226 : if (!TryEnterCriticalSection(&native_handle_)) {
227 : return false;
228 : }
229 : #ifdef DEBUG
230 : DCHECK_LE(0, level_);
231 : level_++;
232 : #endif
233 : return true;
234 : }
235 :
236 : #endif // V8_OS_POSIX
237 :
238 : } // namespace base
239 : } // namespace v8
|