2 * Wrappers around mutex/cond/thread functions
4 * Copyright Red Hat, Inc. 2009
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"
19 #include "qemu/bitmap.h"
21 static bool name_threads;
23 void qemu_thread_naming(bool enable)
25 name_threads = enable;
27 #if !defined CONFIG_PTHREAD_SETNAME_NP_W_TID && \
28 !defined CONFIG_PTHREAD_SETNAME_NP_WO_TID
29 /* This is a debugging option, not fatal */
31 fprintf(stderr, "qemu: thread naming not supported on this host\n");
36 static void error_exit(int err, const char *msg)
38 fprintf(stderr, "qemu: %s: %s\n", msg, strerror(err));
42 static inline clockid_t qemu_timedwait_clockid(void)
44 #ifdef CONFIG_PTHREAD_CONDATTR_SETCLOCK
45 return CLOCK_MONOTONIC;
47 return CLOCK_REALTIME;
51 static void compute_abs_deadline(struct timespec *ts, int ms)
53 clock_gettime(qemu_timedwait_clockid(), ts);
54 ts->tv_nsec += (ms % 1000) * 1000000;
55 ts->tv_sec += ms / 1000;
56 if (ts->tv_nsec >= 1000000000) {
58 ts->tv_nsec -= 1000000000;
62 void qemu_mutex_init(QemuMutex *mutex)
66 err = pthread_mutex_init(&mutex->lock, NULL);
68 error_exit(err, __func__);
69 qemu_mutex_post_init(mutex);
72 void qemu_mutex_destroy(QemuMutex *mutex)
76 assert(mutex->initialized);
77 mutex->initialized = false;
78 err = pthread_mutex_destroy(&mutex->lock);
80 error_exit(err, __func__);
83 void qemu_mutex_lock_impl(QemuMutex *mutex, const char *file, const int line)
87 assert(mutex->initialized);
88 qemu_mutex_pre_lock(mutex, file, line);
89 err = pthread_mutex_lock(&mutex->lock);
91 error_exit(err, __func__);
92 qemu_mutex_post_lock(mutex, file, line);
95 int qemu_mutex_trylock_impl(QemuMutex *mutex, const char *file, const int line)
99 assert(mutex->initialized);
100 err = pthread_mutex_trylock(&mutex->lock);
102 qemu_mutex_post_lock(mutex, file, line);
106 error_exit(err, __func__);
111 void qemu_mutex_unlock_impl(QemuMutex *mutex, const char *file, const int line)
115 assert(mutex->initialized);
116 qemu_mutex_pre_unlock(mutex, file, line);
117 err = pthread_mutex_unlock(&mutex->lock);
119 error_exit(err, __func__);
122 void qemu_rec_mutex_init(QemuRecMutex *mutex)
125 pthread_mutexattr_t attr;
127 pthread_mutexattr_init(&attr);
128 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
129 err = pthread_mutex_init(&mutex->m.lock, &attr);
130 pthread_mutexattr_destroy(&attr);
132 error_exit(err, __func__);
134 mutex->m.initialized = true;
137 void qemu_rec_mutex_destroy(QemuRecMutex *mutex)
139 qemu_mutex_destroy(&mutex->m);
142 void qemu_rec_mutex_lock_impl(QemuRecMutex *mutex, const char *file, int line)
144 qemu_mutex_lock_impl(&mutex->m, file, line);
147 int qemu_rec_mutex_trylock_impl(QemuRecMutex *mutex, const char *file, int line)
149 return qemu_mutex_trylock_impl(&mutex->m, file, line);
152 void qemu_rec_mutex_unlock_impl(QemuRecMutex *mutex, const char *file, int line)
154 qemu_mutex_unlock_impl(&mutex->m, file, line);
157 void qemu_cond_init(QemuCond *cond)
159 pthread_condattr_t attr;
162 err = pthread_condattr_init(&attr);
164 error_exit(err, __func__);
166 #ifdef CONFIG_PTHREAD_CONDATTR_SETCLOCK
167 err = pthread_condattr_setclock(&attr, qemu_timedwait_clockid());
169 error_exit(err, __func__);
172 err = pthread_cond_init(&cond->cond, &attr);
174 error_exit(err, __func__);
176 err = pthread_condattr_destroy(&attr);
178 error_exit(err, __func__);
180 cond->initialized = true;
183 void qemu_cond_destroy(QemuCond *cond)
187 assert(cond->initialized);
188 cond->initialized = false;
189 err = pthread_cond_destroy(&cond->cond);
191 error_exit(err, __func__);
194 void qemu_cond_signal(QemuCond *cond)
198 assert(cond->initialized);
199 err = pthread_cond_signal(&cond->cond);
201 error_exit(err, __func__);
204 void qemu_cond_broadcast(QemuCond *cond)
208 assert(cond->initialized);
209 err = pthread_cond_broadcast(&cond->cond);
211 error_exit(err, __func__);
214 void qemu_cond_wait_impl(QemuCond *cond, QemuMutex *mutex, const char *file, const int line)
218 assert(cond->initialized);
219 qemu_mutex_pre_unlock(mutex, file, line);
220 err = pthread_cond_wait(&cond->cond, &mutex->lock);
221 qemu_mutex_post_lock(mutex, file, line);
223 error_exit(err, __func__);
226 static bool TSA_NO_TSA
227 qemu_cond_timedwait_ts(QemuCond *cond, QemuMutex *mutex, struct timespec *ts,
228 const char *file, const int line)
232 assert(cond->initialized);
233 trace_qemu_mutex_unlock(mutex, file, line);
234 err = pthread_cond_timedwait(&cond->cond, &mutex->lock, ts);
235 trace_qemu_mutex_locked(mutex, file, line);
236 if (err && err != ETIMEDOUT) {
237 error_exit(err, __func__);
239 return err != ETIMEDOUT;
242 bool qemu_cond_timedwait_impl(QemuCond *cond, QemuMutex *mutex, int ms,
243 const char *file, const int line)
247 compute_abs_deadline(&ts, ms);
248 return qemu_cond_timedwait_ts(cond, mutex, &ts, file, line);
251 void qemu_sem_init(QemuSemaphore *sem, int init)
253 qemu_mutex_init(&sem->mutex);
254 qemu_cond_init(&sem->cond);
257 error_exit(EINVAL, __func__);
262 void qemu_sem_destroy(QemuSemaphore *sem)
264 qemu_cond_destroy(&sem->cond);
265 qemu_mutex_destroy(&sem->mutex);
268 void qemu_sem_post(QemuSemaphore *sem)
270 qemu_mutex_lock(&sem->mutex);
271 if (sem->count == UINT_MAX) {
272 error_exit(EINVAL, __func__);
275 qemu_cond_signal(&sem->cond);
277 qemu_mutex_unlock(&sem->mutex);
280 int qemu_sem_timedwait(QemuSemaphore *sem, int ms)
285 compute_abs_deadline(&ts, ms);
286 qemu_mutex_lock(&sem->mutex);
287 while (sem->count == 0) {
291 rc = qemu_cond_timedwait_ts(&sem->cond, &sem->mutex, &ts,
294 if (!rc) { /* timeout */
301 qemu_mutex_unlock(&sem->mutex);
302 return (rc ? 0 : -1);
305 void qemu_sem_wait(QemuSemaphore *sem)
307 qemu_mutex_lock(&sem->mutex);
308 while (sem->count == 0) {
309 qemu_cond_wait(&sem->cond, &sem->mutex);
312 qemu_mutex_unlock(&sem->mutex);
316 #include "qemu/futex.h"
318 static inline void qemu_futex_wake(QemuEvent *ev, int n)
320 assert(ev->initialized);
321 pthread_mutex_lock(&ev->lock);
323 pthread_cond_signal(&ev->cond);
325 pthread_cond_broadcast(&ev->cond);
327 pthread_mutex_unlock(&ev->lock);
330 static inline void qemu_futex_wait(QemuEvent *ev, unsigned val)
332 assert(ev->initialized);
333 pthread_mutex_lock(&ev->lock);
334 if (ev->value == val) {
335 pthread_cond_wait(&ev->cond, &ev->lock);
337 pthread_mutex_unlock(&ev->lock);
341 /* Valid transitions:
342 * - free->set, when setting the event
343 * - busy->set, when setting the event, followed by qemu_futex_wake
344 * - set->free, when resetting the event
345 * - free->busy, when waiting
347 * set->busy does not happen (it can be observed from the outside but
348 * it really is set->free->busy).
350 * busy->free provably cannot happen; to enforce it, the set->free transition
351 * is done with an OR, which becomes a no-op if the event has concurrently
352 * transitioned to free or busy.
359 void qemu_event_init(QemuEvent *ev, bool init)
362 pthread_mutex_init(&ev->lock, NULL);
363 pthread_cond_init(&ev->cond, NULL);
366 ev->value = (init ? EV_SET : EV_FREE);
367 ev->initialized = true;
370 void qemu_event_destroy(QemuEvent *ev)
372 assert(ev->initialized);
373 ev->initialized = false;
375 pthread_mutex_destroy(&ev->lock);
376 pthread_cond_destroy(&ev->cond);
380 void qemu_event_set(QemuEvent *ev)
382 /* qemu_event_set has release semantics, but because it *loads*
383 * ev->value we need a full memory barrier here.
385 assert(ev->initialized);
387 if (qatomic_read(&ev->value) != EV_SET) {
388 if (qatomic_xchg(&ev->value, EV_SET) == EV_BUSY) {
389 /* There were waiters, wake them up. */
390 qemu_futex_wake(ev, INT_MAX);
395 void qemu_event_reset(QemuEvent *ev)
399 assert(ev->initialized);
400 value = qatomic_read(&ev->value);
402 if (value == EV_SET) {
404 * If there was a concurrent reset (or even reset+wait),
405 * do nothing. Otherwise change EV_SET->EV_FREE.
407 qatomic_or(&ev->value, EV_FREE);
411 void qemu_event_wait(QemuEvent *ev)
415 assert(ev->initialized);
416 value = qatomic_read(&ev->value);
418 if (value != EV_SET) {
419 if (value == EV_FREE) {
421 * Leave the event reset and tell qemu_event_set that there
422 * are waiters. No need to retry, because there cannot be
423 * a concurrent busy->free transition. After the CAS, the
424 * event will be either set or busy.
426 if (qatomic_cmpxchg(&ev->value, EV_FREE, EV_BUSY) == EV_SET) {
430 qemu_futex_wait(ev, EV_BUSY);
434 static __thread NotifierList thread_exit;
437 * Note that in this implementation you can register a thread-exit
438 * notifier for the main thread, but it will never be called.
439 * This is OK because main thread exit can only happen when the
440 * entire process is exiting, and the API allows notifiers to not
441 * be called on process exit.
443 void qemu_thread_atexit_add(Notifier *notifier)
445 notifier_list_add(&thread_exit, notifier);
448 void qemu_thread_atexit_remove(Notifier *notifier)
450 notifier_remove(notifier);
453 static void qemu_thread_atexit_notify(void *arg)
456 * Called when non-main thread exits (via qemu_thread_exit()
457 * or by returning from its start routine.)
459 notifier_list_notify(&thread_exit, NULL);
463 void *(*start_routine)(void *);
468 static void *qemu_thread_start(void *args)
470 QemuThreadArgs *qemu_thread_args = args;
471 void *(*start_routine)(void *) = qemu_thread_args->start_routine;
472 void *arg = qemu_thread_args->arg;
475 /* Attempt to set the threads name; note that this is for debug, so
476 * we're not going to fail if we can't set it.
478 if (name_threads && qemu_thread_args->name) {
479 # if defined(CONFIG_PTHREAD_SETNAME_NP_W_TID)
480 pthread_setname_np(pthread_self(), qemu_thread_args->name);
481 # elif defined(CONFIG_PTHREAD_SETNAME_NP_WO_TID)
482 pthread_setname_np(qemu_thread_args->name);
485 QEMU_TSAN_ANNOTATE_THREAD_NAME(qemu_thread_args->name);
486 g_free(qemu_thread_args->name);
487 g_free(qemu_thread_args);
490 * GCC 11 with glibc 2.17 on PowerPC reports
492 * qemu-thread-posix.c:540:5: error: ‘__sigsetjmp’ accessing 656 bytes
493 * in a region of size 528 [-Werror=stringop-overflow=]
494 * 540 | pthread_cleanup_push(qemu_thread_atexit_notify, NULL);
495 * | ^~~~~~~~~~~~~~~~~~~~
497 * which is clearly nonsense.
499 #pragma GCC diagnostic push
501 #pragma GCC diagnostic ignored "-Wstringop-overflow"
504 pthread_cleanup_push(qemu_thread_atexit_notify, NULL);
505 r = start_routine(arg);
506 pthread_cleanup_pop(1);
508 #pragma GCC diagnostic pop
513 void qemu_thread_create(QemuThread *thread, const char *name,
514 void *(*start_routine)(void*),
517 sigset_t set, oldset;
520 QemuThreadArgs *qemu_thread_args;
522 err = pthread_attr_init(&attr);
524 error_exit(err, __func__);
527 if (mode == QEMU_THREAD_DETACHED) {
528 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
531 /* Leave signal handling to the iothread. */
533 /* Blocking the signals can result in undefined behaviour. */
534 sigdelset(&set, SIGSEGV);
535 sigdelset(&set, SIGFPE);
536 sigdelset(&set, SIGILL);
537 /* TODO avoid SIGBUS loss on macOS */
538 pthread_sigmask(SIG_SETMASK, &set, &oldset);
540 qemu_thread_args = g_new0(QemuThreadArgs, 1);
541 qemu_thread_args->name = g_strdup(name);
542 qemu_thread_args->start_routine = start_routine;
543 qemu_thread_args->arg = arg;
545 err = pthread_create(&thread->thread, &attr,
546 qemu_thread_start, qemu_thread_args);
549 error_exit(err, __func__);
551 pthread_sigmask(SIG_SETMASK, &oldset, NULL);
553 pthread_attr_destroy(&attr);
556 int qemu_thread_set_affinity(QemuThread *thread, unsigned long *host_cpus,
559 #if defined(CONFIG_PTHREAD_AFFINITY_NP)
560 const size_t setsize = CPU_ALLOC_SIZE(nbits);
565 cpuset = CPU_ALLOC(nbits);
568 CPU_ZERO_S(setsize, cpuset);
569 value = find_first_bit(host_cpus, nbits);
570 while (value < nbits) {
571 CPU_SET_S(value, setsize, cpuset);
572 value = find_next_bit(host_cpus, nbits, value + 1);
575 err = pthread_setaffinity_np(thread->thread, setsize, cpuset);
583 int qemu_thread_get_affinity(QemuThread *thread, unsigned long **host_cpus,
584 unsigned long *nbits)
586 #if defined(CONFIG_PTHREAD_AFFINITY_NP)
587 unsigned long tmpbits;
592 tmpbits = CPU_SETSIZE;
594 setsize = CPU_ALLOC_SIZE(tmpbits);
595 cpuset = CPU_ALLOC(tmpbits);
598 err = pthread_getaffinity_np(thread->thread, setsize, cpuset);
601 if (err != -EINVAL) {
610 /* Convert the result into a proper bitmap. */
612 *host_cpus = bitmap_new(tmpbits);
613 for (i = 0; i < tmpbits; i++) {
614 if (CPU_ISSET(i, cpuset)) {
615 set_bit(i, *host_cpus);
625 void qemu_thread_get_self(QemuThread *thread)
627 thread->thread = pthread_self();
630 bool qemu_thread_is_self(QemuThread *thread)
632 return pthread_equal(pthread_self(), thread->thread);
635 void qemu_thread_exit(void *retval)
637 pthread_exit(retval);
640 void *qemu_thread_join(QemuThread *thread)
645 err = pthread_join(thread->thread, &ret);
647 error_exit(err, __func__);