1 /* 2 * Win32 implementation for mutex/cond/thread functions 3 * 4 * Copyright Red Hat, Inc. 2010 5 * 6 * Author: 7 * Paolo Bonzini <pbonzini@redhat.com> 8 * 9 * This work is licensed under the terms of the GNU GPL, version 2 or later. 10 * See the COPYING file in the top-level directory. 11 * 12 */ 13 #include "qemu-common.h" 14 #include "qemu/thread.h" 15 #include <process.h> 16 #include <assert.h> 17 #include <limits.h> 18 19 static bool name_threads; 20 21 void qemu_thread_naming(bool enable) 22 { 23 /* But note we don't actually name them on Windows yet */ 24 name_threads = enable; 25 } 26 27 static void error_exit(int err, const char *msg) 28 { 29 char *pstr; 30 31 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, 32 NULL, err, 0, (LPTSTR)&pstr, 2, NULL); 33 fprintf(stderr, "qemu: %s: %s\n", msg, pstr); 34 LocalFree(pstr); 35 abort(); 36 } 37 38 void qemu_mutex_init(QemuMutex *mutex) 39 { 40 mutex->owner = 0; 41 InitializeCriticalSection(&mutex->lock); 42 } 43 44 void qemu_mutex_destroy(QemuMutex *mutex) 45 { 46 assert(mutex->owner == 0); 47 DeleteCriticalSection(&mutex->lock); 48 } 49 50 void qemu_mutex_lock(QemuMutex *mutex) 51 { 52 EnterCriticalSection(&mutex->lock); 53 54 /* Win32 CRITICAL_SECTIONs are recursive. Assert that we're not 55 * using them as such. 56 */ 57 assert(mutex->owner == 0); 58 mutex->owner = GetCurrentThreadId(); 59 } 60 61 int qemu_mutex_trylock(QemuMutex *mutex) 62 { 63 int owned; 64 65 owned = TryEnterCriticalSection(&mutex->lock); 66 if (owned) { 67 assert(mutex->owner == 0); 68 mutex->owner = GetCurrentThreadId(); 69 } 70 return !owned; 71 } 72 73 void qemu_mutex_unlock(QemuMutex *mutex) 74 { 75 assert(mutex->owner == GetCurrentThreadId()); 76 mutex->owner = 0; 77 LeaveCriticalSection(&mutex->lock); 78 } 79 80 void qemu_cond_init(QemuCond *cond) 81 { 82 memset(cond, 0, sizeof(*cond)); 83 84 cond->sema = CreateSemaphore(NULL, 0, LONG_MAX, NULL); 85 if (!cond->sema) { 86 error_exit(GetLastError(), __func__); 87 } 88 cond->continue_event = CreateEvent(NULL, /* security */ 89 FALSE, /* auto-reset */ 90 FALSE, /* not signaled */ 91 NULL); /* name */ 92 if (!cond->continue_event) { 93 error_exit(GetLastError(), __func__); 94 } 95 } 96 97 void qemu_cond_destroy(QemuCond *cond) 98 { 99 BOOL result; 100 result = CloseHandle(cond->continue_event); 101 if (!result) { 102 error_exit(GetLastError(), __func__); 103 } 104 cond->continue_event = 0; 105 result = CloseHandle(cond->sema); 106 if (!result) { 107 error_exit(GetLastError(), __func__); 108 } 109 cond->sema = 0; 110 } 111 112 void qemu_cond_signal(QemuCond *cond) 113 { 114 DWORD result; 115 116 /* 117 * Signal only when there are waiters. cond->waiters is 118 * incremented by pthread_cond_wait under the external lock, 119 * so we are safe about that. 120 */ 121 if (cond->waiters == 0) { 122 return; 123 } 124 125 /* 126 * Waiting threads decrement it outside the external lock, but 127 * only if another thread is executing pthread_cond_broadcast and 128 * has the mutex. So, it also cannot be decremented concurrently 129 * with this particular access. 130 */ 131 cond->target = cond->waiters - 1; 132 result = SignalObjectAndWait(cond->sema, cond->continue_event, 133 INFINITE, FALSE); 134 if (result == WAIT_ABANDONED || result == WAIT_FAILED) { 135 error_exit(GetLastError(), __func__); 136 } 137 } 138 139 void qemu_cond_broadcast(QemuCond *cond) 140 { 141 BOOLEAN result; 142 /* 143 * As in pthread_cond_signal, access to cond->waiters and 144 * cond->target is locked via the external mutex. 145 */ 146 if (cond->waiters == 0) { 147 return; 148 } 149 150 cond->target = 0; 151 result = ReleaseSemaphore(cond->sema, cond->waiters, NULL); 152 if (!result) { 153 error_exit(GetLastError(), __func__); 154 } 155 156 /* 157 * At this point all waiters continue. Each one takes its 158 * slice of the semaphore. Now it's our turn to wait: Since 159 * the external mutex is held, no thread can leave cond_wait, 160 * yet. For this reason, we can be sure that no thread gets 161 * a chance to eat *more* than one slice. OTOH, it means 162 * that the last waiter must send us a wake-up. 163 */ 164 WaitForSingleObject(cond->continue_event, INFINITE); 165 } 166 167 void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex) 168 { 169 /* 170 * This access is protected under the mutex. 171 */ 172 cond->waiters++; 173 174 /* 175 * Unlock external mutex and wait for signal. 176 * NOTE: we've held mutex locked long enough to increment 177 * waiters count above, so there's no problem with 178 * leaving mutex unlocked before we wait on semaphore. 179 */ 180 qemu_mutex_unlock(mutex); 181 WaitForSingleObject(cond->sema, INFINITE); 182 183 /* Now waiters must rendez-vous with the signaling thread and 184 * let it continue. For cond_broadcast this has heavy contention 185 * and triggers thundering herd. So goes life. 186 * 187 * Decrease waiters count. The mutex is not taken, so we have 188 * to do this atomically. 189 * 190 * All waiters contend for the mutex at the end of this function 191 * until the signaling thread relinquishes it. To ensure 192 * each waiter consumes exactly one slice of the semaphore, 193 * the signaling thread stops until it is told by the last 194 * waiter that it can go on. 195 */ 196 if (InterlockedDecrement(&cond->waiters) == cond->target) { 197 SetEvent(cond->continue_event); 198 } 199 200 qemu_mutex_lock(mutex); 201 } 202 203 void qemu_sem_init(QemuSemaphore *sem, int init) 204 { 205 /* Manual reset. */ 206 sem->sema = CreateSemaphore(NULL, init, LONG_MAX, NULL); 207 } 208 209 void qemu_sem_destroy(QemuSemaphore *sem) 210 { 211 CloseHandle(sem->sema); 212 } 213 214 void qemu_sem_post(QemuSemaphore *sem) 215 { 216 ReleaseSemaphore(sem->sema, 1, NULL); 217 } 218 219 int qemu_sem_timedwait(QemuSemaphore *sem, int ms) 220 { 221 int rc = WaitForSingleObject(sem->sema, ms); 222 if (rc == WAIT_OBJECT_0) { 223 return 0; 224 } 225 if (rc != WAIT_TIMEOUT) { 226 error_exit(GetLastError(), __func__); 227 } 228 return -1; 229 } 230 231 void qemu_sem_wait(QemuSemaphore *sem) 232 { 233 if (WaitForSingleObject(sem->sema, INFINITE) != WAIT_OBJECT_0) { 234 error_exit(GetLastError(), __func__); 235 } 236 } 237 238 void qemu_event_init(QemuEvent *ev, bool init) 239 { 240 /* Manual reset. */ 241 ev->event = CreateEvent(NULL, TRUE, init, NULL); 242 } 243 244 void qemu_event_destroy(QemuEvent *ev) 245 { 246 CloseHandle(ev->event); 247 } 248 249 void qemu_event_set(QemuEvent *ev) 250 { 251 SetEvent(ev->event); 252 } 253 254 void qemu_event_reset(QemuEvent *ev) 255 { 256 ResetEvent(ev->event); 257 } 258 259 void qemu_event_wait(QemuEvent *ev) 260 { 261 WaitForSingleObject(ev->event, INFINITE); 262 } 263 264 struct QemuThreadData { 265 /* Passed to win32_start_routine. */ 266 void *(*start_routine)(void *); 267 void *arg; 268 short mode; 269 270 /* Only used for joinable threads. */ 271 bool exited; 272 void *ret; 273 CRITICAL_SECTION cs; 274 }; 275 276 static __thread QemuThreadData *qemu_thread_data; 277 278 static unsigned __stdcall win32_start_routine(void *arg) 279 { 280 QemuThreadData *data = (QemuThreadData *) arg; 281 void *(*start_routine)(void *) = data->start_routine; 282 void *thread_arg = data->arg; 283 284 if (data->mode == QEMU_THREAD_DETACHED) { 285 g_free(data); 286 data = NULL; 287 } 288 qemu_thread_data = data; 289 qemu_thread_exit(start_routine(thread_arg)); 290 abort(); 291 } 292 293 void qemu_thread_exit(void *arg) 294 { 295 QemuThreadData *data = qemu_thread_data; 296 297 if (data) { 298 assert(data->mode != QEMU_THREAD_DETACHED); 299 data->ret = arg; 300 EnterCriticalSection(&data->cs); 301 data->exited = true; 302 LeaveCriticalSection(&data->cs); 303 } 304 _endthreadex(0); 305 } 306 307 void *qemu_thread_join(QemuThread *thread) 308 { 309 QemuThreadData *data; 310 void *ret; 311 HANDLE handle; 312 313 data = thread->data; 314 if (!data) { 315 return NULL; 316 } 317 /* 318 * Because multiple copies of the QemuThread can exist via 319 * qemu_thread_get_self, we need to store a value that cannot 320 * leak there. The simplest, non racy way is to store the TID, 321 * discard the handle that _beginthreadex gives back, and 322 * get another copy of the handle here. 323 */ 324 handle = qemu_thread_get_handle(thread); 325 if (handle) { 326 WaitForSingleObject(handle, INFINITE); 327 CloseHandle(handle); 328 } 329 ret = data->ret; 330 assert(data->mode != QEMU_THREAD_DETACHED); 331 DeleteCriticalSection(&data->cs); 332 g_free(data); 333 return ret; 334 } 335 336 void qemu_thread_create(QemuThread *thread, const char *name, 337 void *(*start_routine)(void *), 338 void *arg, int mode) 339 { 340 HANDLE hThread; 341 struct QemuThreadData *data; 342 343 data = g_malloc(sizeof *data); 344 data->start_routine = start_routine; 345 data->arg = arg; 346 data->mode = mode; 347 data->exited = false; 348 349 if (data->mode != QEMU_THREAD_DETACHED) { 350 InitializeCriticalSection(&data->cs); 351 } 352 353 hThread = (HANDLE) _beginthreadex(NULL, 0, win32_start_routine, 354 data, 0, &thread->tid); 355 if (!hThread) { 356 error_exit(GetLastError(), __func__); 357 } 358 CloseHandle(hThread); 359 thread->data = (mode == QEMU_THREAD_DETACHED) ? NULL : data; 360 } 361 362 void qemu_thread_get_self(QemuThread *thread) 363 { 364 thread->data = qemu_thread_data; 365 thread->tid = GetCurrentThreadId(); 366 } 367 368 HANDLE qemu_thread_get_handle(QemuThread *thread) 369 { 370 QemuThreadData *data; 371 HANDLE handle; 372 373 data = thread->data; 374 if (!data) { 375 return NULL; 376 } 377 378 assert(data->mode != QEMU_THREAD_DETACHED); 379 EnterCriticalSection(&data->cs); 380 if (!data->exited) { 381 handle = OpenThread(SYNCHRONIZE | THREAD_SUSPEND_RESUME, FALSE, 382 thread->tid); 383 } else { 384 handle = NULL; 385 } 386 LeaveCriticalSection(&data->cs); 387 return handle; 388 } 389 390 bool qemu_thread_is_self(QemuThread *thread) 391 { 392 return GetCurrentThreadId() == thread->tid; 393 } 394