| 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" | 5 #include "platform/globals.h" |
| 6 #if defined(HOST_OS_WINDOWS) | 6 #if defined(HOST_OS_WINDOWS) |
| 7 | 7 |
| 8 #include "bin/thread.h" | 8 #include "bin/thread.h" |
| 9 #include "bin/thread_win.h" | 9 #include "bin/thread_win.h" |
| 10 | 10 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 Thread::ThreadStartFunction function() const { return function_; } | 23 Thread::ThreadStartFunction function() const { return function_; } |
| 24 uword parameter() const { return parameter_; } | 24 uword parameter() const { return parameter_; } |
| 25 | 25 |
| 26 private: | 26 private: |
| 27 Thread::ThreadStartFunction function_; | 27 Thread::ThreadStartFunction function_; |
| 28 uword parameter_; | 28 uword parameter_; |
| 29 | 29 |
| 30 DISALLOW_COPY_AND_ASSIGN(ThreadStartData); | 30 DISALLOW_COPY_AND_ASSIGN(ThreadStartData); |
| 31 }; | 31 }; |
| 32 | 32 |
| 33 | |
| 34 // Dispatch to the thread start function provided by the caller. This trampoline | 33 // Dispatch to the thread start function provided by the caller. This trampoline |
| 35 // is used to ensure that the thread is properly destroyed if the thread just | 34 // is used to ensure that the thread is properly destroyed if the thread just |
| 36 // exits. | 35 // exits. |
| 37 static unsigned int __stdcall ThreadEntry(void* data_ptr) { | 36 static unsigned int __stdcall ThreadEntry(void* data_ptr) { |
| 38 ThreadStartData* data = reinterpret_cast<ThreadStartData*>(data_ptr); | 37 ThreadStartData* data = reinterpret_cast<ThreadStartData*>(data_ptr); |
| 39 | 38 |
| 40 Thread::ThreadStartFunction function = data->function(); | 39 Thread::ThreadStartFunction function = data->function(); |
| 41 uword parameter = data->parameter(); | 40 uword parameter = data->parameter(); |
| 42 delete data; | 41 delete data; |
| 43 | 42 |
| 44 MonitorData::GetMonitorWaitDataForThread(); | 43 MonitorData::GetMonitorWaitDataForThread(); |
| 45 | 44 |
| 46 // Call the supplied thread start function handing it its parameters. | 45 // Call the supplied thread start function handing it its parameters. |
| 47 function(parameter); | 46 function(parameter); |
| 48 | 47 |
| 49 // Clean up the monitor wait data for this thread. | 48 // Clean up the monitor wait data for this thread. |
| 50 MonitorWaitData::ThreadExit(); | 49 MonitorWaitData::ThreadExit(); |
| 51 | 50 |
| 52 return 0; | 51 return 0; |
| 53 } | 52 } |
| 54 | 53 |
| 55 | |
| 56 int Thread::Start(ThreadStartFunction function, uword parameter) { | 54 int Thread::Start(ThreadStartFunction function, uword parameter) { |
| 57 ThreadStartData* start_data = new ThreadStartData(function, parameter); | 55 ThreadStartData* start_data = new ThreadStartData(function, parameter); |
| 58 uint32_t tid; | 56 uint32_t tid; |
| 59 uintptr_t thread = _beginthreadex(NULL, Thread::GetMaxStackSize(), | 57 uintptr_t thread = _beginthreadex(NULL, Thread::GetMaxStackSize(), |
| 60 ThreadEntry, start_data, 0, &tid); | 58 ThreadEntry, start_data, 0, &tid); |
| 61 if ((thread == -1L) || (thread == 0)) { | 59 if ((thread == -1L) || (thread == 0)) { |
| 62 #ifdef DEBUG | 60 #ifdef DEBUG |
| 63 fprintf(stderr, "_beginthreadex error: %d (%s)\n", errno, strerror(errno)); | 61 fprintf(stderr, "_beginthreadex error: %d (%s)\n", errno, strerror(errno)); |
| 64 #endif | 62 #endif |
| 65 return errno; | 63 return errno; |
| 66 } | 64 } |
| 67 | 65 |
| 68 // Close the handle, so we don't leak the thread object. | 66 // Close the handle, so we don't leak the thread object. |
| 69 CloseHandle(reinterpret_cast<HANDLE>(thread)); | 67 CloseHandle(reinterpret_cast<HANDLE>(thread)); |
| 70 | 68 |
| 71 return 0; | 69 return 0; |
| 72 } | 70 } |
| 73 | 71 |
| 74 const ThreadLocalKey Thread::kUnsetThreadLocalKey = TLS_OUT_OF_INDEXES; | 72 const ThreadLocalKey Thread::kUnsetThreadLocalKey = TLS_OUT_OF_INDEXES; |
| 75 const ThreadId Thread::kInvalidThreadId = 0; | 73 const ThreadId Thread::kInvalidThreadId = 0; |
| 76 | 74 |
| 77 ThreadLocalKey Thread::CreateThreadLocal() { | 75 ThreadLocalKey Thread::CreateThreadLocal() { |
| 78 ThreadLocalKey key = TlsAlloc(); | 76 ThreadLocalKey key = TlsAlloc(); |
| 79 if (key == kUnsetThreadLocalKey) { | 77 if (key == kUnsetThreadLocalKey) { |
| 80 FATAL1("TlsAlloc failed %d", GetLastError()); | 78 FATAL1("TlsAlloc failed %d", GetLastError()); |
| 81 } | 79 } |
| 82 return key; | 80 return key; |
| 83 } | 81 } |
| 84 | 82 |
| 85 | |
| 86 void Thread::DeleteThreadLocal(ThreadLocalKey key) { | 83 void Thread::DeleteThreadLocal(ThreadLocalKey key) { |
| 87 ASSERT(key != kUnsetThreadLocalKey); | 84 ASSERT(key != kUnsetThreadLocalKey); |
| 88 BOOL result = TlsFree(key); | 85 BOOL result = TlsFree(key); |
| 89 if (!result) { | 86 if (!result) { |
| 90 FATAL1("TlsFree failed %d", GetLastError()); | 87 FATAL1("TlsFree failed %d", GetLastError()); |
| 91 } | 88 } |
| 92 } | 89 } |
| 93 | 90 |
| 94 | |
| 95 intptr_t Thread::GetMaxStackSize() { | 91 intptr_t Thread::GetMaxStackSize() { |
| 96 const int kStackSize = (128 * kWordSize * KB); | 92 const int kStackSize = (128 * kWordSize * KB); |
| 97 return kStackSize; | 93 return kStackSize; |
| 98 } | 94 } |
| 99 | 95 |
| 100 | |
| 101 ThreadId Thread::GetCurrentThreadId() { | 96 ThreadId Thread::GetCurrentThreadId() { |
| 102 return ::GetCurrentThreadId(); | 97 return ::GetCurrentThreadId(); |
| 103 } | 98 } |
| 104 | 99 |
| 105 | |
| 106 intptr_t Thread::ThreadIdToIntPtr(ThreadId id) { | 100 intptr_t Thread::ThreadIdToIntPtr(ThreadId id) { |
| 107 ASSERT(sizeof(id) <= sizeof(intptr_t)); | 101 ASSERT(sizeof(id) <= sizeof(intptr_t)); |
| 108 return static_cast<intptr_t>(id); | 102 return static_cast<intptr_t>(id); |
| 109 } | 103 } |
| 110 | 104 |
| 111 | |
| 112 bool Thread::Compare(ThreadId a, ThreadId b) { | 105 bool Thread::Compare(ThreadId a, ThreadId b) { |
| 113 return (a == b); | 106 return (a == b); |
| 114 } | 107 } |
| 115 | 108 |
| 116 | |
| 117 void Thread::SetThreadLocal(ThreadLocalKey key, uword value) { | 109 void Thread::SetThreadLocal(ThreadLocalKey key, uword value) { |
| 118 ASSERT(key != kUnsetThreadLocalKey); | 110 ASSERT(key != kUnsetThreadLocalKey); |
| 119 BOOL result = TlsSetValue(key, reinterpret_cast<void*>(value)); | 111 BOOL result = TlsSetValue(key, reinterpret_cast<void*>(value)); |
| 120 if (!result) { | 112 if (!result) { |
| 121 FATAL1("TlsSetValue failed %d", GetLastError()); | 113 FATAL1("TlsSetValue failed %d", GetLastError()); |
| 122 } | 114 } |
| 123 } | 115 } |
| 124 | 116 |
| 125 | |
| 126 void Thread::InitOnce() { | 117 void Thread::InitOnce() { |
| 127 MonitorWaitData::monitor_wait_data_key_ = Thread::CreateThreadLocal(); | 118 MonitorWaitData::monitor_wait_data_key_ = Thread::CreateThreadLocal(); |
| 128 MonitorData::GetMonitorWaitDataForThread(); | 119 MonitorData::GetMonitorWaitDataForThread(); |
| 129 } | 120 } |
| 130 | 121 |
| 131 | |
| 132 Mutex::Mutex() { | 122 Mutex::Mutex() { |
| 133 // Allocate unnamed semaphore with initial count 1 and max count 1. | 123 // Allocate unnamed semaphore with initial count 1 and max count 1. |
| 134 data_.semaphore_ = CreateSemaphore(NULL, 1, 1, NULL); | 124 data_.semaphore_ = CreateSemaphore(NULL, 1, 1, NULL); |
| 135 if (data_.semaphore_ == NULL) { | 125 if (data_.semaphore_ == NULL) { |
| 136 FATAL1("Mutex allocation failed %d", GetLastError()); | 126 FATAL1("Mutex allocation failed %d", GetLastError()); |
| 137 } | 127 } |
| 138 } | 128 } |
| 139 | 129 |
| 140 | |
| 141 Mutex::~Mutex() { | 130 Mutex::~Mutex() { |
| 142 CloseHandle(data_.semaphore_); | 131 CloseHandle(data_.semaphore_); |
| 143 } | 132 } |
| 144 | 133 |
| 145 | |
| 146 void Mutex::Lock() { | 134 void Mutex::Lock() { |
| 147 DWORD result = WaitForSingleObject(data_.semaphore_, INFINITE); | 135 DWORD result = WaitForSingleObject(data_.semaphore_, INFINITE); |
| 148 if (result != WAIT_OBJECT_0) { | 136 if (result != WAIT_OBJECT_0) { |
| 149 FATAL1("Mutex lock failed %d", GetLastError()); | 137 FATAL1("Mutex lock failed %d", GetLastError()); |
| 150 } | 138 } |
| 151 } | 139 } |
| 152 | 140 |
| 153 | |
| 154 bool Mutex::TryLock() { | 141 bool Mutex::TryLock() { |
| 155 // Attempt to pass the semaphore but return immediately. | 142 // Attempt to pass the semaphore but return immediately. |
| 156 DWORD result = WaitForSingleObject(data_.semaphore_, 0); | 143 DWORD result = WaitForSingleObject(data_.semaphore_, 0); |
| 157 if (result == WAIT_OBJECT_0) { | 144 if (result == WAIT_OBJECT_0) { |
| 158 return true; | 145 return true; |
| 159 } | 146 } |
| 160 if ((result == WAIT_ABANDONED) || (result == WAIT_FAILED)) { | 147 if ((result == WAIT_ABANDONED) || (result == WAIT_FAILED)) { |
| 161 FATAL1("Mutex try lock failed %d", GetLastError()); | 148 FATAL1("Mutex try lock failed %d", GetLastError()); |
| 162 } | 149 } |
| 163 ASSERT(result == WAIT_TIMEOUT); | 150 ASSERT(result == WAIT_TIMEOUT); |
| 164 return false; | 151 return false; |
| 165 } | 152 } |
| 166 | 153 |
| 167 | |
| 168 void Mutex::Unlock() { | 154 void Mutex::Unlock() { |
| 169 BOOL result = ReleaseSemaphore(data_.semaphore_, 1, NULL); | 155 BOOL result = ReleaseSemaphore(data_.semaphore_, 1, NULL); |
| 170 if (result == 0) { | 156 if (result == 0) { |
| 171 FATAL1("Mutex unlock failed %d", GetLastError()); | 157 FATAL1("Mutex unlock failed %d", GetLastError()); |
| 172 } | 158 } |
| 173 } | 159 } |
| 174 | 160 |
| 175 | |
| 176 ThreadLocalKey MonitorWaitData::monitor_wait_data_key_ = | 161 ThreadLocalKey MonitorWaitData::monitor_wait_data_key_ = |
| 177 Thread::kUnsetThreadLocalKey; | 162 Thread::kUnsetThreadLocalKey; |
| 178 | 163 |
| 179 | |
| 180 Monitor::Monitor() { | 164 Monitor::Monitor() { |
| 181 InitializeCriticalSection(&data_.cs_); | 165 InitializeCriticalSection(&data_.cs_); |
| 182 InitializeCriticalSection(&data_.waiters_cs_); | 166 InitializeCriticalSection(&data_.waiters_cs_); |
| 183 data_.waiters_head_ = NULL; | 167 data_.waiters_head_ = NULL; |
| 184 data_.waiters_tail_ = NULL; | 168 data_.waiters_tail_ = NULL; |
| 185 } | 169 } |
| 186 | 170 |
| 187 | |
| 188 Monitor::~Monitor() { | 171 Monitor::~Monitor() { |
| 189 DeleteCriticalSection(&data_.cs_); | 172 DeleteCriticalSection(&data_.cs_); |
| 190 DeleteCriticalSection(&data_.waiters_cs_); | 173 DeleteCriticalSection(&data_.waiters_cs_); |
| 191 } | 174 } |
| 192 | 175 |
| 193 | |
| 194 void Monitor::Enter() { | 176 void Monitor::Enter() { |
| 195 EnterCriticalSection(&data_.cs_); | 177 EnterCriticalSection(&data_.cs_); |
| 196 } | 178 } |
| 197 | 179 |
| 198 | |
| 199 void Monitor::Exit() { | 180 void Monitor::Exit() { |
| 200 LeaveCriticalSection(&data_.cs_); | 181 LeaveCriticalSection(&data_.cs_); |
| 201 } | 182 } |
| 202 | 183 |
| 203 | |
| 204 void MonitorWaitData::ThreadExit() { | 184 void MonitorWaitData::ThreadExit() { |
| 205 if (MonitorWaitData::monitor_wait_data_key_ != Thread::kUnsetThreadLocalKey) { | 185 if (MonitorWaitData::monitor_wait_data_key_ != Thread::kUnsetThreadLocalKey) { |
| 206 uword raw_wait_data = | 186 uword raw_wait_data = |
| 207 Thread::GetThreadLocal(MonitorWaitData::monitor_wait_data_key_); | 187 Thread::GetThreadLocal(MonitorWaitData::monitor_wait_data_key_); |
| 208 if (raw_wait_data != 0) { | 188 if (raw_wait_data != 0) { |
| 209 MonitorWaitData* wait_data = | 189 MonitorWaitData* wait_data = |
| 210 reinterpret_cast<MonitorWaitData*>(raw_wait_data); | 190 reinterpret_cast<MonitorWaitData*>(raw_wait_data); |
| 211 delete wait_data; | 191 delete wait_data; |
| 212 } | 192 } |
| 213 } | 193 } |
| 214 } | 194 } |
| 215 | 195 |
| 216 | |
| 217 void MonitorData::AddWaiter(MonitorWaitData* wait_data) { | 196 void MonitorData::AddWaiter(MonitorWaitData* wait_data) { |
| 218 // Add the MonitorWaitData object to the list of objects waiting for | 197 // Add the MonitorWaitData object to the list of objects waiting for |
| 219 // this monitor. | 198 // this monitor. |
| 220 EnterCriticalSection(&waiters_cs_); | 199 EnterCriticalSection(&waiters_cs_); |
| 221 if (waiters_tail_ == NULL) { | 200 if (waiters_tail_ == NULL) { |
| 222 ASSERT(waiters_head_ == NULL); | 201 ASSERT(waiters_head_ == NULL); |
| 223 waiters_head_ = wait_data; | 202 waiters_head_ = wait_data; |
| 224 waiters_tail_ = wait_data; | 203 waiters_tail_ = wait_data; |
| 225 } else { | 204 } else { |
| 226 waiters_tail_->next_ = wait_data; | 205 waiters_tail_->next_ = wait_data; |
| 227 waiters_tail_ = wait_data; | 206 waiters_tail_ = wait_data; |
| 228 } | 207 } |
| 229 LeaveCriticalSection(&waiters_cs_); | 208 LeaveCriticalSection(&waiters_cs_); |
| 230 } | 209 } |
| 231 | 210 |
| 232 | |
| 233 void MonitorData::RemoveWaiter(MonitorWaitData* wait_data) { | 211 void MonitorData::RemoveWaiter(MonitorWaitData* wait_data) { |
| 234 // Remove the MonitorWaitData object from the list of objects | 212 // Remove the MonitorWaitData object from the list of objects |
| 235 // waiting for this monitor. | 213 // waiting for this monitor. |
| 236 EnterCriticalSection(&waiters_cs_); | 214 EnterCriticalSection(&waiters_cs_); |
| 237 MonitorWaitData* previous = NULL; | 215 MonitorWaitData* previous = NULL; |
| 238 MonitorWaitData* current = waiters_head_; | 216 MonitorWaitData* current = waiters_head_; |
| 239 while (current != NULL) { | 217 while (current != NULL) { |
| 240 if (current == wait_data) { | 218 if (current == wait_data) { |
| 241 if (waiters_head_ == waiters_tail_) { | 219 if (waiters_head_ == waiters_tail_) { |
| 242 waiters_head_ = NULL; | 220 waiters_head_ = NULL; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 254 // Clear next. | 232 // Clear next. |
| 255 wait_data->next_ = NULL; | 233 wait_data->next_ = NULL; |
| 256 break; | 234 break; |
| 257 } | 235 } |
| 258 previous = current; | 236 previous = current; |
| 259 current = current->next_; | 237 current = current->next_; |
| 260 } | 238 } |
| 261 LeaveCriticalSection(&waiters_cs_); | 239 LeaveCriticalSection(&waiters_cs_); |
| 262 } | 240 } |
| 263 | 241 |
| 264 | |
| 265 void MonitorData::SignalAndRemoveFirstWaiter() { | 242 void MonitorData::SignalAndRemoveFirstWaiter() { |
| 266 EnterCriticalSection(&waiters_cs_); | 243 EnterCriticalSection(&waiters_cs_); |
| 267 MonitorWaitData* first = waiters_head_; | 244 MonitorWaitData* first = waiters_head_; |
| 268 if (first != NULL) { | 245 if (first != NULL) { |
| 269 // Remove from list. | 246 // Remove from list. |
| 270 if (waiters_head_ == waiters_tail_) { | 247 if (waiters_head_ == waiters_tail_) { |
| 271 waiters_tail_ = NULL; | 248 waiters_tail_ = NULL; |
| 272 waiters_head_ = NULL; | 249 waiters_head_ = NULL; |
| 273 } else { | 250 } else { |
| 274 waiters_head_ = waiters_head_->next_; | 251 waiters_head_ = waiters_head_->next_; |
| 275 } | 252 } |
| 276 // Clear next. | 253 // Clear next. |
| 277 first->next_ = NULL; | 254 first->next_ = NULL; |
| 278 // Signal event. | 255 // Signal event. |
| 279 BOOL result = SetEvent(first->event_); | 256 BOOL result = SetEvent(first->event_); |
| 280 if (result == 0) { | 257 if (result == 0) { |
| 281 FATAL1("Monitor::Notify failed to signal event %d", GetLastError()); | 258 FATAL1("Monitor::Notify failed to signal event %d", GetLastError()); |
| 282 } | 259 } |
| 283 } | 260 } |
| 284 LeaveCriticalSection(&waiters_cs_); | 261 LeaveCriticalSection(&waiters_cs_); |
| 285 } | 262 } |
| 286 | 263 |
| 287 | |
| 288 void MonitorData::SignalAndRemoveAllWaiters() { | 264 void MonitorData::SignalAndRemoveAllWaiters() { |
| 289 EnterCriticalSection(&waiters_cs_); | 265 EnterCriticalSection(&waiters_cs_); |
| 290 // Extract list to signal. | 266 // Extract list to signal. |
| 291 MonitorWaitData* current = waiters_head_; | 267 MonitorWaitData* current = waiters_head_; |
| 292 // Clear list. | 268 // Clear list. |
| 293 waiters_head_ = NULL; | 269 waiters_head_ = NULL; |
| 294 waiters_tail_ = NULL; | 270 waiters_tail_ = NULL; |
| 295 // Iterate and signal all events. | 271 // Iterate and signal all events. |
| 296 while (current != NULL) { | 272 while (current != NULL) { |
| 297 // Copy next. | 273 // Copy next. |
| 298 MonitorWaitData* next = current->next_; | 274 MonitorWaitData* next = current->next_; |
| 299 // Clear next. | 275 // Clear next. |
| 300 current->next_ = NULL; | 276 current->next_ = NULL; |
| 301 // Signal event. | 277 // Signal event. |
| 302 BOOL result = SetEvent(current->event_); | 278 BOOL result = SetEvent(current->event_); |
| 303 if (result == 0) { | 279 if (result == 0) { |
| 304 FATAL1("Failed to set event for NotifyAll %d", GetLastError()); | 280 FATAL1("Failed to set event for NotifyAll %d", GetLastError()); |
| 305 } | 281 } |
| 306 current = next; | 282 current = next; |
| 307 } | 283 } |
| 308 LeaveCriticalSection(&waiters_cs_); | 284 LeaveCriticalSection(&waiters_cs_); |
| 309 } | 285 } |
| 310 | 286 |
| 311 | |
| 312 MonitorWaitData* MonitorData::GetMonitorWaitDataForThread() { | 287 MonitorWaitData* MonitorData::GetMonitorWaitDataForThread() { |
| 313 // Ensure that the thread local key for monitor wait data objects is | 288 // Ensure that the thread local key for monitor wait data objects is |
| 314 // initialized. | 289 // initialized. |
| 315 ASSERT(MonitorWaitData::monitor_wait_data_key_ != | 290 ASSERT(MonitorWaitData::monitor_wait_data_key_ != |
| 316 Thread::kUnsetThreadLocalKey); | 291 Thread::kUnsetThreadLocalKey); |
| 317 | 292 |
| 318 // Get the MonitorWaitData object containing the event for this | 293 // Get the MonitorWaitData object containing the event for this |
| 319 // thread from thread local storage. Create it if it does not exist. | 294 // thread from thread local storage. Create it if it does not exist. |
| 320 uword raw_wait_data = | 295 uword raw_wait_data = |
| 321 Thread::GetThreadLocal(MonitorWaitData::monitor_wait_data_key_); | 296 Thread::GetThreadLocal(MonitorWaitData::monitor_wait_data_key_); |
| 322 MonitorWaitData* wait_data = NULL; | 297 MonitorWaitData* wait_data = NULL; |
| 323 if (raw_wait_data == 0) { | 298 if (raw_wait_data == 0) { |
| 324 HANDLE event = CreateEvent(NULL, FALSE, FALSE, NULL); | 299 HANDLE event = CreateEvent(NULL, FALSE, FALSE, NULL); |
| 325 wait_data = new MonitorWaitData(event); | 300 wait_data = new MonitorWaitData(event); |
| 326 Thread::SetThreadLocal(MonitorWaitData::monitor_wait_data_key_, | 301 Thread::SetThreadLocal(MonitorWaitData::monitor_wait_data_key_, |
| 327 reinterpret_cast<uword>(wait_data)); | 302 reinterpret_cast<uword>(wait_data)); |
| 328 } else { | 303 } else { |
| 329 wait_data = reinterpret_cast<MonitorWaitData*>(raw_wait_data); | 304 wait_data = reinterpret_cast<MonitorWaitData*>(raw_wait_data); |
| 330 wait_data->next_ = NULL; | 305 wait_data->next_ = NULL; |
| 331 } | 306 } |
| 332 return wait_data; | 307 return wait_data; |
| 333 } | 308 } |
| 334 | 309 |
| 335 | |
| 336 Monitor::WaitResult Monitor::Wait(int64_t millis) { | 310 Monitor::WaitResult Monitor::Wait(int64_t millis) { |
| 337 Monitor::WaitResult retval = kNotified; | 311 Monitor::WaitResult retval = kNotified; |
| 338 | 312 |
| 339 // Get the wait data object containing the event to wait for. | 313 // Get the wait data object containing the event to wait for. |
| 340 MonitorWaitData* wait_data = MonitorData::GetMonitorWaitDataForThread(); | 314 MonitorWaitData* wait_data = MonitorData::GetMonitorWaitDataForThread(); |
| 341 | 315 |
| 342 // Start waiting by adding the MonitorWaitData to the list of | 316 // Start waiting by adding the MonitorWaitData to the list of |
| 343 // waiters. | 317 // waiters. |
| 344 data_.AddWaiter(wait_data); | 318 data_.AddWaiter(wait_data); |
| 345 | 319 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 367 retval = kTimedOut; | 341 retval = kTimedOut; |
| 368 } | 342 } |
| 369 } | 343 } |
| 370 | 344 |
| 371 // Reacquire the monitor critical section before continuing. | 345 // Reacquire the monitor critical section before continuing. |
| 372 EnterCriticalSection(&data_.cs_); | 346 EnterCriticalSection(&data_.cs_); |
| 373 | 347 |
| 374 return retval; | 348 return retval; |
| 375 } | 349 } |
| 376 | 350 |
| 377 | |
| 378 Monitor::WaitResult Monitor::WaitMicros(int64_t micros) { | 351 Monitor::WaitResult Monitor::WaitMicros(int64_t micros) { |
| 379 // TODO(johnmccutchan): Investigate sub-millisecond sleep times on Windows. | 352 // TODO(johnmccutchan): Investigate sub-millisecond sleep times on Windows. |
| 380 int64_t millis = micros / kMicrosecondsPerMillisecond; | 353 int64_t millis = micros / kMicrosecondsPerMillisecond; |
| 381 if ((millis * kMicrosecondsPerMillisecond) < micros) { | 354 if ((millis * kMicrosecondsPerMillisecond) < micros) { |
| 382 // We've been asked to sleep for a fraction of a millisecond, | 355 // We've been asked to sleep for a fraction of a millisecond, |
| 383 // this isn't supported on Windows. Bumps milliseconds up by one | 356 // this isn't supported on Windows. Bumps milliseconds up by one |
| 384 // so that we never return too early. We likely return late though. | 357 // so that we never return too early. We likely return late though. |
| 385 millis += 1; | 358 millis += 1; |
| 386 } | 359 } |
| 387 return Wait(millis); | 360 return Wait(millis); |
| 388 } | 361 } |
| 389 | 362 |
| 390 | |
| 391 void Monitor::Notify() { | 363 void Monitor::Notify() { |
| 392 data_.SignalAndRemoveFirstWaiter(); | 364 data_.SignalAndRemoveFirstWaiter(); |
| 393 } | 365 } |
| 394 | 366 |
| 395 | |
| 396 void Monitor::NotifyAll() { | 367 void Monitor::NotifyAll() { |
| 397 // If one of the objects in the list of waiters wakes because of a | 368 // If one of the objects in the list of waiters wakes because of a |
| 398 // timeout before we signal it, that object will get an extra | 369 // timeout before we signal it, that object will get an extra |
| 399 // signal. This will be treated as a spurious wake-up and is OK | 370 // signal. This will be treated as a spurious wake-up and is OK |
| 400 // since all uses of monitors should recheck the condition after a | 371 // since all uses of monitors should recheck the condition after a |
| 401 // Wait. | 372 // Wait. |
| 402 data_.SignalAndRemoveAllWaiters(); | 373 data_.SignalAndRemoveAllWaiters(); |
| 403 } | 374 } |
| 404 | 375 |
| 405 } // namespace bin | 376 } // namespace bin |
| 406 } // namespace dart | 377 } // namespace dart |
| 407 | 378 |
| 408 #endif // defined(HOST_OS_WINDOWS) | 379 #endif // defined(HOST_OS_WINDOWS) |
| OLD | NEW |