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 owner_ = OSThread::kInvalidThreadId; | |
446 #endif // defined(DEBUG) | |
447 | |
420 Monitor::WaitResult retval = kNotified; | 448 Monitor::WaitResult retval = kNotified; |
421 | 449 |
422 // Get the wait data object containing the event to wait for. | 450 // Get the wait data object containing the event to wait for. |
423 MonitorWaitData* wait_data = MonitorData::GetMonitorWaitDataForThread(); | 451 MonitorWaitData* wait_data = MonitorData::GetMonitorWaitDataForThread(); |
424 | 452 |
425 // Start waiting by adding the MonitorWaitData to the list of | 453 // Start waiting by adding the MonitorWaitData to the list of |
426 // waiters. | 454 // waiters. |
427 data_.AddWaiter(wait_data); | 455 data_.AddWaiter(wait_data); |
428 | 456 |
429 // Leave the monitor critical section while waiting. | 457 // Leave the monitor critical section while waiting. |
(...skipping 17 matching lines...) Expand all Loading... | |
447 if (result == WAIT_TIMEOUT) { | 475 if (result == WAIT_TIMEOUT) { |
448 // No longer waiting. Remove from the list of waiters. | 476 // No longer waiting. Remove from the list of waiters. |
449 data_.RemoveWaiter(wait_data); | 477 data_.RemoveWaiter(wait_data); |
450 retval = kTimedOut; | 478 retval = kTimedOut; |
451 } | 479 } |
452 } | 480 } |
453 | 481 |
454 // Reacquire the monitor critical section before continuing. | 482 // Reacquire the monitor critical section before continuing. |
455 EnterCriticalSection(&data_.cs_); | 483 EnterCriticalSection(&data_.cs_); |
456 | 484 |
485 #if defined(DEBUG) | |
486 // When running with assertions enabled we track the owner. | |
487 ASSERT(owner_ == OSThread::kInvalidThreadId); | |
488 owner_ = OSThread::GetCurrentThreadId(); | |
srdjan
2015/10/26 23:02:11
ditto
siva
2015/10/27 00:14:57
Done.
| |
489 #endif // defined(DEBUG) | |
457 return retval; | 490 return retval; |
458 } | 491 } |
459 | 492 |
460 | 493 |
461 Monitor::WaitResult Monitor::WaitMicros(int64_t micros) { | 494 Monitor::WaitResult Monitor::WaitMicros(int64_t micros) { |
462 // TODO(johnmccutchan): Investigate sub-millisecond sleep times on Windows. | 495 // TODO(johnmccutchan): Investigate sub-millisecond sleep times on Windows. |
463 int64_t millis = micros / kMicrosecondsPerMillisecond; | 496 int64_t millis = micros / kMicrosecondsPerMillisecond; |
464 if ((millis * kMicrosecondsPerMillisecond) < micros) { | 497 if ((millis * kMicrosecondsPerMillisecond) < micros) { |
465 // We've been asked to sleep for a fraction of a millisecond, | 498 // We've been asked to sleep for a fraction of a millisecond, |
466 // this isn't supported on Windows. Bumps milliseconds up by one | 499 // this isn't supported on Windows. Bumps milliseconds up by one |
467 // so that we never return too early. We likely return late though. | 500 // so that we never return too early. We likely return late though. |
468 millis += 1; | 501 millis += 1; |
469 } | 502 } |
470 return Wait(millis); | 503 return Wait(millis); |
471 } | 504 } |
472 | 505 |
473 | 506 |
474 void Monitor::Notify() { | 507 void Monitor::Notify() { |
508 #if defined(DEBUG) | |
509 // When running with assertions enabled we track the owner. | |
510 ASSERT(IsOwnedByCurrentThread()); | |
Cutch
2015/10/26 23:00:50
#if defined(DEBUG) is redundant with ASSERT.
siva
2015/10/27 00:14:57
Done.
| |
511 #endif // defined(DEBUG) | |
512 | |
475 data_.SignalAndRemoveFirstWaiter(); | 513 data_.SignalAndRemoveFirstWaiter(); |
476 } | 514 } |
477 | 515 |
478 | 516 |
479 void Monitor::NotifyAll() { | 517 void Monitor::NotifyAll() { |
518 #if defined(DEBUG) | |
Cutch
2015/10/26 23:00:50
#if defined(DEBUG) is redundant with ASSERT.
siva
2015/10/27 00:14:57
Done.
| |
519 // When running with assertions enabled we track the owner. | |
520 ASSERT(IsOwnedByCurrentThread()); | |
521 #endif // defined(DEBUG) | |
522 | |
480 // If one of the objects in the list of waiters wakes because of a | 523 // 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 | 524 // 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 | 525 // 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 | 526 // since all uses of monitors should recheck the condition after a |
484 // Wait. | 527 // Wait. |
485 data_.SignalAndRemoveAllWaiters(); | 528 data_.SignalAndRemoveAllWaiters(); |
486 } | 529 } |
487 | 530 |
488 | 531 |
489 void ThreadLocalData::AddThreadLocal(ThreadLocalKey key, | 532 void ThreadLocalData::AddThreadLocal(ThreadLocalKey key, |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
638 #pragma data_seg(".CRT$XLB") | 681 #pragma data_seg(".CRT$XLB") |
639 PIMAGE_TLS_CALLBACK p_thread_callback_dart = OnDartThreadExit; | 682 PIMAGE_TLS_CALLBACK p_thread_callback_dart = OnDartThreadExit; |
640 | 683 |
641 // Reset the default section. | 684 // Reset the default section. |
642 #pragma data_seg() | 685 #pragma data_seg() |
643 | 686 |
644 #endif // _WIN64 | 687 #endif // _WIN64 |
645 } // extern "C" | 688 } // extern "C" |
646 | 689 |
647 #endif // defined(TARGET_OS_WINDOWS) | 690 #endif // defined(TARGET_OS_WINDOWS) |
OLD | NEW |