ui: annotate DCLOps callback requirements
[qemu/kevin.git] / util / qemu-thread-posix.c
blobdcff5e7c5d676a357785c9f10f1a955cea7d5cfc
1 /*
2 * Wrappers around mutex/cond/thread functions
4 * Copyright Red Hat, Inc. 2009
6 * Author:
7 * Marcelo Tosatti <mtosatti@redhat.com>
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.
13 #include "qemu/osdep.h"
14 #include "qemu/thread.h"
15 #include "qemu/atomic.h"
16 #include "qemu/notify.h"
17 #include "qemu-thread-common.h"
18 #include "qemu/tsan.h"
20 static bool name_threads;
22 void qemu_thread_naming(bool enable)
24 name_threads = enable;
26 #ifndef CONFIG_THREAD_SETNAME_BYTHREAD
27 /* This is a debugging option, not fatal */
28 if (enable) {
29 fprintf(stderr, "qemu: thread naming not supported on this host\n");
31 #endif
34 static void error_exit(int err, const char *msg)
36 fprintf(stderr, "qemu: %s: %s\n", msg, strerror(err));
37 abort();
40 static void compute_abs_deadline(struct timespec *ts, int ms)
42 struct timeval tv;
43 gettimeofday(&tv, NULL);
44 ts->tv_nsec = tv.tv_usec * 1000 + (ms % 1000) * 1000000;
45 ts->tv_sec = tv.tv_sec + ms / 1000;
46 if (ts->tv_nsec >= 1000000000) {
47 ts->tv_sec++;
48 ts->tv_nsec -= 1000000000;
52 void qemu_mutex_init(QemuMutex *mutex)
54 int err;
56 err = pthread_mutex_init(&mutex->lock, NULL);
57 if (err)
58 error_exit(err, __func__);
59 qemu_mutex_post_init(mutex);
62 void qemu_mutex_destroy(QemuMutex *mutex)
64 int err;
66 assert(mutex->initialized);
67 mutex->initialized = false;
68 err = pthread_mutex_destroy(&mutex->lock);
69 if (err)
70 error_exit(err, __func__);
73 void qemu_mutex_lock_impl(QemuMutex *mutex, const char *file, const int line)
75 int err;
77 assert(mutex->initialized);
78 qemu_mutex_pre_lock(mutex, file, line);
79 err = pthread_mutex_lock(&mutex->lock);
80 if (err)
81 error_exit(err, __func__);
82 qemu_mutex_post_lock(mutex, file, line);
85 int qemu_mutex_trylock_impl(QemuMutex *mutex, const char *file, const int line)
87 int err;
89 assert(mutex->initialized);
90 err = pthread_mutex_trylock(&mutex->lock);
91 if (err == 0) {
92 qemu_mutex_post_lock(mutex, file, line);
93 return 0;
95 if (err != EBUSY) {
96 error_exit(err, __func__);
98 return -EBUSY;
101 void qemu_mutex_unlock_impl(QemuMutex *mutex, const char *file, const int line)
103 int err;
105 assert(mutex->initialized);
106 qemu_mutex_pre_unlock(mutex, file, line);
107 err = pthread_mutex_unlock(&mutex->lock);
108 if (err)
109 error_exit(err, __func__);
112 void qemu_rec_mutex_init(QemuRecMutex *mutex)
114 int err;
115 pthread_mutexattr_t attr;
117 pthread_mutexattr_init(&attr);
118 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
119 err = pthread_mutex_init(&mutex->lock, &attr);
120 pthread_mutexattr_destroy(&attr);
121 if (err) {
122 error_exit(err, __func__);
124 mutex->initialized = true;
127 void qemu_cond_init(QemuCond *cond)
129 int err;
131 err = pthread_cond_init(&cond->cond, NULL);
132 if (err)
133 error_exit(err, __func__);
134 cond->initialized = true;
137 void qemu_cond_destroy(QemuCond *cond)
139 int err;
141 assert(cond->initialized);
142 cond->initialized = false;
143 err = pthread_cond_destroy(&cond->cond);
144 if (err)
145 error_exit(err, __func__);
148 void qemu_cond_signal(QemuCond *cond)
150 int err;
152 assert(cond->initialized);
153 err = pthread_cond_signal(&cond->cond);
154 if (err)
155 error_exit(err, __func__);
158 void qemu_cond_broadcast(QemuCond *cond)
160 int err;
162 assert(cond->initialized);
163 err = pthread_cond_broadcast(&cond->cond);
164 if (err)
165 error_exit(err, __func__);
168 void qemu_cond_wait_impl(QemuCond *cond, QemuMutex *mutex, const char *file, const int line)
170 int err;
172 assert(cond->initialized);
173 qemu_mutex_pre_unlock(mutex, file, line);
174 err = pthread_cond_wait(&cond->cond, &mutex->lock);
175 qemu_mutex_post_lock(mutex, file, line);
176 if (err)
177 error_exit(err, __func__);
180 bool qemu_cond_timedwait_impl(QemuCond *cond, QemuMutex *mutex, int ms,
181 const char *file, const int line)
183 int err;
184 struct timespec ts;
186 assert(cond->initialized);
187 trace_qemu_mutex_unlock(mutex, file, line);
188 compute_abs_deadline(&ts, ms);
189 err = pthread_cond_timedwait(&cond->cond, &mutex->lock, &ts);
190 trace_qemu_mutex_locked(mutex, file, line);
191 if (err && err != ETIMEDOUT) {
192 error_exit(err, __func__);
194 return err != ETIMEDOUT;
197 void qemu_sem_init(QemuSemaphore *sem, int init)
199 int rc;
201 #ifndef CONFIG_SEM_TIMEDWAIT
202 rc = pthread_mutex_init(&sem->lock, NULL);
203 if (rc != 0) {
204 error_exit(rc, __func__);
206 rc = pthread_cond_init(&sem->cond, NULL);
207 if (rc != 0) {
208 error_exit(rc, __func__);
210 if (init < 0) {
211 error_exit(EINVAL, __func__);
213 sem->count = init;
214 #else
215 rc = sem_init(&sem->sem, 0, init);
216 if (rc < 0) {
217 error_exit(errno, __func__);
219 #endif
220 sem->initialized = true;
223 void qemu_sem_destroy(QemuSemaphore *sem)
225 int rc;
227 assert(sem->initialized);
228 sem->initialized = false;
229 #ifndef CONFIG_SEM_TIMEDWAIT
230 rc = pthread_cond_destroy(&sem->cond);
231 if (rc < 0) {
232 error_exit(rc, __func__);
234 rc = pthread_mutex_destroy(&sem->lock);
235 if (rc < 0) {
236 error_exit(rc, __func__);
238 #else
239 rc = sem_destroy(&sem->sem);
240 if (rc < 0) {
241 error_exit(errno, __func__);
243 #endif
246 void qemu_sem_post(QemuSemaphore *sem)
248 int rc;
250 assert(sem->initialized);
251 #ifndef CONFIG_SEM_TIMEDWAIT
252 pthread_mutex_lock(&sem->lock);
253 if (sem->count == UINT_MAX) {
254 rc = EINVAL;
255 } else {
256 sem->count++;
257 rc = pthread_cond_signal(&sem->cond);
259 pthread_mutex_unlock(&sem->lock);
260 if (rc != 0) {
261 error_exit(rc, __func__);
263 #else
264 rc = sem_post(&sem->sem);
265 if (rc < 0) {
266 error_exit(errno, __func__);
268 #endif
271 int qemu_sem_timedwait(QemuSemaphore *sem, int ms)
273 int rc;
274 struct timespec ts;
276 assert(sem->initialized);
277 #ifndef CONFIG_SEM_TIMEDWAIT
278 rc = 0;
279 compute_abs_deadline(&ts, ms);
280 pthread_mutex_lock(&sem->lock);
281 while (sem->count == 0) {
282 rc = pthread_cond_timedwait(&sem->cond, &sem->lock, &ts);
283 if (rc == ETIMEDOUT) {
284 break;
286 if (rc != 0) {
287 error_exit(rc, __func__);
290 if (rc != ETIMEDOUT) {
291 --sem->count;
293 pthread_mutex_unlock(&sem->lock);
294 return (rc == ETIMEDOUT ? -1 : 0);
295 #else
296 if (ms <= 0) {
297 /* This is cheaper than sem_timedwait. */
298 do {
299 rc = sem_trywait(&sem->sem);
300 } while (rc == -1 && errno == EINTR);
301 if (rc == -1 && errno == EAGAIN) {
302 return -1;
304 } else {
305 compute_abs_deadline(&ts, ms);
306 do {
307 rc = sem_timedwait(&sem->sem, &ts);
308 } while (rc == -1 && errno == EINTR);
309 if (rc == -1 && errno == ETIMEDOUT) {
310 return -1;
313 if (rc < 0) {
314 error_exit(errno, __func__);
316 return 0;
317 #endif
320 void qemu_sem_wait(QemuSemaphore *sem)
322 int rc;
324 assert(sem->initialized);
325 #ifndef CONFIG_SEM_TIMEDWAIT
326 pthread_mutex_lock(&sem->lock);
327 while (sem->count == 0) {
328 rc = pthread_cond_wait(&sem->cond, &sem->lock);
329 if (rc != 0) {
330 error_exit(rc, __func__);
333 --sem->count;
334 pthread_mutex_unlock(&sem->lock);
335 #else
336 do {
337 rc = sem_wait(&sem->sem);
338 } while (rc == -1 && errno == EINTR);
339 if (rc < 0) {
340 error_exit(errno, __func__);
342 #endif
345 #ifdef __linux__
346 #include "qemu/futex.h"
347 #else
348 static inline void qemu_futex_wake(QemuEvent *ev, int n)
350 assert(ev->initialized);
351 pthread_mutex_lock(&ev->lock);
352 if (n == 1) {
353 pthread_cond_signal(&ev->cond);
354 } else {
355 pthread_cond_broadcast(&ev->cond);
357 pthread_mutex_unlock(&ev->lock);
360 static inline void qemu_futex_wait(QemuEvent *ev, unsigned val)
362 assert(ev->initialized);
363 pthread_mutex_lock(&ev->lock);
364 if (ev->value == val) {
365 pthread_cond_wait(&ev->cond, &ev->lock);
367 pthread_mutex_unlock(&ev->lock);
369 #endif
371 /* Valid transitions:
372 * - free->set, when setting the event
373 * - busy->set, when setting the event, followed by qemu_futex_wake
374 * - set->free, when resetting the event
375 * - free->busy, when waiting
377 * set->busy does not happen (it can be observed from the outside but
378 * it really is set->free->busy).
380 * busy->free provably cannot happen; to enforce it, the set->free transition
381 * is done with an OR, which becomes a no-op if the event has concurrently
382 * transitioned to free or busy.
385 #define EV_SET 0
386 #define EV_FREE 1
387 #define EV_BUSY -1
389 void qemu_event_init(QemuEvent *ev, bool init)
391 #ifndef __linux__
392 pthread_mutex_init(&ev->lock, NULL);
393 pthread_cond_init(&ev->cond, NULL);
394 #endif
396 ev->value = (init ? EV_SET : EV_FREE);
397 ev->initialized = true;
400 void qemu_event_destroy(QemuEvent *ev)
402 assert(ev->initialized);
403 ev->initialized = false;
404 #ifndef __linux__
405 pthread_mutex_destroy(&ev->lock);
406 pthread_cond_destroy(&ev->cond);
407 #endif
410 void qemu_event_set(QemuEvent *ev)
412 /* qemu_event_set has release semantics, but because it *loads*
413 * ev->value we need a full memory barrier here.
415 assert(ev->initialized);
416 smp_mb();
417 if (qatomic_read(&ev->value) != EV_SET) {
418 if (qatomic_xchg(&ev->value, EV_SET) == EV_BUSY) {
419 /* There were waiters, wake them up. */
420 qemu_futex_wake(ev, INT_MAX);
425 void qemu_event_reset(QemuEvent *ev)
427 unsigned value;
429 assert(ev->initialized);
430 value = qatomic_read(&ev->value);
431 smp_mb_acquire();
432 if (value == EV_SET) {
434 * If there was a concurrent reset (or even reset+wait),
435 * do nothing. Otherwise change EV_SET->EV_FREE.
437 qatomic_or(&ev->value, EV_FREE);
441 void qemu_event_wait(QemuEvent *ev)
443 unsigned value;
445 assert(ev->initialized);
446 value = qatomic_read(&ev->value);
447 smp_mb_acquire();
448 if (value != EV_SET) {
449 if (value == EV_FREE) {
451 * Leave the event reset and tell qemu_event_set that there
452 * are waiters. No need to retry, because there cannot be
453 * a concurrent busy->free transition. After the CAS, the
454 * event will be either set or busy.
456 if (qatomic_cmpxchg(&ev->value, EV_FREE, EV_BUSY) == EV_SET) {
457 return;
460 qemu_futex_wait(ev, EV_BUSY);
464 static __thread NotifierList thread_exit;
467 * Note that in this implementation you can register a thread-exit
468 * notifier for the main thread, but it will never be called.
469 * This is OK because main thread exit can only happen when the
470 * entire process is exiting, and the API allows notifiers to not
471 * be called on process exit.
473 void qemu_thread_atexit_add(Notifier *notifier)
475 notifier_list_add(&thread_exit, notifier);
478 void qemu_thread_atexit_remove(Notifier *notifier)
480 notifier_remove(notifier);
483 static void qemu_thread_atexit_notify(void *arg)
486 * Called when non-main thread exits (via qemu_thread_exit()
487 * or by returning from its start routine.)
489 notifier_list_notify(&thread_exit, NULL);
492 typedef struct {
493 void *(*start_routine)(void *);
494 void *arg;
495 char *name;
496 } QemuThreadArgs;
498 static void *qemu_thread_start(void *args)
500 QemuThreadArgs *qemu_thread_args = args;
501 void *(*start_routine)(void *) = qemu_thread_args->start_routine;
502 void *arg = qemu_thread_args->arg;
503 void *r;
505 #ifdef CONFIG_THREAD_SETNAME_BYTHREAD
506 /* Attempt to set the threads name; note that this is for debug, so
507 * we're not going to fail if we can't set it.
509 if (name_threads && qemu_thread_args->name) {
510 # if defined(CONFIG_PTHREAD_SETNAME_NP_W_TID)
511 pthread_setname_np(pthread_self(), qemu_thread_args->name);
512 # elif defined(CONFIG_PTHREAD_SETNAME_NP_WO_TID)
513 pthread_setname_np(qemu_thread_args->name);
514 # endif
516 #endif
517 QEMU_TSAN_ANNOTATE_THREAD_NAME(qemu_thread_args->name);
518 g_free(qemu_thread_args->name);
519 g_free(qemu_thread_args);
520 pthread_cleanup_push(qemu_thread_atexit_notify, NULL);
521 r = start_routine(arg);
522 pthread_cleanup_pop(1);
523 return r;
526 void qemu_thread_create(QemuThread *thread, const char *name,
527 void *(*start_routine)(void*),
528 void *arg, int mode)
530 sigset_t set, oldset;
531 int err;
532 pthread_attr_t attr;
533 QemuThreadArgs *qemu_thread_args;
535 err = pthread_attr_init(&attr);
536 if (err) {
537 error_exit(err, __func__);
540 if (mode == QEMU_THREAD_DETACHED) {
541 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
544 /* Leave signal handling to the iothread. */
545 sigfillset(&set);
546 /* Blocking the signals can result in undefined behaviour. */
547 sigdelset(&set, SIGSEGV);
548 sigdelset(&set, SIGFPE);
549 sigdelset(&set, SIGILL);
550 /* TODO avoid SIGBUS loss on macOS */
551 pthread_sigmask(SIG_SETMASK, &set, &oldset);
553 qemu_thread_args = g_new0(QemuThreadArgs, 1);
554 qemu_thread_args->name = g_strdup(name);
555 qemu_thread_args->start_routine = start_routine;
556 qemu_thread_args->arg = arg;
558 err = pthread_create(&thread->thread, &attr,
559 qemu_thread_start, qemu_thread_args);
561 if (err)
562 error_exit(err, __func__);
564 pthread_sigmask(SIG_SETMASK, &oldset, NULL);
566 pthread_attr_destroy(&attr);
569 void qemu_thread_get_self(QemuThread *thread)
571 thread->thread = pthread_self();
574 bool qemu_thread_is_self(QemuThread *thread)
576 return pthread_equal(pthread_self(), thread->thread);
579 void qemu_thread_exit(void *retval)
581 pthread_exit(retval);
584 void *qemu_thread_join(QemuThread *thread)
586 int err;
587 void *ret;
589 err = pthread_join(thread->thread, &ret);
590 if (err) {
591 error_exit(err, __func__);
593 return ret;