Flutter Engine
The Flutter Engine
thread_win.cc
Go to the documentation of this 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
3// BSD-style license that can be found in the LICENSE file.
4
5#include "platform/globals.h"
6#if defined(DART_HOST_OS_WINDOWS) && !defined(DART_USE_ABSL)
7
8#include "bin/thread.h"
9#include "bin/thread_win.h"
10
11#include <process.h> // NOLINT
12
13#include "platform/assert.h"
14
15namespace dart {
16namespace bin {
17
18class ThreadStartData {
19 public:
20 ThreadStartData(const char* name,
22 uword parameter)
23 : name_(name), function_(function), parameter_(parameter) {}
24
25 const char* name() const { return name_; }
26 Thread::ThreadStartFunction function() const { return function_; }
27 uword parameter() const { return parameter_; }
28
29 private:
30 const char* name_;
32 uword parameter_;
33
34 DISALLOW_COPY_AND_ASSIGN(ThreadStartData);
35};
36
37// Dispatch to the thread start function provided by the caller. This trampoline
38// is used to ensure that the thread is properly destroyed if the thread just
39// exits.
40static unsigned int __stdcall ThreadEntry(void* data_ptr) {
41 ThreadStartData* data = reinterpret_cast<ThreadStartData*>(data_ptr);
42
44 uword parameter = data->parameter();
45 delete data;
46
47 // Call the supplied thread start function handing it its parameters.
48 function(parameter);
49
50 return 0;
51}
52
53int Thread::Start(const char* name,
54 ThreadStartFunction function,
55 uword parameter) {
56 ThreadStartData* start_data = new ThreadStartData(name, function, parameter);
57 uint32_t tid;
58 uintptr_t thread = _beginthreadex(nullptr, Thread::GetMaxStackSize(),
59 ThreadEntry, start_data, 0, &tid);
60 if ((thread == -1L) || (thread == 0)) {
61#ifdef DEBUG
62 fprintf(stderr, "_beginthreadex error: %d (%s)\n", errno, strerror(errno));
63#endif
64 return errno;
65 }
66
67 // Close the handle, so we don't leak the thread object.
68 CloseHandle(reinterpret_cast<HANDLE>(thread));
69
70 return 0;
71}
72
74
75intptr_t Thread::GetMaxStackSize() {
76 const int kStackSize = (128 * kWordSize * KB);
77 return kStackSize;
78}
79
81 return ::GetCurrentThreadId();
82}
83
85 return (a == b);
86}
87
89 InitializeSRWLock(&data_.lock_);
90}
91
93
94void Mutex::Lock() {
95 AcquireSRWLockExclusive(&data_.lock_);
96}
97
98bool Mutex::TryLock() {
99 if (TryAcquireSRWLockExclusive(&data_.lock_) != 0) {
100 return true;
101 }
102 return false;
103}
104
105void Mutex::Unlock() {
106 ReleaseSRWLockExclusive(&data_.lock_);
107}
108
110 InitializeCriticalSection(&data_.cs_);
111 InitializeConditionVariable(&data_.cond_);
112}
113
115 DeleteCriticalSection(&data_.cs_);
116}
117
118void Monitor::Enter() {
119 EnterCriticalSection(&data_.cs_);
120}
121
122void Monitor::Exit() {
123 LeaveCriticalSection(&data_.cs_);
124}
125
126Monitor::WaitResult Monitor::Wait(int64_t millis) {
128 if (millis == kNoTimeout) {
129 SleepConditionVariableCS(&data_.cond_, &data_.cs_, INFINITE);
130 } else {
131 // Wait for the given period of time for a Notify or a NotifyAll
132 // event.
133 if (!SleepConditionVariableCS(&data_.cond_, &data_.cs_, millis)) {
134 ASSERT(GetLastError() == ERROR_TIMEOUT);
135 retval = kTimedOut;
136 }
137 }
138
139 return retval;
140}
141
143 // TODO(johnmccutchan): Investigate sub-millisecond sleep times on Windows.
144 int64_t millis = micros / kMicrosecondsPerMillisecond;
145 if ((millis * kMicrosecondsPerMillisecond) < micros) {
146 // We've been asked to sleep for a fraction of a millisecond,
147 // this isn't supported on Windows. Bumps milliseconds up by one
148 // so that we never return too early. We likely return late though.
149 millis += 1;
150 }
151 return Wait(millis);
152}
153
154void Monitor::Notify() {
155 WakeConditionVariable(&data_.cond_);
156}
157
158void Monitor::NotifyAll() {
159 WakeAllConditionVariable(&data_.cond_);
160}
161
162} // namespace bin
163} // namespace dart
164
165#endif // defined(DART_HOST_OS_WINDOWS) && !defined(DART_USE_ABSL)
static constexpr int64_t kNoTimeout
Definition: thread.h:79
WaitResult Wait(int64_t millis)
WaitResult WaitMicros(int64_t micros)
static const ThreadId kInvalidThreadId
Definition: thread.h:38
void(* ThreadStartFunction)(uword parameter)
Definition: thread.h:40
static intptr_t GetMaxStackSize()
static int Start(const char *name, ThreadStartFunction function, uword parameters)
static bool Compare(ThreadId a, ThreadId b)
static ThreadId GetCurrentThreadId()
#define ASSERT(E)
static bool b
struct MyStruct a[10]
Dart_NativeFunction function
Definition: fuchsia.cc:51
pthread_t ThreadId
Definition: thread_absl.h:21
Definition: dart_vm.cc:33
constexpr intptr_t kMicrosecondsPerMillisecond
Definition: globals.h:561
const char *const name
constexpr intptr_t KB
Definition: globals.h:528
uintptr_t uword
Definition: globals.h:501
constexpr intptr_t kWordSize
Definition: globals.h:509
static int8_t data[kExtLength]
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: globals.h:581
WINBASEAPI BOOLEAN WINAPI TryAcquireSRWLockExclusive(_Inout_ PSRWLOCK SRWLock)
WINBASEAPI _Releases_exclusive_lock_ SRWLock VOID WINAPI ReleaseSRWLockExclusive(_Inout_ PSRWLOCK SRWLock)
WINBASEAPI _Check_return_ _Post_equals_last_error_ DWORD WINAPI GetLastError(VOID)
void * HANDLE
Definition: windows_types.h:36