| 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 |