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(TARGET_OS_MACOS) | 6 #if defined(TARGET_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 <sys/errno.h> // NOLINT |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 VALIDATE_PTHREAD_RESULT(result); | 216 VALIDATE_PTHREAD_RESULT(result); |
217 #endif // defined(DEBUG) | 217 #endif // defined(DEBUG) |
218 | 218 |
219 result = pthread_mutex_init(data_.mutex(), &attr); | 219 result = pthread_mutex_init(data_.mutex(), &attr); |
220 // Verify that creating a pthread_mutex succeeded. | 220 // Verify that creating a pthread_mutex succeeded. |
221 VALIDATE_PTHREAD_RESULT(result); | 221 VALIDATE_PTHREAD_RESULT(result); |
222 | 222 |
223 result = pthread_mutexattr_destroy(&attr); | 223 result = pthread_mutexattr_destroy(&attr); |
224 VALIDATE_PTHREAD_RESULT(result); | 224 VALIDATE_PTHREAD_RESULT(result); |
225 | 225 |
| 226 #if defined(DEBUG) |
226 // When running with assertions enabled we do track the owner. | 227 // When running with assertions enabled we do track the owner. |
227 #if defined(DEBUG) | |
228 owner_ = OSThread::kInvalidThreadId; | 228 owner_ = OSThread::kInvalidThreadId; |
229 #endif // defined(DEBUG) | 229 #endif // defined(DEBUG) |
230 } | 230 } |
231 | 231 |
232 | 232 |
233 Mutex::~Mutex() { | 233 Mutex::~Mutex() { |
234 int result = pthread_mutex_destroy(data_.mutex()); | 234 int result = pthread_mutex_destroy(data_.mutex()); |
235 // Verify that the pthread_mutex was destroyed. | 235 // Verify that the pthread_mutex was destroyed. |
236 VALIDATE_PTHREAD_RESULT(result); | 236 VALIDATE_PTHREAD_RESULT(result); |
237 | 237 |
| 238 #if defined(DEBUG) |
238 // When running with assertions enabled we do track the owner. | 239 // When running with assertions enabled we do track the owner. |
239 #if defined(DEBUG) | |
240 ASSERT(owner_ == OSThread::kInvalidThreadId); | 240 ASSERT(owner_ == OSThread::kInvalidThreadId); |
241 #endif // defined(DEBUG) | 241 #endif // defined(DEBUG) |
242 } | 242 } |
243 | 243 |
244 | 244 |
245 void Mutex::Lock() { | 245 void Mutex::Lock() { |
246 int result = pthread_mutex_lock(data_.mutex()); | 246 int result = pthread_mutex_lock(data_.mutex()); |
247 // Specifically check for dead lock to help debugging. | 247 // Specifically check for dead lock to help debugging. |
248 ASSERT(result != EDEADLK); | 248 ASSERT(result != EDEADLK); |
249 ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors. | 249 ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors. |
| 250 #if defined(DEBUG) |
250 // When running with assertions enabled we do track the owner. | 251 // When running with assertions enabled we do track the owner. |
251 #if defined(DEBUG) | |
252 owner_ = OSThread::GetCurrentThreadId(); | 252 owner_ = OSThread::GetCurrentThreadId(); |
253 #endif // defined(DEBUG) | 253 #endif // defined(DEBUG) |
254 } | 254 } |
255 | 255 |
256 | 256 |
257 bool Mutex::TryLock() { | 257 bool Mutex::TryLock() { |
258 int result = pthread_mutex_trylock(data_.mutex()); | 258 int result = pthread_mutex_trylock(data_.mutex()); |
259 // Return false if the lock is busy and locking failed. | 259 // Return false if the lock is busy and locking failed. |
260 if ((result == EBUSY) || (result == EDEADLK)) { | 260 if ((result == EBUSY) || (result == EDEADLK)) { |
261 return false; | 261 return false; |
262 } | 262 } |
263 ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors. | 263 ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors. |
| 264 #if defined(DEBUG) |
264 // When running with assertions enabled we do track the owner. | 265 // When running with assertions enabled we do track the owner. |
265 #if defined(DEBUG) | |
266 owner_ = OSThread::GetCurrentThreadId(); | 266 owner_ = OSThread::GetCurrentThreadId(); |
267 #endif // defined(DEBUG) | 267 #endif // defined(DEBUG) |
268 return true; | 268 return true; |
269 } | 269 } |
270 | 270 |
271 | 271 |
272 void Mutex::Unlock() { | 272 void Mutex::Unlock() { |
| 273 #if defined(DEBUG) |
273 // When running with assertions enabled we do track the owner. | 274 // When running with assertions enabled we do track the owner. |
274 #if defined(DEBUG) | |
275 ASSERT(IsOwnedByCurrentThread()); | 275 ASSERT(IsOwnedByCurrentThread()); |
276 owner_ = OSThread::kInvalidThreadId; | 276 owner_ = OSThread::kInvalidThreadId; |
277 #endif // defined(DEBUG) | 277 #endif // defined(DEBUG) |
278 int result = pthread_mutex_unlock(data_.mutex()); | 278 int result = pthread_mutex_unlock(data_.mutex()); |
279 // Specifically check for wrong thread unlocking to aid debugging. | 279 // Specifically check for wrong thread unlocking to aid debugging. |
280 ASSERT(result != EPERM); | 280 ASSERT(result != EPERM); |
281 ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors. | 281 ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors. |
282 } | 282 } |
283 | 283 |
284 | 284 |
285 Monitor::Monitor() { | 285 Monitor::Monitor() { |
286 pthread_mutexattr_t attr; | 286 pthread_mutexattr_t attr; |
287 int result = pthread_mutexattr_init(&attr); | 287 int result = pthread_mutexattr_init(&attr); |
288 VALIDATE_PTHREAD_RESULT(result); | 288 VALIDATE_PTHREAD_RESULT(result); |
289 | 289 |
290 #if defined(DEBUG) | 290 #if defined(DEBUG) |
291 result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); | 291 result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); |
292 VALIDATE_PTHREAD_RESULT(result); | 292 VALIDATE_PTHREAD_RESULT(result); |
293 #endif // defined(DEBUG) | 293 #endif // defined(DEBUG) |
294 | 294 |
295 result = pthread_mutex_init(data_.mutex(), &attr); | 295 result = pthread_mutex_init(data_.mutex(), &attr); |
296 VALIDATE_PTHREAD_RESULT(result); | 296 VALIDATE_PTHREAD_RESULT(result); |
297 | 297 |
298 result = pthread_mutexattr_destroy(&attr); | 298 result = pthread_mutexattr_destroy(&attr); |
299 VALIDATE_PTHREAD_RESULT(result); | 299 VALIDATE_PTHREAD_RESULT(result); |
300 | 300 |
301 result = pthread_cond_init(data_.cond(), NULL); | 301 result = pthread_cond_init(data_.cond(), NULL); |
302 VALIDATE_PTHREAD_RESULT(result); | 302 VALIDATE_PTHREAD_RESULT(result); |
| 303 |
| 304 #if defined(DEBUG) |
| 305 // When running with assertions enabled we track the owner. |
| 306 owner_ = OSThread::kInvalidThreadId; |
| 307 #endif // defined(DEBUG) |
303 } | 308 } |
304 | 309 |
305 | 310 |
306 Monitor::~Monitor() { | 311 Monitor::~Monitor() { |
| 312 #if defined(DEBUG) |
| 313 // When running with assertions enabled we track the owner. |
| 314 ASSERT(owner_ == OSThread::kInvalidThreadId); |
| 315 #endif // defined(DEBUG) |
| 316 |
307 int result = pthread_mutex_destroy(data_.mutex()); | 317 int result = pthread_mutex_destroy(data_.mutex()); |
308 VALIDATE_PTHREAD_RESULT(result); | 318 VALIDATE_PTHREAD_RESULT(result); |
309 | 319 |
310 result = pthread_cond_destroy(data_.cond()); | 320 result = pthread_cond_destroy(data_.cond()); |
311 VALIDATE_PTHREAD_RESULT(result); | 321 VALIDATE_PTHREAD_RESULT(result); |
312 } | 322 } |
313 | 323 |
314 | 324 |
315 void Monitor::Enter() { | 325 void Monitor::Enter() { |
316 int result = pthread_mutex_lock(data_.mutex()); | 326 int result = pthread_mutex_lock(data_.mutex()); |
317 VALIDATE_PTHREAD_RESULT(result); | 327 VALIDATE_PTHREAD_RESULT(result); |
318 // TODO(iposva): Do we need to track lock owners? | 328 |
| 329 #if defined(DEBUG) |
| 330 // When running with assertions enabled we track the owner. |
| 331 ASSERT(owner_ == OSThread::kInvalidThreadId); |
| 332 owner_ = OSThread::GetCurrentThreadId(); |
| 333 #endif // defined(DEBUG) |
319 } | 334 } |
320 | 335 |
321 | 336 |
322 void Monitor::Exit() { | 337 void Monitor::Exit() { |
323 // TODO(iposva): Do we need to track lock owners? | 338 #if defined(DEBUG) |
| 339 // When running with assertions enabled we track the owner. |
| 340 ASSERT(IsOwnedByCurrentThread()); |
| 341 owner_ = OSThread::kInvalidThreadId; |
| 342 #endif // defined(DEBUG) |
| 343 |
324 int result = pthread_mutex_unlock(data_.mutex()); | 344 int result = pthread_mutex_unlock(data_.mutex()); |
325 VALIDATE_PTHREAD_RESULT(result); | 345 VALIDATE_PTHREAD_RESULT(result); |
326 } | 346 } |
327 | 347 |
328 | 348 |
329 Monitor::WaitResult Monitor::Wait(int64_t millis) { | 349 Monitor::WaitResult Monitor::Wait(int64_t millis) { |
330 return WaitMicros(millis * kMicrosecondsPerMillisecond); | 350 return WaitMicros(millis * kMicrosecondsPerMillisecond); |
331 } | 351 } |
332 | 352 |
333 | 353 |
334 Monitor::WaitResult Monitor::WaitMicros(int64_t micros) { | 354 Monitor::WaitResult Monitor::WaitMicros(int64_t micros) { |
335 // TODO(iposva): Do we need to track lock owners? | 355 #if defined(DEBUG) |
| 356 // When running with assertions enabled we track the owner. |
| 357 ASSERT(IsOwnedByCurrentThread()); |
| 358 ThreadId saved_owner = owner_; |
| 359 owner_ = OSThread::kInvalidThreadId; |
| 360 #endif // defined(DEBUG) |
| 361 |
336 Monitor::WaitResult retval = kNotified; | 362 Monitor::WaitResult retval = kNotified; |
337 if (micros == kNoTimeout) { | 363 if (micros == kNoTimeout) { |
338 // Wait forever. | 364 // Wait forever. |
339 int result = pthread_cond_wait(data_.cond(), data_.mutex()); | 365 int result = pthread_cond_wait(data_.cond(), data_.mutex()); |
340 VALIDATE_PTHREAD_RESULT(result); | 366 VALIDATE_PTHREAD_RESULT(result); |
341 } else { | 367 } else { |
342 struct timespec ts; | 368 struct timespec ts; |
343 int64_t secs = micros / kMicrosecondsPerSecond; | 369 int64_t secs = micros / kMicrosecondsPerSecond; |
344 if (secs > kMaxInt32) { | 370 if (secs > kMaxInt32) { |
345 // Avoid truncation of overly large timeout values. | 371 // Avoid truncation of overly large timeout values. |
346 secs = kMaxInt32; | 372 secs = kMaxInt32; |
347 } | 373 } |
348 int64_t nanos = | 374 int64_t nanos = |
349 (micros - (secs * kMicrosecondsPerSecond)) * kNanosecondsPerMicrosecond; | 375 (micros - (secs * kMicrosecondsPerSecond)) * kNanosecondsPerMicrosecond; |
350 ts.tv_sec = static_cast<int32_t>(secs); | 376 ts.tv_sec = static_cast<int32_t>(secs); |
351 ts.tv_nsec = static_cast<long>(nanos); // NOLINT (long used in timespec). | 377 ts.tv_nsec = static_cast<long>(nanos); // NOLINT (long used in timespec). |
352 int result = pthread_cond_timedwait_relative_np(data_.cond(), | 378 int result = pthread_cond_timedwait_relative_np(data_.cond(), |
353 data_.mutex(), | 379 data_.mutex(), |
354 &ts); | 380 &ts); |
355 ASSERT((result == 0) || (result == ETIMEDOUT)); | 381 ASSERT((result == 0) || (result == ETIMEDOUT)); |
356 if (result == ETIMEDOUT) { | 382 if (result == ETIMEDOUT) { |
357 retval = kTimedOut; | 383 retval = kTimedOut; |
358 } | 384 } |
359 } | 385 } |
| 386 |
| 387 #if defined(DEBUG) |
| 388 // When running with assertions enabled we track the owner. |
| 389 ASSERT(owner_ == OSThread::kInvalidThreadId); |
| 390 owner_ = OSThread::GetCurrentThreadId(); |
| 391 ASSERT(owner_ == saved_owner); |
| 392 #endif // defined(DEBUG) |
360 return retval; | 393 return retval; |
361 } | 394 } |
362 | 395 |
363 | 396 |
364 void Monitor::Notify() { | 397 void Monitor::Notify() { |
365 // TODO(iposva): Do we need to track lock owners? | 398 // When running with assertions enabled we track the owner. |
| 399 ASSERT(IsOwnedByCurrentThread()); |
366 int result = pthread_cond_signal(data_.cond()); | 400 int result = pthread_cond_signal(data_.cond()); |
367 VALIDATE_PTHREAD_RESULT(result); | 401 VALIDATE_PTHREAD_RESULT(result); |
368 } | 402 } |
369 | 403 |
370 | 404 |
371 void Monitor::NotifyAll() { | 405 void Monitor::NotifyAll() { |
372 // TODO(iposva): Do we need to track lock owners? | 406 // When running with assertions enabled we track the owner. |
| 407 ASSERT(IsOwnedByCurrentThread()); |
373 int result = pthread_cond_broadcast(data_.cond()); | 408 int result = pthread_cond_broadcast(data_.cond()); |
374 VALIDATE_PTHREAD_RESULT(result); | 409 VALIDATE_PTHREAD_RESULT(result); |
375 } | 410 } |
376 | 411 |
377 } // namespace dart | 412 } // namespace dart |
378 | 413 |
379 #endif // defined(TARGET_OS_MACOS) | 414 #endif // defined(TARGET_OS_MACOS) |
OLD | NEW |