| 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_WINDOWS) | 6 #if defined(TARGET_OS_WINDOWS) |
| 7 | 7 |
| 8 #include "vm/growable_array.h" | 8 #include "vm/growable_array.h" |
| 9 #include "vm/os_thread.h" | 9 #include "vm/os_thread.h" |
| 10 | 10 |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 191 } | 191 } |
| 192 } | 192 } |
| 193 | 193 |
| 194 | 194 |
| 195 Mutex::Mutex() { | 195 Mutex::Mutex() { |
| 196 // Allocate unnamed semaphore with initial count 1 and max count 1. | 196 // Allocate unnamed semaphore with initial count 1 and max count 1. |
| 197 data_.semaphore_ = CreateSemaphore(NULL, 1, 1, NULL); | 197 data_.semaphore_ = CreateSemaphore(NULL, 1, 1, NULL); |
| 198 if (data_.semaphore_ == NULL) { | 198 if (data_.semaphore_ == NULL) { |
| 199 FATAL1("Mutex allocation failed %d", GetLastError()); | 199 FATAL1("Mutex allocation failed %d", GetLastError()); |
| 200 } | 200 } |
| 201 #if defined(DEBUG) |
| 201 // When running with assertions enabled we do track the owner. | 202 // When running with assertions enabled we do track the owner. |
| 202 #if defined(DEBUG) | |
| 203 owner_ = OSThread::kInvalidThreadId; | 203 owner_ = OSThread::kInvalidThreadId; |
| 204 #endif // defined(DEBUG) | 204 #endif // defined(DEBUG) |
| 205 } | 205 } |
| 206 | 206 |
| 207 | 207 |
| 208 Mutex::~Mutex() { | 208 Mutex::~Mutex() { |
| 209 CloseHandle(data_.semaphore_); | 209 CloseHandle(data_.semaphore_); |
| 210 #if defined(DEBUG) |
| 210 // When running with assertions enabled we do track the owner. | 211 // When running with assertions enabled we do track the owner. |
| 211 #if defined(DEBUG) | |
| 212 ASSERT(owner_ == OSThread::kInvalidThreadId); | 212 ASSERT(owner_ == OSThread::kInvalidThreadId); |
| 213 #endif // defined(DEBUG) | 213 #endif // defined(DEBUG) |
| 214 } | 214 } |
| 215 | 215 |
| 216 | 216 |
| 217 void Mutex::Lock() { | 217 void Mutex::Lock() { |
| 218 DWORD result = WaitForSingleObject(data_.semaphore_, INFINITE); | 218 DWORD result = WaitForSingleObject(data_.semaphore_, INFINITE); |
| 219 if (result != WAIT_OBJECT_0) { | 219 if (result != WAIT_OBJECT_0) { |
| 220 FATAL1("Mutex lock failed %d", GetLastError()); | 220 FATAL1("Mutex lock failed %d", GetLastError()); |
| 221 } | 221 } |
| 222 #if defined(DEBUG) |
| 222 // When running with assertions enabled we do track the owner. | 223 // When running with assertions enabled we do track the owner. |
| 223 #if defined(DEBUG) | |
| 224 owner_ = OSThread::GetCurrentThreadId(); | 224 owner_ = OSThread::GetCurrentThreadId(); |
| 225 #endif // defined(DEBUG) | 225 #endif // defined(DEBUG) |
| 226 } | 226 } |
| 227 | 227 |
| 228 | 228 |
| 229 bool Mutex::TryLock() { | 229 bool Mutex::TryLock() { |
| 230 // Attempt to pass the semaphore but return immediately. | 230 // Attempt to pass the semaphore but return immediately. |
| 231 DWORD result = WaitForSingleObject(data_.semaphore_, 0); | 231 DWORD result = WaitForSingleObject(data_.semaphore_, 0); |
| 232 if (result == WAIT_OBJECT_0) { | 232 if (result == WAIT_OBJECT_0) { |
| 233 #if defined(DEBUG) |
| 233 // When running with assertions enabled we do track the owner. | 234 // When running with assertions enabled we do track the owner. |
| 234 #if defined(DEBUG) | |
| 235 owner_ = OSThread::GetCurrentThreadId(); | 235 owner_ = OSThread::GetCurrentThreadId(); |
| 236 #endif // defined(DEBUG) | 236 #endif // defined(DEBUG) |
| 237 return true; | 237 return true; |
| 238 } | 238 } |
| 239 if (result == WAIT_ABANDONED || result == WAIT_FAILED) { | 239 if (result == WAIT_ABANDONED || result == WAIT_FAILED) { |
| 240 FATAL1("Mutex try lock failed %d", GetLastError()); | 240 FATAL1("Mutex try lock failed %d", GetLastError()); |
| 241 } | 241 } |
| 242 ASSERT(result == WAIT_TIMEOUT); | 242 ASSERT(result == WAIT_TIMEOUT); |
| 243 return false; | 243 return false; |
| 244 } | 244 } |
| 245 | 245 |
| 246 | 246 |
| 247 void Mutex::Unlock() { | 247 void Mutex::Unlock() { |
| 248 #if defined(DEBUG) |
| 248 // When running with assertions enabled we do track the owner. | 249 // When running with assertions enabled we do track the owner. |
| 249 #if defined(DEBUG) | |
| 250 ASSERT(IsOwnedByCurrentThread()); | 250 ASSERT(IsOwnedByCurrentThread()); |
| 251 owner_ = OSThread::kInvalidThreadId; | 251 owner_ = OSThread::kInvalidThreadId; |
| 252 #endif // defined(DEBUG) | 252 #endif // defined(DEBUG) |
| 253 BOOL result = ReleaseSemaphore(data_.semaphore_, 1, NULL); | 253 BOOL result = ReleaseSemaphore(data_.semaphore_, 1, NULL); |
| 254 if (result == 0) { | 254 if (result == 0) { |
| 255 FATAL1("Mutex unlock failed %d", GetLastError()); | 255 FATAL1("Mutex unlock failed %d", GetLastError()); |
| 256 } | 256 } |
| 257 } | 257 } |
| 258 | 258 |
| 259 | 259 |
| 260 ThreadLocalKey MonitorWaitData::monitor_wait_data_key_ = | 260 ThreadLocalKey MonitorWaitData::monitor_wait_data_key_ = |
| 261 OSThread::kUnsetThreadLocalKey; | 261 OSThread::kUnsetThreadLocalKey; |
| 262 | 262 |
| 263 | 263 |
| 264 Monitor::Monitor() { | 264 Monitor::Monitor() { |
| 265 InitializeCriticalSection(&data_.cs_); | 265 InitializeCriticalSection(&data_.cs_); |
| 266 InitializeCriticalSection(&data_.waiters_cs_); | 266 InitializeCriticalSection(&data_.waiters_cs_); |
| 267 data_.waiters_head_ = NULL; | 267 data_.waiters_head_ = NULL; |
| 268 data_.waiters_tail_ = NULL; | 268 data_.waiters_tail_ = NULL; |
| 269 |
| 270 #if defined(DEBUG) |
| 271 // When running with assertions enabled we track the owner. |
| 272 owner_ = OSThread::kInvalidThreadId; |
| 273 #endif // defined(DEBUG) |
| 269 } | 274 } |
| 270 | 275 |
| 271 | 276 |
| 272 Monitor::~Monitor() { | 277 Monitor::~Monitor() { |
| 278 #if defined(DEBUG) |
| 279 // When running with assertions enabled we track the owner. |
| 280 ASSERT(owner_ == OSThread::kInvalidThreadId); |
| 281 #endif // defined(DEBUG) |
| 282 |
| 273 DeleteCriticalSection(&data_.cs_); | 283 DeleteCriticalSection(&data_.cs_); |
| 274 DeleteCriticalSection(&data_.waiters_cs_); | 284 DeleteCriticalSection(&data_.waiters_cs_); |
| 275 } | 285 } |
| 276 | 286 |
| 277 | 287 |
| 278 void Monitor::Enter() { | 288 void Monitor::Enter() { |
| 279 EnterCriticalSection(&data_.cs_); | 289 EnterCriticalSection(&data_.cs_); |
| 290 |
| 291 #if defined(DEBUG) |
| 292 // When running with assertions enabled we track the owner. |
| 293 ASSERT(owner_ == OSThread::kInvalidThreadId); |
| 294 owner_ = OSThread::GetCurrentThreadId(); |
| 295 #endif // defined(DEBUG) |
| 280 } | 296 } |
| 281 | 297 |
| 282 | 298 |
| 283 void Monitor::Exit() { | 299 void Monitor::Exit() { |
| 300 #if defined(DEBUG) |
| 301 // When running with assertions enabled we track the owner. |
| 302 ASSERT(IsOwnedByCurrentThread()); |
| 303 owner_ = OSThread::kInvalidThreadId; |
| 304 #endif // defined(DEBUG) |
| 305 |
| 284 LeaveCriticalSection(&data_.cs_); | 306 LeaveCriticalSection(&data_.cs_); |
| 285 } | 307 } |
| 286 | 308 |
| 287 | 309 |
| 288 void MonitorWaitData::ThreadExit() { | 310 void MonitorWaitData::ThreadExit() { |
| 289 if (MonitorWaitData::monitor_wait_data_key_ != | 311 if (MonitorWaitData::monitor_wait_data_key_ != |
| 290 OSThread::kUnsetThreadLocalKey) { | 312 OSThread::kUnsetThreadLocalKey) { |
| 291 uword raw_wait_data = | 313 uword raw_wait_data = |
| 292 OSThread::GetThreadLocal(MonitorWaitData::monitor_wait_data_key_); | 314 OSThread::GetThreadLocal(MonitorWaitData::monitor_wait_data_key_); |
| 293 // Clear in case this is called a second time. | 315 // Clear in case this is called a second time. |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 reinterpret_cast<uword>(wait_data)); | 432 reinterpret_cast<uword>(wait_data)); |
| 411 } else { | 433 } else { |
| 412 wait_data = reinterpret_cast<MonitorWaitData*>(raw_wait_data); | 434 wait_data = reinterpret_cast<MonitorWaitData*>(raw_wait_data); |
| 413 wait_data->next_ = NULL; | 435 wait_data->next_ = NULL; |
| 414 } | 436 } |
| 415 return wait_data; | 437 return wait_data; |
| 416 } | 438 } |
| 417 | 439 |
| 418 | 440 |
| 419 Monitor::WaitResult Monitor::Wait(int64_t millis) { | 441 Monitor::WaitResult Monitor::Wait(int64_t millis) { |
| 442 #if defined(DEBUG) |
| 443 // When running with assertions enabled we track the owner. |
| 444 ASSERT(IsOwnedByCurrentThread()); |
| 445 ThreadId saved_owner = owner_; |
| 446 owner_ = OSThread::kInvalidThreadId; |
| 447 #endif // defined(DEBUG) |
| 448 |
| 420 Monitor::WaitResult retval = kNotified; | 449 Monitor::WaitResult retval = kNotified; |
| 421 | 450 |
| 422 // Get the wait data object containing the event to wait for. | 451 // Get the wait data object containing the event to wait for. |
| 423 MonitorWaitData* wait_data = MonitorData::GetMonitorWaitDataForThread(); | 452 MonitorWaitData* wait_data = MonitorData::GetMonitorWaitDataForThread(); |
| 424 | 453 |
| 425 // Start waiting by adding the MonitorWaitData to the list of | 454 // Start waiting by adding the MonitorWaitData to the list of |
| 426 // waiters. | 455 // waiters. |
| 427 data_.AddWaiter(wait_data); | 456 data_.AddWaiter(wait_data); |
| 428 | 457 |
| 429 // Leave the monitor critical section while waiting. | 458 // Leave the monitor critical section while waiting. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 447 if (result == WAIT_TIMEOUT) { | 476 if (result == WAIT_TIMEOUT) { |
| 448 // No longer waiting. Remove from the list of waiters. | 477 // No longer waiting. Remove from the list of waiters. |
| 449 data_.RemoveWaiter(wait_data); | 478 data_.RemoveWaiter(wait_data); |
| 450 retval = kTimedOut; | 479 retval = kTimedOut; |
| 451 } | 480 } |
| 452 } | 481 } |
| 453 | 482 |
| 454 // Reacquire the monitor critical section before continuing. | 483 // Reacquire the monitor critical section before continuing. |
| 455 EnterCriticalSection(&data_.cs_); | 484 EnterCriticalSection(&data_.cs_); |
| 456 | 485 |
| 486 #if defined(DEBUG) |
| 487 // When running with assertions enabled we track the owner. |
| 488 ASSERT(owner_ == OSThread::kInvalidThreadId); |
| 489 owner_ = OSThread::GetCurrentThreadId(); |
| 490 ASSERT(owner_ == saved_owner); |
| 491 #endif // defined(DEBUG) |
| 457 return retval; | 492 return retval; |
| 458 } | 493 } |
| 459 | 494 |
| 460 | 495 |
| 461 Monitor::WaitResult Monitor::WaitMicros(int64_t micros) { | 496 Monitor::WaitResult Monitor::WaitMicros(int64_t micros) { |
| 462 // TODO(johnmccutchan): Investigate sub-millisecond sleep times on Windows. | 497 // TODO(johnmccutchan): Investigate sub-millisecond sleep times on Windows. |
| 463 int64_t millis = micros / kMicrosecondsPerMillisecond; | 498 int64_t millis = micros / kMicrosecondsPerMillisecond; |
| 464 if ((millis * kMicrosecondsPerMillisecond) < micros) { | 499 if ((millis * kMicrosecondsPerMillisecond) < micros) { |
| 465 // We've been asked to sleep for a fraction of a millisecond, | 500 // We've been asked to sleep for a fraction of a millisecond, |
| 466 // this isn't supported on Windows. Bumps milliseconds up by one | 501 // this isn't supported on Windows. Bumps milliseconds up by one |
| 467 // so that we never return too early. We likely return late though. | 502 // so that we never return too early. We likely return late though. |
| 468 millis += 1; | 503 millis += 1; |
| 469 } | 504 } |
| 470 return Wait(millis); | 505 return Wait(millis); |
| 471 } | 506 } |
| 472 | 507 |
| 473 | 508 |
| 474 void Monitor::Notify() { | 509 void Monitor::Notify() { |
| 510 // When running with assertions enabled we track the owner. |
| 511 ASSERT(IsOwnedByCurrentThread()); |
| 475 data_.SignalAndRemoveFirstWaiter(); | 512 data_.SignalAndRemoveFirstWaiter(); |
| 476 } | 513 } |
| 477 | 514 |
| 478 | 515 |
| 479 void Monitor::NotifyAll() { | 516 void Monitor::NotifyAll() { |
| 517 // When running with assertions enabled we track the owner. |
| 518 ASSERT(IsOwnedByCurrentThread()); |
| 480 // If one of the objects in the list of waiters wakes because of a | 519 // If one of the objects in the list of waiters wakes because of a |
| 481 // timeout before we signal it, that object will get an extra | 520 // timeout before we signal it, that object will get an extra |
| 482 // signal. This will be treated as a spurious wake-up and is OK | 521 // signal. This will be treated as a spurious wake-up and is OK |
| 483 // since all uses of monitors should recheck the condition after a | 522 // since all uses of monitors should recheck the condition after a |
| 484 // Wait. | 523 // Wait. |
| 485 data_.SignalAndRemoveAllWaiters(); | 524 data_.SignalAndRemoveAllWaiters(); |
| 486 } | 525 } |
| 487 | 526 |
| 488 | 527 |
| 489 void ThreadLocalData::AddThreadLocal(ThreadLocalKey key, | 528 void ThreadLocalData::AddThreadLocal(ThreadLocalKey key, |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 638 #pragma data_seg(".CRT$XLB") | 677 #pragma data_seg(".CRT$XLB") |
| 639 PIMAGE_TLS_CALLBACK p_thread_callback_dart = OnDartThreadExit; | 678 PIMAGE_TLS_CALLBACK p_thread_callback_dart = OnDartThreadExit; |
| 640 | 679 |
| 641 // Reset the default section. | 680 // Reset the default section. |
| 642 #pragma data_seg() | 681 #pragma data_seg() |
| 643 | 682 |
| 644 #endif // _WIN64 | 683 #endif // _WIN64 |
| 645 } // extern "C" | 684 } // extern "C" |
| 646 | 685 |
| 647 #endif // defined(TARGET_OS_WINDOWS) | 686 #endif // defined(TARGET_OS_WINDOWS) |
| OLD | NEW |