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 5444081 : result = pthread_mutex_init(mutex, nullptr);
29 : #endif // defined(DEBUG)
30 : DCHECK_EQ(0, result);
31 5444079 : USE(result);
32 : }
33 :
34 :
35 : static V8_INLINE void InitializeRecursiveNativeHandle(pthread_mutex_t* mutex) {
36 : pthread_mutexattr_t attr;
37 817716 : int result = pthread_mutexattr_init(&attr);
38 : DCHECK_EQ(0, result);
39 817716 : result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
40 : DCHECK_EQ(0, result);
41 817716 : result = pthread_mutex_init(mutex, &attr);
42 : DCHECK_EQ(0, result);
43 817716 : result = pthread_mutexattr_destroy(&attr);
44 : DCHECK_EQ(0, result);
45 817716 : USE(result);
46 : }
47 :
48 :
49 : static V8_INLINE void DestroyNativeHandle(pthread_mutex_t* mutex) {
50 5858388 : int result = pthread_mutex_destroy(mutex);
51 : DCHECK_EQ(0, result);
52 5858394 : USE(result);
53 : }
54 :
55 :
56 : static V8_INLINE void LockNativeHandle(pthread_mutex_t* mutex) {
57 179937445 : int result = pthread_mutex_lock(mutex);
58 : DCHECK_EQ(0, result);
59 180002152 : USE(result);
60 : }
61 :
62 :
63 : static V8_INLINE void UnlockNativeHandle(pthread_mutex_t* mutex) {
64 179964652 : int result = pthread_mutex_unlock(mutex);
65 : DCHECK_EQ(0, result);
66 179994588 : 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 5444081 : Mutex::Mutex() {
81 5444081 : InitializeNativeHandle(&native_handle_);
82 : #ifdef DEBUG
83 : level_ = 0;
84 : #endif
85 5444080 : }
86 :
87 :
88 5063674 : Mutex::~Mutex() {
89 5063674 : DestroyNativeHandle(&native_handle_);
90 : DCHECK_EQ(0, level_);
91 5063675 : }
92 :
93 :
94 170492716 : void Mutex::Lock() {
95 170492716 : LockNativeHandle(&native_handle_);
96 : AssertUnheldAndMark();
97 170547166 : }
98 :
99 :
100 170519510 : void Mutex::Unlock() {
101 : AssertHeldAndUnmark();
102 170519510 : UnlockNativeHandle(&native_handle_);
103 170544114 : }
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 817716 : RecursiveMutex::RecursiveMutex() {
116 817716 : InitializeRecursiveNativeHandle(&native_handle_);
117 : #ifdef DEBUG
118 : level_ = 0;
119 : #endif
120 817716 : }
121 :
122 :
123 794714 : RecursiveMutex::~RecursiveMutex() {
124 794714 : DestroyNativeHandle(&native_handle_);
125 : DCHECK_EQ(0, level_);
126 794718 : }
127 :
128 :
129 9444729 : void RecursiveMutex::Lock() {
130 9444729 : LockNativeHandle(&native_handle_);
131 : #ifdef DEBUG
132 : DCHECK_LE(0, level_);
133 : level_++;
134 : #endif
135 9445220 : }
136 :
137 :
138 9445142 : void RecursiveMutex::Unlock() {
139 : #ifdef DEBUG
140 : DCHECK_LT(0, level_);
141 : level_--;
142 : #endif
143 9445142 : UnlockNativeHandle(&native_handle_);
144 9445313 : }
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
|