OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "platform/globals.h" // NOLINT | 5 #include "platform/globals.h" // NOLINT |
6 #if defined(HOST_OS_MACOS) | 6 #if defined(HOST_OS_MACOS) |
7 | 7 |
8 #include "vm/os_thread.h" | 8 #include "vm/os_thread.h" |
9 | 9 |
10 #include <sys/errno.h> // NOLINT | 10 #include <mach/mach_host.h> // NOLINT |
11 #include <sys/types.h> // NOLINT | |
12 #include <sys/sysctl.h> // NOLINT | |
13 #include <mach/mach_init.h> // NOLINT | 11 #include <mach/mach_init.h> // NOLINT |
14 #include <mach/mach_host.h> // NOLINT | |
15 #include <mach/mach_port.h> // NOLINT | 12 #include <mach/mach_port.h> // NOLINT |
16 #include <mach/mach_traps.h> // NOLINT | 13 #include <mach/mach_traps.h> // NOLINT |
17 #include <mach/task_info.h> // NOLINT | 14 #include <mach/task_info.h> // NOLINT |
| 15 #include <mach/thread_act.h> // NOLINT |
18 #include <mach/thread_info.h> // NOLINT | 16 #include <mach/thread_info.h> // NOLINT |
19 #include <mach/thread_act.h> // NOLINT | 17 #include <sys/errno.h> // NOLINT |
| 18 #include <sys/sysctl.h> // NOLINT |
| 19 #include <sys/types.h> // NOLINT |
20 | 20 |
21 #include "platform/assert.h" | 21 #include "platform/assert.h" |
22 #include "platform/utils.h" | 22 #include "platform/utils.h" |
23 | 23 |
24 #include "vm/profiler.h" | 24 #include "vm/profiler.h" |
25 | 25 |
26 namespace dart { | 26 namespace dart { |
27 | 27 |
28 #define VALIDATE_PTHREAD_RESULT(result) \ | 28 #define VALIDATE_PTHREAD_RESULT(result) \ |
29 if (result != 0) { \ | 29 if (result != 0) { \ |
30 const int kBufferSize = 1024; \ | 30 const int kBufferSize = 1024; \ |
31 char error_message[kBufferSize]; \ | 31 char error_message[kBufferSize]; \ |
32 NOT_IN_PRODUCT(Profiler::DumpStackTrace()); \ | 32 NOT_IN_PRODUCT(Profiler::DumpStackTrace()); \ |
33 Utils::StrError(result, error_message, kBufferSize); \ | 33 Utils::StrError(result, error_message, kBufferSize); \ |
34 FATAL2("pthread error: %d (%s)", result, error_message); \ | 34 FATAL2("pthread error: %d (%s)", result, error_message); \ |
35 } | 35 } |
36 | 36 |
37 | |
38 #if defined(DEBUG) | 37 #if defined(DEBUG) |
39 #define ASSERT_PTHREAD_SUCCESS(result) VALIDATE_PTHREAD_RESULT(result) | 38 #define ASSERT_PTHREAD_SUCCESS(result) VALIDATE_PTHREAD_RESULT(result) |
40 #else | 39 #else |
41 // NOTE: This (currently) expands to a no-op. | 40 // NOTE: This (currently) expands to a no-op. |
42 #define ASSERT_PTHREAD_SUCCESS(result) ASSERT(result == 0) | 41 #define ASSERT_PTHREAD_SUCCESS(result) ASSERT(result == 0) |
43 #endif | 42 #endif |
44 | 43 |
45 | |
46 #ifdef DEBUG | 44 #ifdef DEBUG |
47 #define RETURN_ON_PTHREAD_FAILURE(result) \ | 45 #define RETURN_ON_PTHREAD_FAILURE(result) \ |
48 if (result != 0) { \ | 46 if (result != 0) { \ |
49 const int kBufferSize = 1024; \ | 47 const int kBufferSize = 1024; \ |
50 char error_message[kBufferSize]; \ | 48 char error_message[kBufferSize]; \ |
51 Utils::StrError(result, error_message, kBufferSize); \ | 49 Utils::StrError(result, error_message, kBufferSize); \ |
52 fprintf(stderr, "%s:%d: pthread error: %d (%s)\n", __FILE__, __LINE__, \ | 50 fprintf(stderr, "%s:%d: pthread error: %d (%s)\n", __FILE__, __LINE__, \ |
53 result, error_message); \ | 51 result, error_message); \ |
54 return result; \ | 52 return result; \ |
55 } | 53 } |
56 #else | 54 #else |
57 #define RETURN_ON_PTHREAD_FAILURE(result) \ | 55 #define RETURN_ON_PTHREAD_FAILURE(result) \ |
58 if (result != 0) return result; | 56 if (result != 0) return result; |
59 #endif | 57 #endif |
60 | 58 |
61 | |
62 class ThreadStartData { | 59 class ThreadStartData { |
63 public: | 60 public: |
64 ThreadStartData(const char* name, | 61 ThreadStartData(const char* name, |
65 OSThread::ThreadStartFunction function, | 62 OSThread::ThreadStartFunction function, |
66 uword parameter) | 63 uword parameter) |
67 : name_(name), function_(function), parameter_(parameter) {} | 64 : name_(name), function_(function), parameter_(parameter) {} |
68 | 65 |
69 const char* name() const { return name_; } | 66 const char* name() const { return name_; } |
70 OSThread::ThreadStartFunction function() const { return function_; } | 67 OSThread::ThreadStartFunction function() const { return function_; } |
71 uword parameter() const { return parameter_; } | 68 uword parameter() const { return parameter_; } |
72 | 69 |
73 private: | 70 private: |
74 const char* name_; | 71 const char* name_; |
75 OSThread::ThreadStartFunction function_; | 72 OSThread::ThreadStartFunction function_; |
76 uword parameter_; | 73 uword parameter_; |
77 | 74 |
78 DISALLOW_COPY_AND_ASSIGN(ThreadStartData); | 75 DISALLOW_COPY_AND_ASSIGN(ThreadStartData); |
79 }; | 76 }; |
80 | 77 |
81 | |
82 // Dispatch to the thread start function provided by the caller. This trampoline | 78 // Dispatch to the thread start function provided by the caller. This trampoline |
83 // is used to ensure that the thread is properly destroyed if the thread just | 79 // is used to ensure that the thread is properly destroyed if the thread just |
84 // exits. | 80 // exits. |
85 static void* ThreadStart(void* data_ptr) { | 81 static void* ThreadStart(void* data_ptr) { |
86 ThreadStartData* data = reinterpret_cast<ThreadStartData*>(data_ptr); | 82 ThreadStartData* data = reinterpret_cast<ThreadStartData*>(data_ptr); |
87 | 83 |
88 const char* name = data->name(); | 84 const char* name = data->name(); |
89 OSThread::ThreadStartFunction function = data->function(); | 85 OSThread::ThreadStartFunction function = data->function(); |
90 uword parameter = data->parameter(); | 86 uword parameter = data->parameter(); |
91 delete data; | 87 delete data; |
92 | 88 |
93 // Create new OSThread object and set as TLS for new thread. | 89 // Create new OSThread object and set as TLS for new thread. |
94 OSThread* thread = OSThread::CreateOSThread(); | 90 OSThread* thread = OSThread::CreateOSThread(); |
95 if (thread != NULL) { | 91 if (thread != NULL) { |
96 OSThread::SetCurrent(thread); | 92 OSThread::SetCurrent(thread); |
97 thread->set_name(name); | 93 thread->set_name(name); |
98 | 94 |
99 // Call the supplied thread start function handing it its parameters. | 95 // Call the supplied thread start function handing it its parameters. |
100 function(parameter); | 96 function(parameter); |
101 } | 97 } |
102 | 98 |
103 return NULL; | 99 return NULL; |
104 } | 100 } |
105 | 101 |
106 | |
107 int OSThread::Start(const char* name, | 102 int OSThread::Start(const char* name, |
108 ThreadStartFunction function, | 103 ThreadStartFunction function, |
109 uword parameter) { | 104 uword parameter) { |
110 pthread_attr_t attr; | 105 pthread_attr_t attr; |
111 int result = pthread_attr_init(&attr); | 106 int result = pthread_attr_init(&attr); |
112 RETURN_ON_PTHREAD_FAILURE(result); | 107 RETURN_ON_PTHREAD_FAILURE(result); |
113 | 108 |
114 result = pthread_attr_setstacksize(&attr, OSThread::GetMaxStackSize()); | 109 result = pthread_attr_setstacksize(&attr, OSThread::GetMaxStackSize()); |
115 RETURN_ON_PTHREAD_FAILURE(result); | 110 RETURN_ON_PTHREAD_FAILURE(result); |
116 | 111 |
117 ThreadStartData* data = new ThreadStartData(name, function, parameter); | 112 ThreadStartData* data = new ThreadStartData(name, function, parameter); |
118 | 113 |
119 pthread_t tid; | 114 pthread_t tid; |
120 result = pthread_create(&tid, &attr, ThreadStart, data); | 115 result = pthread_create(&tid, &attr, ThreadStart, data); |
121 RETURN_ON_PTHREAD_FAILURE(result); | 116 RETURN_ON_PTHREAD_FAILURE(result); |
122 | 117 |
123 result = pthread_attr_destroy(&attr); | 118 result = pthread_attr_destroy(&attr); |
124 RETURN_ON_PTHREAD_FAILURE(result); | 119 RETURN_ON_PTHREAD_FAILURE(result); |
125 | 120 |
126 return 0; | 121 return 0; |
127 } | 122 } |
128 | 123 |
129 | |
130 const ThreadId OSThread::kInvalidThreadId = reinterpret_cast<ThreadId>(NULL); | 124 const ThreadId OSThread::kInvalidThreadId = reinterpret_cast<ThreadId>(NULL); |
131 const ThreadJoinId OSThread::kInvalidThreadJoinId = | 125 const ThreadJoinId OSThread::kInvalidThreadJoinId = |
132 reinterpret_cast<ThreadJoinId>(NULL); | 126 reinterpret_cast<ThreadJoinId>(NULL); |
133 | 127 |
134 | |
135 ThreadLocalKey OSThread::CreateThreadLocal(ThreadDestructor destructor) { | 128 ThreadLocalKey OSThread::CreateThreadLocal(ThreadDestructor destructor) { |
136 pthread_key_t key = kUnsetThreadLocalKey; | 129 pthread_key_t key = kUnsetThreadLocalKey; |
137 int result = pthread_key_create(&key, destructor); | 130 int result = pthread_key_create(&key, destructor); |
138 VALIDATE_PTHREAD_RESULT(result); | 131 VALIDATE_PTHREAD_RESULT(result); |
139 ASSERT(key != kUnsetThreadLocalKey); | 132 ASSERT(key != kUnsetThreadLocalKey); |
140 return key; | 133 return key; |
141 } | 134 } |
142 | 135 |
143 | |
144 void OSThread::DeleteThreadLocal(ThreadLocalKey key) { | 136 void OSThread::DeleteThreadLocal(ThreadLocalKey key) { |
145 ASSERT(key != kUnsetThreadLocalKey); | 137 ASSERT(key != kUnsetThreadLocalKey); |
146 int result = pthread_key_delete(key); | 138 int result = pthread_key_delete(key); |
147 VALIDATE_PTHREAD_RESULT(result); | 139 VALIDATE_PTHREAD_RESULT(result); |
148 } | 140 } |
149 | 141 |
150 | |
151 void OSThread::SetThreadLocal(ThreadLocalKey key, uword value) { | 142 void OSThread::SetThreadLocal(ThreadLocalKey key, uword value) { |
152 ASSERT(key != kUnsetThreadLocalKey); | 143 ASSERT(key != kUnsetThreadLocalKey); |
153 int result = pthread_setspecific(key, reinterpret_cast<void*>(value)); | 144 int result = pthread_setspecific(key, reinterpret_cast<void*>(value)); |
154 VALIDATE_PTHREAD_RESULT(result); | 145 VALIDATE_PTHREAD_RESULT(result); |
155 } | 146 } |
156 | 147 |
157 | |
158 intptr_t OSThread::GetMaxStackSize() { | 148 intptr_t OSThread::GetMaxStackSize() { |
159 const int kStackSize = (128 * kWordSize * KB); | 149 const int kStackSize = (128 * kWordSize * KB); |
160 return kStackSize; | 150 return kStackSize; |
161 } | 151 } |
162 | 152 |
163 | |
164 ThreadId OSThread::GetCurrentThreadId() { | 153 ThreadId OSThread::GetCurrentThreadId() { |
165 return pthread_self(); | 154 return pthread_self(); |
166 } | 155 } |
167 | 156 |
168 | |
169 #ifndef PRODUCT | 157 #ifndef PRODUCT |
170 ThreadId OSThread::GetCurrentThreadTraceId() { | 158 ThreadId OSThread::GetCurrentThreadTraceId() { |
171 return ThreadIdFromIntPtr(pthread_mach_thread_np(pthread_self())); | 159 return ThreadIdFromIntPtr(pthread_mach_thread_np(pthread_self())); |
172 } | 160 } |
173 #endif // PRODUCT | 161 #endif // PRODUCT |
174 | 162 |
175 | |
176 ThreadJoinId OSThread::GetCurrentThreadJoinId(OSThread* thread) { | 163 ThreadJoinId OSThread::GetCurrentThreadJoinId(OSThread* thread) { |
177 ASSERT(thread != NULL); | 164 ASSERT(thread != NULL); |
178 // Make sure we're filling in the join id for the current thread. | 165 // Make sure we're filling in the join id for the current thread. |
179 ASSERT(thread->id() == GetCurrentThreadId()); | 166 ASSERT(thread->id() == GetCurrentThreadId()); |
180 // Make sure the join_id_ hasn't been set, yet. | 167 // Make sure the join_id_ hasn't been set, yet. |
181 DEBUG_ASSERT(thread->join_id_ == kInvalidThreadJoinId); | 168 DEBUG_ASSERT(thread->join_id_ == kInvalidThreadJoinId); |
182 pthread_t id = pthread_self(); | 169 pthread_t id = pthread_self(); |
183 #if defined(DEBUG) | 170 #if defined(DEBUG) |
184 thread->join_id_ = id; | 171 thread->join_id_ = id; |
185 #endif | 172 #endif |
186 return id; | 173 return id; |
187 } | 174 } |
188 | 175 |
189 | |
190 void OSThread::Join(ThreadJoinId id) { | 176 void OSThread::Join(ThreadJoinId id) { |
191 int result = pthread_join(id, NULL); | 177 int result = pthread_join(id, NULL); |
192 ASSERT(result == 0); | 178 ASSERT(result == 0); |
193 } | 179 } |
194 | 180 |
195 | |
196 intptr_t OSThread::ThreadIdToIntPtr(ThreadId id) { | 181 intptr_t OSThread::ThreadIdToIntPtr(ThreadId id) { |
197 ASSERT(sizeof(id) == sizeof(intptr_t)); | 182 ASSERT(sizeof(id) == sizeof(intptr_t)); |
198 return reinterpret_cast<intptr_t>(id); | 183 return reinterpret_cast<intptr_t>(id); |
199 } | 184 } |
200 | 185 |
201 | |
202 ThreadId OSThread::ThreadIdFromIntPtr(intptr_t id) { | 186 ThreadId OSThread::ThreadIdFromIntPtr(intptr_t id) { |
203 return reinterpret_cast<ThreadId>(id); | 187 return reinterpret_cast<ThreadId>(id); |
204 } | 188 } |
205 | 189 |
206 | |
207 bool OSThread::Compare(ThreadId a, ThreadId b) { | 190 bool OSThread::Compare(ThreadId a, ThreadId b) { |
208 return pthread_equal(a, b) != 0; | 191 return pthread_equal(a, b) != 0; |
209 } | 192 } |
210 | 193 |
211 | |
212 bool OSThread::GetCurrentStackBounds(uword* lower, uword* upper) { | 194 bool OSThread::GetCurrentStackBounds(uword* lower, uword* upper) { |
213 *upper = reinterpret_cast<uword>(pthread_get_stackaddr_np(pthread_self())); | 195 *upper = reinterpret_cast<uword>(pthread_get_stackaddr_np(pthread_self())); |
214 *lower = *upper - pthread_get_stacksize_np(pthread_self()); | 196 *lower = *upper - pthread_get_stacksize_np(pthread_self()); |
215 return true; | 197 return true; |
216 } | 198 } |
217 | 199 |
218 | |
219 Mutex::Mutex() { | 200 Mutex::Mutex() { |
220 pthread_mutexattr_t attr; | 201 pthread_mutexattr_t attr; |
221 int result = pthread_mutexattr_init(&attr); | 202 int result = pthread_mutexattr_init(&attr); |
222 VALIDATE_PTHREAD_RESULT(result); | 203 VALIDATE_PTHREAD_RESULT(result); |
223 | 204 |
224 #if defined(DEBUG) | 205 #if defined(DEBUG) |
225 result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); | 206 result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); |
226 VALIDATE_PTHREAD_RESULT(result); | 207 VALIDATE_PTHREAD_RESULT(result); |
227 #endif // defined(DEBUG) | 208 #endif // defined(DEBUG) |
228 | 209 |
229 result = pthread_mutex_init(data_.mutex(), &attr); | 210 result = pthread_mutex_init(data_.mutex(), &attr); |
230 // Verify that creating a pthread_mutex succeeded. | 211 // Verify that creating a pthread_mutex succeeded. |
231 VALIDATE_PTHREAD_RESULT(result); | 212 VALIDATE_PTHREAD_RESULT(result); |
232 | 213 |
233 result = pthread_mutexattr_destroy(&attr); | 214 result = pthread_mutexattr_destroy(&attr); |
234 VALIDATE_PTHREAD_RESULT(result); | 215 VALIDATE_PTHREAD_RESULT(result); |
235 | 216 |
236 #if defined(DEBUG) | 217 #if defined(DEBUG) |
237 // When running with assertions enabled we do track the owner. | 218 // When running with assertions enabled we do track the owner. |
238 owner_ = OSThread::kInvalidThreadId; | 219 owner_ = OSThread::kInvalidThreadId; |
239 #endif // defined(DEBUG) | 220 #endif // defined(DEBUG) |
240 } | 221 } |
241 | 222 |
242 | |
243 Mutex::~Mutex() { | 223 Mutex::~Mutex() { |
244 int result = pthread_mutex_destroy(data_.mutex()); | 224 int result = pthread_mutex_destroy(data_.mutex()); |
245 // Verify that the pthread_mutex was destroyed. | 225 // Verify that the pthread_mutex was destroyed. |
246 VALIDATE_PTHREAD_RESULT(result); | 226 VALIDATE_PTHREAD_RESULT(result); |
247 | 227 |
248 #if defined(DEBUG) | 228 #if defined(DEBUG) |
249 // When running with assertions enabled we do track the owner. | 229 // When running with assertions enabled we do track the owner. |
250 ASSERT(owner_ == OSThread::kInvalidThreadId); | 230 ASSERT(owner_ == OSThread::kInvalidThreadId); |
251 #endif // defined(DEBUG) | 231 #endif // defined(DEBUG) |
252 } | 232 } |
253 | 233 |
254 | |
255 void Mutex::Lock() { | 234 void Mutex::Lock() { |
256 int result = pthread_mutex_lock(data_.mutex()); | 235 int result = pthread_mutex_lock(data_.mutex()); |
257 // Specifically check for dead lock to help debugging. | 236 // Specifically check for dead lock to help debugging. |
258 ASSERT(result != EDEADLK); | 237 ASSERT(result != EDEADLK); |
259 ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors. | 238 ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors. |
260 #if defined(DEBUG) | 239 #if defined(DEBUG) |
261 // When running with assertions enabled we do track the owner. | 240 // When running with assertions enabled we do track the owner. |
262 owner_ = OSThread::GetCurrentThreadId(); | 241 owner_ = OSThread::GetCurrentThreadId(); |
263 #endif // defined(DEBUG) | 242 #endif // defined(DEBUG) |
264 } | 243 } |
265 | 244 |
266 | |
267 bool Mutex::TryLock() { | 245 bool Mutex::TryLock() { |
268 int result = pthread_mutex_trylock(data_.mutex()); | 246 int result = pthread_mutex_trylock(data_.mutex()); |
269 // Return false if the lock is busy and locking failed. | 247 // Return false if the lock is busy and locking failed. |
270 if ((result == EBUSY) || (result == EDEADLK)) { | 248 if ((result == EBUSY) || (result == EDEADLK)) { |
271 return false; | 249 return false; |
272 } | 250 } |
273 ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors. | 251 ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors. |
274 #if defined(DEBUG) | 252 #if defined(DEBUG) |
275 // When running with assertions enabled we do track the owner. | 253 // When running with assertions enabled we do track the owner. |
276 owner_ = OSThread::GetCurrentThreadId(); | 254 owner_ = OSThread::GetCurrentThreadId(); |
277 #endif // defined(DEBUG) | 255 #endif // defined(DEBUG) |
278 return true; | 256 return true; |
279 } | 257 } |
280 | 258 |
281 | |
282 void Mutex::Unlock() { | 259 void Mutex::Unlock() { |
283 #if defined(DEBUG) | 260 #if defined(DEBUG) |
284 // When running with assertions enabled we do track the owner. | 261 // When running with assertions enabled we do track the owner. |
285 ASSERT(IsOwnedByCurrentThread()); | 262 ASSERT(IsOwnedByCurrentThread()); |
286 owner_ = OSThread::kInvalidThreadId; | 263 owner_ = OSThread::kInvalidThreadId; |
287 #endif // defined(DEBUG) | 264 #endif // defined(DEBUG) |
288 int result = pthread_mutex_unlock(data_.mutex()); | 265 int result = pthread_mutex_unlock(data_.mutex()); |
289 // Specifically check for wrong thread unlocking to aid debugging. | 266 // Specifically check for wrong thread unlocking to aid debugging. |
290 ASSERT(result != EPERM); | 267 ASSERT(result != EPERM); |
291 ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors. | 268 ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors. |
292 } | 269 } |
293 | 270 |
294 | |
295 Monitor::Monitor() { | 271 Monitor::Monitor() { |
296 pthread_mutexattr_t attr; | 272 pthread_mutexattr_t attr; |
297 int result = pthread_mutexattr_init(&attr); | 273 int result = pthread_mutexattr_init(&attr); |
298 VALIDATE_PTHREAD_RESULT(result); | 274 VALIDATE_PTHREAD_RESULT(result); |
299 | 275 |
300 #if defined(DEBUG) | 276 #if defined(DEBUG) |
301 result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); | 277 result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); |
302 VALIDATE_PTHREAD_RESULT(result); | 278 VALIDATE_PTHREAD_RESULT(result); |
303 #endif // defined(DEBUG) | 279 #endif // defined(DEBUG) |
304 | 280 |
305 result = pthread_mutex_init(data_.mutex(), &attr); | 281 result = pthread_mutex_init(data_.mutex(), &attr); |
306 VALIDATE_PTHREAD_RESULT(result); | 282 VALIDATE_PTHREAD_RESULT(result); |
307 | 283 |
308 result = pthread_mutexattr_destroy(&attr); | 284 result = pthread_mutexattr_destroy(&attr); |
309 VALIDATE_PTHREAD_RESULT(result); | 285 VALIDATE_PTHREAD_RESULT(result); |
310 | 286 |
311 result = pthread_cond_init(data_.cond(), NULL); | 287 result = pthread_cond_init(data_.cond(), NULL); |
312 VALIDATE_PTHREAD_RESULT(result); | 288 VALIDATE_PTHREAD_RESULT(result); |
313 | 289 |
314 #if defined(DEBUG) | 290 #if defined(DEBUG) |
315 // When running with assertions enabled we track the owner. | 291 // When running with assertions enabled we track the owner. |
316 owner_ = OSThread::kInvalidThreadId; | 292 owner_ = OSThread::kInvalidThreadId; |
317 #endif // defined(DEBUG) | 293 #endif // defined(DEBUG) |
318 } | 294 } |
319 | 295 |
320 | |
321 Monitor::~Monitor() { | 296 Monitor::~Monitor() { |
322 #if defined(DEBUG) | 297 #if defined(DEBUG) |
323 // When running with assertions enabled we track the owner. | 298 // When running with assertions enabled we track the owner. |
324 ASSERT(owner_ == OSThread::kInvalidThreadId); | 299 ASSERT(owner_ == OSThread::kInvalidThreadId); |
325 #endif // defined(DEBUG) | 300 #endif // defined(DEBUG) |
326 | 301 |
327 int result = pthread_mutex_destroy(data_.mutex()); | 302 int result = pthread_mutex_destroy(data_.mutex()); |
328 VALIDATE_PTHREAD_RESULT(result); | 303 VALIDATE_PTHREAD_RESULT(result); |
329 | 304 |
330 result = pthread_cond_destroy(data_.cond()); | 305 result = pthread_cond_destroy(data_.cond()); |
331 VALIDATE_PTHREAD_RESULT(result); | 306 VALIDATE_PTHREAD_RESULT(result); |
332 } | 307 } |
333 | 308 |
334 | |
335 bool Monitor::TryEnter() { | 309 bool Monitor::TryEnter() { |
336 int result = pthread_mutex_trylock(data_.mutex()); | 310 int result = pthread_mutex_trylock(data_.mutex()); |
337 // Return false if the lock is busy and locking failed. | 311 // Return false if the lock is busy and locking failed. |
338 if ((result == EBUSY) || (result == EDEADLK)) { | 312 if ((result == EBUSY) || (result == EDEADLK)) { |
339 return false; | 313 return false; |
340 } | 314 } |
341 ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors. | 315 ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors. |
342 #if defined(DEBUG) | 316 #if defined(DEBUG) |
343 // When running with assertions enabled we track the owner. | 317 // When running with assertions enabled we track the owner. |
344 ASSERT(owner_ == OSThread::kInvalidThreadId); | 318 ASSERT(owner_ == OSThread::kInvalidThreadId); |
345 owner_ = OSThread::GetCurrentThreadId(); | 319 owner_ = OSThread::GetCurrentThreadId(); |
346 #endif // defined(DEBUG) | 320 #endif // defined(DEBUG) |
347 return true; | 321 return true; |
348 } | 322 } |
349 | 323 |
350 | |
351 void Monitor::Enter() { | 324 void Monitor::Enter() { |
352 int result = pthread_mutex_lock(data_.mutex()); | 325 int result = pthread_mutex_lock(data_.mutex()); |
353 VALIDATE_PTHREAD_RESULT(result); | 326 VALIDATE_PTHREAD_RESULT(result); |
354 | 327 |
355 #if defined(DEBUG) | 328 #if defined(DEBUG) |
356 // When running with assertions enabled we track the owner. | 329 // When running with assertions enabled we track the owner. |
357 ASSERT(owner_ == OSThread::kInvalidThreadId); | 330 ASSERT(owner_ == OSThread::kInvalidThreadId); |
358 owner_ = OSThread::GetCurrentThreadId(); | 331 owner_ = OSThread::GetCurrentThreadId(); |
359 #endif // defined(DEBUG) | 332 #endif // defined(DEBUG) |
360 } | 333 } |
361 | 334 |
362 | |
363 void Monitor::Exit() { | 335 void Monitor::Exit() { |
364 #if defined(DEBUG) | 336 #if defined(DEBUG) |
365 // When running with assertions enabled we track the owner. | 337 // When running with assertions enabled we track the owner. |
366 ASSERT(IsOwnedByCurrentThread()); | 338 ASSERT(IsOwnedByCurrentThread()); |
367 owner_ = OSThread::kInvalidThreadId; | 339 owner_ = OSThread::kInvalidThreadId; |
368 #endif // defined(DEBUG) | 340 #endif // defined(DEBUG) |
369 | 341 |
370 int result = pthread_mutex_unlock(data_.mutex()); | 342 int result = pthread_mutex_unlock(data_.mutex()); |
371 VALIDATE_PTHREAD_RESULT(result); | 343 VALIDATE_PTHREAD_RESULT(result); |
372 } | 344 } |
373 | 345 |
374 | |
375 Monitor::WaitResult Monitor::Wait(int64_t millis) { | 346 Monitor::WaitResult Monitor::Wait(int64_t millis) { |
376 return WaitMicros(millis * kMicrosecondsPerMillisecond); | 347 return WaitMicros(millis * kMicrosecondsPerMillisecond); |
377 } | 348 } |
378 | 349 |
379 | |
380 Monitor::WaitResult Monitor::WaitMicros(int64_t micros) { | 350 Monitor::WaitResult Monitor::WaitMicros(int64_t micros) { |
381 #if defined(DEBUG) | 351 #if defined(DEBUG) |
382 // When running with assertions enabled we track the owner. | 352 // When running with assertions enabled we track the owner. |
383 ASSERT(IsOwnedByCurrentThread()); | 353 ASSERT(IsOwnedByCurrentThread()); |
384 ThreadId saved_owner = owner_; | 354 ThreadId saved_owner = owner_; |
385 owner_ = OSThread::kInvalidThreadId; | 355 owner_ = OSThread::kInvalidThreadId; |
386 #endif // defined(DEBUG) | 356 #endif // defined(DEBUG) |
387 | 357 |
388 Monitor::WaitResult retval = kNotified; | 358 Monitor::WaitResult retval = kNotified; |
389 if (micros == kNoTimeout) { | 359 if (micros == kNoTimeout) { |
(...skipping 21 matching lines...) Expand all Loading... |
411 | 381 |
412 #if defined(DEBUG) | 382 #if defined(DEBUG) |
413 // When running with assertions enabled we track the owner. | 383 // When running with assertions enabled we track the owner. |
414 ASSERT(owner_ == OSThread::kInvalidThreadId); | 384 ASSERT(owner_ == OSThread::kInvalidThreadId); |
415 owner_ = OSThread::GetCurrentThreadId(); | 385 owner_ = OSThread::GetCurrentThreadId(); |
416 ASSERT(owner_ == saved_owner); | 386 ASSERT(owner_ == saved_owner); |
417 #endif // defined(DEBUG) | 387 #endif // defined(DEBUG) |
418 return retval; | 388 return retval; |
419 } | 389 } |
420 | 390 |
421 | |
422 void Monitor::Notify() { | 391 void Monitor::Notify() { |
423 // When running with assertions enabled we track the owner. | 392 // When running with assertions enabled we track the owner. |
424 ASSERT(IsOwnedByCurrentThread()); | 393 ASSERT(IsOwnedByCurrentThread()); |
425 int result = pthread_cond_signal(data_.cond()); | 394 int result = pthread_cond_signal(data_.cond()); |
426 VALIDATE_PTHREAD_RESULT(result); | 395 VALIDATE_PTHREAD_RESULT(result); |
427 } | 396 } |
428 | 397 |
429 | |
430 void Monitor::NotifyAll() { | 398 void Monitor::NotifyAll() { |
431 // When running with assertions enabled we track the owner. | 399 // When running with assertions enabled we track the owner. |
432 ASSERT(IsOwnedByCurrentThread()); | 400 ASSERT(IsOwnedByCurrentThread()); |
433 int result = pthread_cond_broadcast(data_.cond()); | 401 int result = pthread_cond_broadcast(data_.cond()); |
434 VALIDATE_PTHREAD_RESULT(result); | 402 VALIDATE_PTHREAD_RESULT(result); |
435 } | 403 } |
436 | 404 |
437 } // namespace dart | 405 } // namespace dart |
438 | 406 |
439 #endif // defined(HOST_OS_MACOS) | 407 #endif // defined(HOST_OS_MACOS) |
OLD | NEW |