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 3205347 : result = pthread_mutex_init(mutex, NULL);
29 : #endif // defined(DEBUG)
30 : DCHECK_EQ(0, result);
31 3205346 : USE(result);
32 : }
33 :
34 :
35 : static V8_INLINE void InitializeRecursiveNativeHandle(pthread_mutex_t* mutex) {
36 : pthread_mutexattr_t attr;
37 961141 : int result = pthread_mutexattr_init(&attr);
38 : DCHECK_EQ(0, result);
39 961141 : result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
40 : DCHECK_EQ(0, result);
41 961141 : result = pthread_mutex_init(mutex, &attr);
42 : DCHECK_EQ(0, result);
43 961141 : result = pthread_mutexattr_destroy(&attr);
44 : DCHECK_EQ(0, result);
45 961141 : USE(result);
46 : }
47 :
48 :
49 : static V8_INLINE void DestroyNativeHandle(pthread_mutex_t* mutex) {
50 3814990 : int result = pthread_mutex_destroy(mutex);
51 : DCHECK_EQ(0, result);
52 3814970 : USE(result);
53 : }
54 :
55 :
56 : static V8_INLINE void LockNativeHandle(pthread_mutex_t* mutex) {
57 198327517 : int result = pthread_mutex_lock(mutex);
58 : DCHECK_EQ(0, result);
59 198362999 : USE(result);
60 : }
61 :
62 :
63 : static V8_INLINE void UnlockNativeHandle(pthread_mutex_t* mutex) {
64 198356375 : int result = pthread_mutex_unlock(mutex);
65 : DCHECK_EQ(0, result);
66 198363545 : 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 : #elif V8_OS_WIN
80 :
81 : static V8_INLINE void InitializeNativeHandle(PCRITICAL_SECTION cs) {
82 : InitializeCriticalSection(cs);
83 : }
84 :
85 :
86 : static V8_INLINE void InitializeRecursiveNativeHandle(PCRITICAL_SECTION cs) {
87 : InitializeCriticalSection(cs);
88 : }
89 :
90 :
91 : static V8_INLINE void DestroyNativeHandle(PCRITICAL_SECTION cs) {
92 : DeleteCriticalSection(cs);
93 : }
94 :
95 :
96 : static V8_INLINE void LockNativeHandle(PCRITICAL_SECTION cs) {
97 : EnterCriticalSection(cs);
98 : }
99 :
100 :
101 : static V8_INLINE void UnlockNativeHandle(PCRITICAL_SECTION cs) {
102 : LeaveCriticalSection(cs);
103 : }
104 :
105 :
106 : static V8_INLINE bool TryLockNativeHandle(PCRITICAL_SECTION cs) {
107 : return TryEnterCriticalSection(cs) != FALSE;
108 : }
109 :
110 : #endif // V8_OS_POSIX
111 :
112 :
113 3205347 : Mutex::Mutex() {
114 3205347 : InitializeNativeHandle(&native_handle_);
115 : #ifdef DEBUG
116 : level_ = 0;
117 : #endif
118 3205346 : }
119 :
120 :
121 2877415 : Mutex::~Mutex() {
122 2877415 : DestroyNativeHandle(&native_handle_);
123 : DCHECK_EQ(0, level_);
124 2877417 : }
125 :
126 :
127 183281878 : void Mutex::Lock() {
128 183281878 : LockNativeHandle(&native_handle_);
129 : AssertUnheldAndMark();
130 183315595 : }
131 :
132 :
133 183310723 : void Mutex::Unlock() {
134 : AssertHeldAndUnmark();
135 183310723 : UnlockNativeHandle(&native_handle_);
136 183312372 : }
137 :
138 :
139 0 : bool Mutex::TryLock() {
140 0 : if (!TryLockNativeHandle(&native_handle_)) {
141 : return false;
142 : }
143 : AssertUnheldAndMark();
144 0 : return true;
145 : }
146 :
147 :
148 961141 : RecursiveMutex::RecursiveMutex() {
149 961141 : InitializeRecursiveNativeHandle(&native_handle_);
150 : #ifdef DEBUG
151 : level_ = 0;
152 : #endif
153 961141 : }
154 :
155 :
156 937575 : RecursiveMutex::~RecursiveMutex() {
157 937575 : DestroyNativeHandle(&native_handle_);
158 : DCHECK_EQ(0, level_);
159 937553 : }
160 :
161 :
162 15045639 : void RecursiveMutex::Lock() {
163 15045639 : LockNativeHandle(&native_handle_);
164 : #ifdef DEBUG
165 : DCHECK_LE(0, level_);
166 : level_++;
167 : #endif
168 15045710 : }
169 :
170 :
171 15045652 : void RecursiveMutex::Unlock() {
172 : #ifdef DEBUG
173 : DCHECK_LT(0, level_);
174 : level_--;
175 : #endif
176 15045652 : UnlockNativeHandle(&native_handle_);
177 15045708 : }
178 :
179 :
180 4 : bool RecursiveMutex::TryLock() {
181 8 : if (!TryLockNativeHandle(&native_handle_)) {
182 : return false;
183 : }
184 : #ifdef DEBUG
185 : DCHECK_LE(0, level_);
186 : level_++;
187 : #endif
188 4 : return true;
189 : }
190 :
191 : } // namespace base
192 : } // namespace v8
|