Merge remote-tracking branch 'remotes/dgilbert-gitlab/tags/pull-virtiofs-20210315...
[qemu/ar7.git] / util / qemu-thread-posix.c
blobdcff5e7c5d676a357785c9f10f1a955cea7d5cfc
1 /*
2  * Wrappers around mutex/cond/thread functions
3  *
4  * Copyright Red Hat, Inc. 2009
5  *
6  * Author:
7  *  Marcelo Tosatti <mtosatti@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/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");
30     }
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;
49     }
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;
94     }
95     if (err != EBUSY) {
96         error_exit(err, __func__);
97     }
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__);
123     }
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__);
193     }
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__);
205     }
206     rc = pthread_cond_init(&sem->cond, NULL);
207     if (rc != 0) {
208         error_exit(rc, __func__);
209     }
210     if (init < 0) {
211         error_exit(EINVAL, __func__);
212     }
213     sem->count = init;
214 #else
215     rc = sem_init(&sem->sem, 0, init);
216     if (rc < 0) {
217         error_exit(errno, __func__);
218     }
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__);
233     }
234     rc = pthread_mutex_destroy(&sem->lock);
235     if (rc < 0) {
236         error_exit(rc, __func__);
237     }
238 #else
239     rc = sem_destroy(&sem->sem);
240     if (rc < 0) {
241         error_exit(errno, __func__);
242     }
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);
258     }
259     pthread_mutex_unlock(&sem->lock);
260     if (rc != 0) {
261         error_exit(rc, __func__);
262     }
263 #else
264     rc = sem_post(&sem->sem);
265     if (rc < 0) {
266         error_exit(errno, __func__);
267     }
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;
285         }
286         if (rc != 0) {
287             error_exit(rc, __func__);
288         }
289     }
290     if (rc != ETIMEDOUT) {
291         --sem->count;
292     }
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;
303         }
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;
311         }
312     }
313     if (rc < 0) {
314         error_exit(errno, __func__);
315     }
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__);
331         }
332     }
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__);
341     }
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);
356     }
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);
366     }
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.
383  */
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.
414      */
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);
421         }
422     }
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) {
433         /*
434          * If there was a concurrent reset (or even reset+wait),
435          * do nothing.  Otherwise change EV_SET->EV_FREE.
436          */
437         qatomic_or(&ev->value, EV_FREE);
438     }
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) {
450             /*
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.
455              */
456             if (qatomic_cmpxchg(&ev->value, EV_FREE, EV_BUSY) == EV_SET) {
457                 return;
458             }
459         }
460         qemu_futex_wait(ev, EV_BUSY);
461     }
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.
472  */
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)
485     /*
486      * Called when non-main thread exits (via qemu_thread_exit()
487      * or by returning from its start routine.)
488      */
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.
508      */
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
515     }
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__);
538     }
540     if (mode == QEMU_THREAD_DETACHED) {
541         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
542     }
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__);
592     }
593     return ret;