| // Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| #include "platform/globals.h" // NOLINT |
| #if defined(DART_HOST_OS_WINDOWS) && !defined(DART_USE_ABSL) |
| |
| #include "platform/synchronization.h" |
| |
| #include <process.h> // NOLINT |
| |
| #include "platform/address_sanitizer.h" |
| #include "platform/assert.h" |
| #include "platform/safe_stack.h" |
| |
| namespace dart { |
| |
| Mutex::Mutex() { |
| InitializeSRWLock(&mutex_); |
| } |
| |
| Mutex::~Mutex() {} |
| |
| void Mutex::Lock() { |
| DEBUG_ASSERT(!DisallowMutexLockingScope::is_active()); |
| |
| AcquireSRWLockExclusive(&mutex_); |
| owner_.Acquire(); |
| } |
| |
| bool Mutex::TryLock() { |
| DEBUG_ASSERT(!DisallowMutexLockingScope::is_active()); |
| |
| if (TryAcquireSRWLockExclusive(&mutex_) != 0) { |
| owner_.Acquire(); |
| return true; |
| } |
| return false; |
| } |
| |
| void Mutex::Unlock() { |
| owner_.Release(); |
| ReleaseSRWLockExclusive(&mutex_); |
| } |
| |
| ConditionVariable::ConditionVariable() { |
| InitializeConditionVariable(&cv_); |
| } |
| |
| ConditionVariable::~ConditionVariable() {} |
| |
| ConditionVariable::WaitResult ConditionVariable::Wait(Mutex* mutex, |
| int64_t timeout_millis) { |
| mutex->owner_.Release(); |
| Monitor::WaitResult retval = kNotified; |
| if (timeout_millis == kNoTimeout) { |
| SleepConditionVariableSRW(&cv_, &mutex->mutex_, INFINITE, 0); |
| } else { |
| // Wait for the given period of time for a Notify or a NotifyAll |
| // event. |
| if (!SleepConditionVariableSRW(&cv_, &mutex->mutex_, timeout_millis, 0)) { |
| ASSERT(GetLastError() == ERROR_TIMEOUT); |
| retval = kTimedOut; |
| } |
| } |
| mutex->owner_.Acquire(); |
| return retval; |
| } |
| |
| ConditionVariable::WaitResult ConditionVariable::WaitMicros(Mutex* mutex, |
| int64_t micros) { |
| // TODO(johnmccutchan): Investigate sub-millisecond sleep times on Windows. |
| int64_t millis = micros / kMicrosecondsPerMillisecond; |
| if ((millis * kMicrosecondsPerMillisecond) < micros) { |
| // We've been asked to sleep for a fraction of a millisecond, |
| // this isn't supported on Windows. Bumps milliseconds up by one |
| // so that we never return too early. We likely return late though. |
| millis += 1; |
| } |
| return Wait(mutex, millis); |
| } |
| |
| void ConditionVariable::Notify() { |
| WakeConditionVariable(&cv_); |
| } |
| |
| void ConditionVariable::NotifyAll() { |
| WakeAllConditionVariable(&cv_); |
| } |
| |
| } // namespace dart |
| |
| #endif // defined(DART_HOST_OS_WINDOWS) && !defined(DART_USE_ABSL) |