• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #include "platform/mutex.h"
29 
30 #include <cerrno>
31 
32 namespace v8 {
33 namespace internal {
34 
35 #if V8_OS_POSIX
36 
InitializeNativeHandle(pthread_mutex_t * mutex)37 static V8_INLINE void InitializeNativeHandle(pthread_mutex_t* mutex) {
38   int result;
39 #if defined(DEBUG)
40   // Use an error checking mutex in debug mode.
41   pthread_mutexattr_t attr;
42   result = pthread_mutexattr_init(&attr);
43   ASSERT_EQ(0, result);
44   result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
45   ASSERT_EQ(0, result);
46   result = pthread_mutex_init(mutex, &attr);
47   ASSERT_EQ(0, result);
48   result = pthread_mutexattr_destroy(&attr);
49 #else
50   // Use a fast mutex (default attributes).
51   result = pthread_mutex_init(mutex, NULL);
52 #endif  // defined(DEBUG)
53   ASSERT_EQ(0, result);
54   USE(result);
55 }
56 
57 
InitializeRecursiveNativeHandle(pthread_mutex_t * mutex)58 static V8_INLINE void InitializeRecursiveNativeHandle(pthread_mutex_t* mutex) {
59   pthread_mutexattr_t attr;
60   int result = pthread_mutexattr_init(&attr);
61   ASSERT_EQ(0, result);
62   result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
63   ASSERT_EQ(0, result);
64   result = pthread_mutex_init(mutex, &attr);
65   ASSERT_EQ(0, result);
66   result = pthread_mutexattr_destroy(&attr);
67   ASSERT_EQ(0, result);
68   USE(result);
69 }
70 
71 
DestroyNativeHandle(pthread_mutex_t * mutex)72 static V8_INLINE void DestroyNativeHandle(pthread_mutex_t* mutex) {
73   int result = pthread_mutex_destroy(mutex);
74   ASSERT_EQ(0, result);
75   USE(result);
76 }
77 
78 
LockNativeHandle(pthread_mutex_t * mutex)79 static V8_INLINE void LockNativeHandle(pthread_mutex_t* mutex) {
80   int result = pthread_mutex_lock(mutex);
81   ASSERT_EQ(0, result);
82   USE(result);
83 }
84 
85 
UnlockNativeHandle(pthread_mutex_t * mutex)86 static V8_INLINE void UnlockNativeHandle(pthread_mutex_t* mutex) {
87   int result = pthread_mutex_unlock(mutex);
88   ASSERT_EQ(0, result);
89   USE(result);
90 }
91 
92 
TryLockNativeHandle(pthread_mutex_t * mutex)93 static V8_INLINE bool TryLockNativeHandle(pthread_mutex_t* mutex) {
94   int result = pthread_mutex_trylock(mutex);
95   if (result == EBUSY) {
96     return false;
97   }
98   ASSERT_EQ(0, result);
99   return true;
100 }
101 
102 #elif V8_OS_WIN
103 
104 static V8_INLINE void InitializeNativeHandle(PCRITICAL_SECTION cs) {
105   InitializeCriticalSection(cs);
106 }
107 
108 
109 static V8_INLINE void InitializeRecursiveNativeHandle(PCRITICAL_SECTION cs) {
110   InitializeCriticalSection(cs);
111 }
112 
113 
114 static V8_INLINE void DestroyNativeHandle(PCRITICAL_SECTION cs) {
115   DeleteCriticalSection(cs);
116 }
117 
118 
119 static V8_INLINE void LockNativeHandle(PCRITICAL_SECTION cs) {
120   EnterCriticalSection(cs);
121 }
122 
123 
124 static V8_INLINE void UnlockNativeHandle(PCRITICAL_SECTION cs) {
125   LeaveCriticalSection(cs);
126 }
127 
128 
129 static V8_INLINE bool TryLockNativeHandle(PCRITICAL_SECTION cs) {
130   return TryEnterCriticalSection(cs);
131 }
132 
133 #endif  // V8_OS_POSIX
134 
135 
Mutex()136 Mutex::Mutex() {
137   InitializeNativeHandle(&native_handle_);
138 #ifdef DEBUG
139   level_ = 0;
140 #endif
141 }
142 
143 
~Mutex()144 Mutex::~Mutex() {
145   DestroyNativeHandle(&native_handle_);
146   ASSERT_EQ(0, level_);
147 }
148 
149 
Lock()150 void Mutex::Lock() {
151   LockNativeHandle(&native_handle_);
152   AssertUnheldAndMark();
153 }
154 
155 
Unlock()156 void Mutex::Unlock() {
157   AssertHeldAndUnmark();
158   UnlockNativeHandle(&native_handle_);
159 }
160 
161 
TryLock()162 bool Mutex::TryLock() {
163   if (!TryLockNativeHandle(&native_handle_)) {
164     return false;
165   }
166   AssertUnheldAndMark();
167   return true;
168 }
169 
170 
RecursiveMutex()171 RecursiveMutex::RecursiveMutex() {
172   InitializeRecursiveNativeHandle(&native_handle_);
173 #ifdef DEBUG
174   level_ = 0;
175 #endif
176 }
177 
178 
~RecursiveMutex()179 RecursiveMutex::~RecursiveMutex() {
180   DestroyNativeHandle(&native_handle_);
181   ASSERT_EQ(0, level_);
182 }
183 
184 
Lock()185 void RecursiveMutex::Lock() {
186   LockNativeHandle(&native_handle_);
187 #ifdef DEBUG
188   ASSERT_LE(0, level_);
189   level_++;
190 #endif
191 }
192 
193 
Unlock()194 void RecursiveMutex::Unlock() {
195 #ifdef DEBUG
196   ASSERT_LT(0, level_);
197   level_--;
198 #endif
199   UnlockNativeHandle(&native_handle_);
200 }
201 
202 
TryLock()203 bool RecursiveMutex::TryLock() {
204   if (!TryLockNativeHandle(&native_handle_)) {
205     return false;
206   }
207 #ifdef DEBUG
208   ASSERT_LE(0, level_);
209   level_++;
210 #endif
211   return true;
212 }
213 
214 } }  // namespace v8::internal
215