OLD | NEW |
| (Empty) |
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/platform/mutex.h" | |
6 | |
7 #include <errno.h> | |
8 | |
9 namespace v8 { | |
10 namespace internal { | |
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 ASSERT_EQ(0, result); | |
21 result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); | |
22 ASSERT_EQ(0, result); | |
23 result = pthread_mutex_init(mutex, &attr); | |
24 ASSERT_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 ASSERT_EQ(0, result); | |
31 USE(result); | |
32 } | |
33 | |
34 | |
35 static V8_INLINE void InitializeRecursiveNativeHandle(pthread_mutex_t* mutex) { | |
36 pthread_mutexattr_t attr; | |
37 int result = pthread_mutexattr_init(&attr); | |
38 ASSERT_EQ(0, result); | |
39 result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); | |
40 ASSERT_EQ(0, result); | |
41 result = pthread_mutex_init(mutex, &attr); | |
42 ASSERT_EQ(0, result); | |
43 result = pthread_mutexattr_destroy(&attr); | |
44 ASSERT_EQ(0, result); | |
45 USE(result); | |
46 } | |
47 | |
48 | |
49 static V8_INLINE void DestroyNativeHandle(pthread_mutex_t* mutex) { | |
50 int result = pthread_mutex_destroy(mutex); | |
51 ASSERT_EQ(0, result); | |
52 USE(result); | |
53 } | |
54 | |
55 | |
56 static V8_INLINE void LockNativeHandle(pthread_mutex_t* mutex) { | |
57 int result = pthread_mutex_lock(mutex); | |
58 ASSERT_EQ(0, result); | |
59 USE(result); | |
60 } | |
61 | |
62 | |
63 static V8_INLINE void UnlockNativeHandle(pthread_mutex_t* mutex) { | |
64 int result = pthread_mutex_unlock(mutex); | |
65 ASSERT_EQ(0, result); | |
66 USE(result); | |
67 } | |
68 | |
69 | |
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 ASSERT_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 | |
113 Mutex::Mutex() { | |
114 InitializeNativeHandle(&native_handle_); | |
115 #ifdef DEBUG | |
116 level_ = 0; | |
117 #endif | |
118 } | |
119 | |
120 | |
121 Mutex::~Mutex() { | |
122 DestroyNativeHandle(&native_handle_); | |
123 ASSERT_EQ(0, level_); | |
124 } | |
125 | |
126 | |
127 void Mutex::Lock() { | |
128 LockNativeHandle(&native_handle_); | |
129 AssertUnheldAndMark(); | |
130 } | |
131 | |
132 | |
133 void Mutex::Unlock() { | |
134 AssertHeldAndUnmark(); | |
135 UnlockNativeHandle(&native_handle_); | |
136 } | |
137 | |
138 | |
139 bool Mutex::TryLock() { | |
140 if (!TryLockNativeHandle(&native_handle_)) { | |
141 return false; | |
142 } | |
143 AssertUnheldAndMark(); | |
144 return true; | |
145 } | |
146 | |
147 | |
148 RecursiveMutex::RecursiveMutex() { | |
149 InitializeRecursiveNativeHandle(&native_handle_); | |
150 #ifdef DEBUG | |
151 level_ = 0; | |
152 #endif | |
153 } | |
154 | |
155 | |
156 RecursiveMutex::~RecursiveMutex() { | |
157 DestroyNativeHandle(&native_handle_); | |
158 ASSERT_EQ(0, level_); | |
159 } | |
160 | |
161 | |
162 void RecursiveMutex::Lock() { | |
163 LockNativeHandle(&native_handle_); | |
164 #ifdef DEBUG | |
165 ASSERT_LE(0, level_); | |
166 level_++; | |
167 #endif | |
168 } | |
169 | |
170 | |
171 void RecursiveMutex::Unlock() { | |
172 #ifdef DEBUG | |
173 ASSERT_LT(0, level_); | |
174 level_--; | |
175 #endif | |
176 UnlockNativeHandle(&native_handle_); | |
177 } | |
178 | |
179 | |
180 bool RecursiveMutex::TryLock() { | |
181 if (!TryLockNativeHandle(&native_handle_)) { | |
182 return false; | |
183 } | |
184 #ifdef DEBUG | |
185 ASSERT_LE(0, level_); | |
186 level_++; | |
187 #endif | |
188 return true; | |
189 } | |
190 | |
191 } } // namespace v8::internal | |
OLD | NEW |