• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
InitializeNativeHandle(pthread_mutex_t * mutex)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   result = pthread_mutex_init(mutex, NULL);
29 #endif  // defined(DEBUG)
30   DCHECK_EQ(0, result);
31   USE(result);
32 }
33 
34 
InitializeRecursiveNativeHandle(pthread_mutex_t * mutex)35 static V8_INLINE void InitializeRecursiveNativeHandle(pthread_mutex_t* mutex) {
36   pthread_mutexattr_t attr;
37   int result = pthread_mutexattr_init(&attr);
38   DCHECK_EQ(0, result);
39   result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
40   DCHECK_EQ(0, result);
41   result = pthread_mutex_init(mutex, &attr);
42   DCHECK_EQ(0, result);
43   result = pthread_mutexattr_destroy(&attr);
44   DCHECK_EQ(0, result);
45   USE(result);
46 }
47 
48 
DestroyNativeHandle(pthread_mutex_t * mutex)49 static V8_INLINE void DestroyNativeHandle(pthread_mutex_t* mutex) {
50   int result = pthread_mutex_destroy(mutex);
51   DCHECK_EQ(0, result);
52   USE(result);
53 }
54 
55 
LockNativeHandle(pthread_mutex_t * mutex)56 static V8_INLINE void LockNativeHandle(pthread_mutex_t* mutex) {
57   int result = pthread_mutex_lock(mutex);
58   DCHECK_EQ(0, result);
59   USE(result);
60 }
61 
62 
UnlockNativeHandle(pthread_mutex_t * mutex)63 static V8_INLINE void UnlockNativeHandle(pthread_mutex_t* mutex) {
64   int result = pthread_mutex_unlock(mutex);
65   DCHECK_EQ(0, result);
66   USE(result);
67 }
68 
69 
TryLockNativeHandle(pthread_mutex_t * mutex)70 static V8_INLINE bool TryLockNativeHandle(pthread_mutex_t* mutex) {
71   int result = pthread_mutex_trylock(mutex);
72   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);
108 }
109 
110 #endif  // V8_OS_POSIX
111 
112 
Mutex()113 Mutex::Mutex() {
114   InitializeNativeHandle(&native_handle_);
115 #ifdef DEBUG
116   level_ = 0;
117 #endif
118 }
119 
120 
~Mutex()121 Mutex::~Mutex() {
122   DestroyNativeHandle(&native_handle_);
123   DCHECK_EQ(0, level_);
124 }
125 
126 
Lock()127 void Mutex::Lock() {
128   LockNativeHandle(&native_handle_);
129   AssertUnheldAndMark();
130 }
131 
132 
Unlock()133 void Mutex::Unlock() {
134   AssertHeldAndUnmark();
135   UnlockNativeHandle(&native_handle_);
136 }
137 
138 
TryLock()139 bool Mutex::TryLock() {
140   if (!TryLockNativeHandle(&native_handle_)) {
141     return false;
142   }
143   AssertUnheldAndMark();
144   return true;
145 }
146 
147 
RecursiveMutex()148 RecursiveMutex::RecursiveMutex() {
149   InitializeRecursiveNativeHandle(&native_handle_);
150 #ifdef DEBUG
151   level_ = 0;
152 #endif
153 }
154 
155 
~RecursiveMutex()156 RecursiveMutex::~RecursiveMutex() {
157   DestroyNativeHandle(&native_handle_);
158   DCHECK_EQ(0, level_);
159 }
160 
161 
Lock()162 void RecursiveMutex::Lock() {
163   LockNativeHandle(&native_handle_);
164 #ifdef DEBUG
165   DCHECK_LE(0, level_);
166   level_++;
167 #endif
168 }
169 
170 
Unlock()171 void RecursiveMutex::Unlock() {
172 #ifdef DEBUG
173   DCHECK_LT(0, level_);
174   level_--;
175 #endif
176   UnlockNativeHandle(&native_handle_);
177 }
178 
179 
TryLock()180 bool RecursiveMutex::TryLock() {
181   if (!TryLockNativeHandle(&native_handle_)) {
182     return false;
183   }
184 #ifdef DEBUG
185   DCHECK_LE(0, level_);
186   level_++;
187 #endif
188   return true;
189 }
190 
191 }  // namespace base
192 }  // namespace v8
193