]> git.proxmox.com Git - mirror_qemu.git/blame - util/qemu-thread-posix.c
target/m68k: call gen_raise_exception() directly if single-stepping in gen_jmp_tb()
[mirror_qemu.git] / util / qemu-thread-posix.c
CommitLineData
e5d355d1
AL
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 */
aafd7584 13#include "qemu/osdep.h"
1de7afc9 14#include "qemu/thread.h"
c7c4d063 15#include "qemu/atomic.h"
ef57137f 16#include "qemu/notify.h"
f1aff7aa 17#include "qemu-thread-common.h"
ce9f0e5b 18#include "qemu/tsan.h"
e5d355d1 19
8f480de0
DDAG
20static bool name_threads;
21
22void qemu_thread_naming(bool enable)
23{
24 name_threads = enable;
5c312079
DDAG
25
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
8f480de0
DDAG
32}
33
e5d355d1
AL
34static void error_exit(int err, const char *msg)
35{
36 fprintf(stderr, "qemu: %s: %s\n", msg, strerror(err));
53380ac3 37 abort();
e5d355d1
AL
38}
39
3dcc9c6e
YK
40static void compute_abs_deadline(struct timespec *ts, int ms)
41{
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 }
50}
51
e5d355d1
AL
52void qemu_mutex_init(QemuMutex *mutex)
53{
54 int err;
55
24fa9049 56 err = pthread_mutex_init(&mutex->lock, NULL);
e5d355d1
AL
57 if (err)
58 error_exit(err, __func__);
f1aff7aa 59 qemu_mutex_post_init(mutex);
e5d355d1
AL
60}
61
313b1d69
CC
62void qemu_mutex_destroy(QemuMutex *mutex)
63{
64 int err;
65
c096358e
FZ
66 assert(mutex->initialized);
67 mutex->initialized = false;
313b1d69
CC
68 err = pthread_mutex_destroy(&mutex->lock);
69 if (err)
70 error_exit(err, __func__);
71}
72
6c27a0de 73void qemu_mutex_lock_impl(QemuMutex *mutex, const char *file, const int line)
e5d355d1
AL
74{
75 int err;
76
c096358e 77 assert(mutex->initialized);
f1aff7aa 78 qemu_mutex_pre_lock(mutex, file, line);
e5d355d1
AL
79 err = pthread_mutex_lock(&mutex->lock);
80 if (err)
81 error_exit(err, __func__);
f1aff7aa 82 qemu_mutex_post_lock(mutex, file, line);
e5d355d1
AL
83}
84
6c27a0de 85int qemu_mutex_trylock_impl(QemuMutex *mutex, const char *file, const int line)
e5d355d1 86{
31f5a726
JRZ
87 int err;
88
c096358e 89 assert(mutex->initialized);
31f5a726
JRZ
90 err = pthread_mutex_trylock(&mutex->lock);
91 if (err == 0) {
f1aff7aa 92 qemu_mutex_post_lock(mutex, file, line);
31f5a726
JRZ
93 return 0;
94 }
95 if (err != EBUSY) {
96 error_exit(err, __func__);
97 }
98 return -EBUSY;
e5d355d1
AL
99}
100
6c27a0de 101void qemu_mutex_unlock_impl(QemuMutex *mutex, const char *file, const int line)
e5d355d1
AL
102{
103 int err;
104
c096358e 105 assert(mutex->initialized);
f1aff7aa 106 qemu_mutex_pre_unlock(mutex, file, line);
e5d355d1
AL
107 err = pthread_mutex_unlock(&mutex->lock);
108 if (err)
109 error_exit(err, __func__);
110}
111
feadec63
PB
112void qemu_rec_mutex_init(QemuRecMutex *mutex)
113{
114 int err;
115 pthread_mutexattr_t attr;
116
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 }
c096358e 124 mutex->initialized = true;
feadec63
PB
125}
126
e5d355d1
AL
127void qemu_cond_init(QemuCond *cond)
128{
129 int err;
130
131 err = pthread_cond_init(&cond->cond, NULL);
132 if (err)
133 error_exit(err, __func__);
c096358e 134 cond->initialized = true;
e5d355d1
AL
135}
136
313b1d69
CC
137void qemu_cond_destroy(QemuCond *cond)
138{
139 int err;
140
c096358e
FZ
141 assert(cond->initialized);
142 cond->initialized = false;
313b1d69
CC
143 err = pthread_cond_destroy(&cond->cond);
144 if (err)
145 error_exit(err, __func__);
146}
147
e5d355d1
AL
148void qemu_cond_signal(QemuCond *cond)
149{
150 int err;
151
c096358e 152 assert(cond->initialized);
e5d355d1
AL
153 err = pthread_cond_signal(&cond->cond);
154 if (err)
155 error_exit(err, __func__);
156}
157
158void qemu_cond_broadcast(QemuCond *cond)
159{
160 int err;
161
c096358e 162 assert(cond->initialized);
e5d355d1
AL
163 err = pthread_cond_broadcast(&cond->cond);
164 if (err)
165 error_exit(err, __func__);
166}
167
6c27a0de 168void qemu_cond_wait_impl(QemuCond *cond, QemuMutex *mutex, const char *file, const int line)
e5d355d1
AL
169{
170 int err;
171
c096358e 172 assert(cond->initialized);
f1aff7aa 173 qemu_mutex_pre_unlock(mutex, file, line);
e5d355d1 174 err = pthread_cond_wait(&cond->cond, &mutex->lock);
f1aff7aa 175 qemu_mutex_post_lock(mutex, file, line);
e5d355d1
AL
176 if (err)
177 error_exit(err, __func__);
178}
179
3dcc9c6e
YK
180bool qemu_cond_timedwait_impl(QemuCond *cond, QemuMutex *mutex, int ms,
181 const char *file, const int line)
182{
183 int err;
184 struct timespec ts;
185
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;
195}
196
38b14db3
PB
197void qemu_sem_init(QemuSemaphore *sem, int init)
198{
199 int rc;
200
401bc051 201#ifndef CONFIG_SEM_TIMEDWAIT
c166cb72
PB
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
38b14db3
PB
215 rc = sem_init(&sem->sem, 0, init);
216 if (rc < 0) {
217 error_exit(errno, __func__);
218 }
c166cb72 219#endif
c096358e 220 sem->initialized = true;
38b14db3
PB
221}
222
223void qemu_sem_destroy(QemuSemaphore *sem)
224{
225 int rc;
226
c096358e
FZ
227 assert(sem->initialized);
228 sem->initialized = false;
401bc051 229#ifndef CONFIG_SEM_TIMEDWAIT
c166cb72
PB
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
38b14db3
PB
239 rc = sem_destroy(&sem->sem);
240 if (rc < 0) {
241 error_exit(errno, __func__);
242 }
c166cb72 243#endif
38b14db3
PB
244}
245
246void qemu_sem_post(QemuSemaphore *sem)
247{
248 int rc;
249
c096358e 250 assert(sem->initialized);
401bc051 251#ifndef CONFIG_SEM_TIMEDWAIT
c166cb72 252 pthread_mutex_lock(&sem->lock);
79761c66 253 if (sem->count == UINT_MAX) {
c166cb72 254 rc = EINVAL;
c166cb72 255 } else {
79761c66
IT
256 sem->count++;
257 rc = pthread_cond_signal(&sem->cond);
c166cb72
PB
258 }
259 pthread_mutex_unlock(&sem->lock);
260 if (rc != 0) {
261 error_exit(rc, __func__);
262 }
263#else
38b14db3
PB
264 rc = sem_post(&sem->sem);
265 if (rc < 0) {
266 error_exit(errno, __func__);
267 }
c166cb72
PB
268#endif
269}
270
38b14db3
PB
271int qemu_sem_timedwait(QemuSemaphore *sem, int ms)
272{
273 int rc;
c166cb72
PB
274 struct timespec ts;
275
c096358e 276 assert(sem->initialized);
401bc051 277#ifndef CONFIG_SEM_TIMEDWAIT
79761c66 278 rc = 0;
c166cb72
PB
279 compute_abs_deadline(&ts, ms);
280 pthread_mutex_lock(&sem->lock);
79761c66 281 while (sem->count == 0) {
c166cb72
PB
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 }
79761c66
IT
290 if (rc != ETIMEDOUT) {
291 --sem->count;
292 }
c166cb72
PB
293 pthread_mutex_unlock(&sem->lock);
294 return (rc == ETIMEDOUT ? -1 : 0);
295#else
38b14db3
PB
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 {
c166cb72 305 compute_abs_deadline(&ts, ms);
38b14db3
PB
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;
c166cb72 317#endif
38b14db3
PB
318}
319
320void qemu_sem_wait(QemuSemaphore *sem)
321{
79761c66
IT
322 int rc;
323
c096358e 324 assert(sem->initialized);
401bc051 325#ifndef CONFIG_SEM_TIMEDWAIT
c166cb72 326 pthread_mutex_lock(&sem->lock);
79761c66
IT
327 while (sem->count == 0) {
328 rc = pthread_cond_wait(&sem->cond, &sem->lock);
329 if (rc != 0) {
330 error_exit(rc, __func__);
331 }
c166cb72 332 }
79761c66 333 --sem->count;
c166cb72
PB
334 pthread_mutex_unlock(&sem->lock);
335#else
38b14db3
PB
336 do {
337 rc = sem_wait(&sem->sem);
338 } while (rc == -1 && errno == EINTR);
339 if (rc < 0) {
340 error_exit(errno, __func__);
341 }
c166cb72 342#endif
38b14db3
PB
343}
344
c7c4d063 345#ifdef __linux__
fbcc3e50 346#include "qemu/futex.h"
c7c4d063 347#else
fbcc3e50 348static inline void qemu_futex_wake(QemuEvent *ev, int n)
c7c4d063 349{
c096358e 350 assert(ev->initialized);
158ef8cb 351 pthread_mutex_lock(&ev->lock);
c7c4d063
PB
352 if (n == 1) {
353 pthread_cond_signal(&ev->cond);
354 } else {
355 pthread_cond_broadcast(&ev->cond);
356 }
158ef8cb 357 pthread_mutex_unlock(&ev->lock);
c7c4d063
PB
358}
359
fbcc3e50 360static inline void qemu_futex_wait(QemuEvent *ev, unsigned val)
c7c4d063 361{
c096358e 362 assert(ev->initialized);
c7c4d063
PB
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);
368}
369#endif
370
371/* Valid transitions:
372 * - free->set, when setting the event
fbcc3e50 373 * - busy->set, when setting the event, followed by qemu_futex_wake
c7c4d063
PB
374 * - set->free, when resetting the event
375 * - free->busy, when waiting
376 *
377 * set->busy does not happen (it can be observed from the outside but
378 * it really is set->free->busy).
379 *
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 */
384
385#define EV_SET 0
386#define EV_FREE 1
387#define EV_BUSY -1
388
389void qemu_event_init(QemuEvent *ev, bool init)
390{
391#ifndef __linux__
392 pthread_mutex_init(&ev->lock, NULL);
393 pthread_cond_init(&ev->cond, NULL);
394#endif
395
396 ev->value = (init ? EV_SET : EV_FREE);
c096358e 397 ev->initialized = true;
c7c4d063
PB
398}
399
400void qemu_event_destroy(QemuEvent *ev)
401{
c096358e
FZ
402 assert(ev->initialized);
403 ev->initialized = false;
c7c4d063
PB
404#ifndef __linux__
405 pthread_mutex_destroy(&ev->lock);
406 pthread_cond_destroy(&ev->cond);
407#endif
408}
409
410void qemu_event_set(QemuEvent *ev)
411{
374293ca
PB
412 /* qemu_event_set has release semantics, but because it *loads*
413 * ev->value we need a full memory barrier here.
414 */
c096358e 415 assert(ev->initialized);
374293ca 416 smp_mb();
d73415a3
SH
417 if (qatomic_read(&ev->value) != EV_SET) {
418 if (qatomic_xchg(&ev->value, EV_SET) == EV_BUSY) {
c7c4d063 419 /* There were waiters, wake them up. */
fbcc3e50 420 qemu_futex_wake(ev, INT_MAX);
c7c4d063
PB
421 }
422 }
423}
424
425void qemu_event_reset(QemuEvent *ev)
426{
374293ca
PB
427 unsigned value;
428
c096358e 429 assert(ev->initialized);
d73415a3 430 value = qatomic_read(&ev->value);
374293ca
PB
431 smp_mb_acquire();
432 if (value == EV_SET) {
c7c4d063
PB
433 /*
434 * If there was a concurrent reset (or even reset+wait),
435 * do nothing. Otherwise change EV_SET->EV_FREE.
436 */
d73415a3 437 qatomic_or(&ev->value, EV_FREE);
c7c4d063
PB
438 }
439}
440
441void qemu_event_wait(QemuEvent *ev)
442{
443 unsigned value;
444
c096358e 445 assert(ev->initialized);
d73415a3 446 value = qatomic_read(&ev->value);
374293ca 447 smp_mb_acquire();
c7c4d063
PB
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
67cc32eb 453 * a concurrent busy->free transition. After the CAS, the
c7c4d063
PB
454 * event will be either set or busy.
455 */
d73415a3 456 if (qatomic_cmpxchg(&ev->value, EV_FREE, EV_BUSY) == EV_SET) {
c7c4d063
PB
457 return;
458 }
459 }
fbcc3e50 460 qemu_futex_wait(ev, EV_BUSY);
c7c4d063
PB
461 }
462}
463
a458774a 464static __thread NotifierList thread_exit;
ef57137f 465
a458774a
PM
466/*
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 */
ef57137f
PB
473void qemu_thread_atexit_add(Notifier *notifier)
474{
a458774a 475 notifier_list_add(&thread_exit, notifier);
ef57137f
PB
476}
477
478void qemu_thread_atexit_remove(Notifier *notifier)
479{
ef57137f 480 notifier_remove(notifier);
ef57137f
PB
481}
482
a458774a 483static void qemu_thread_atexit_notify(void *arg)
ef57137f 484{
a458774a
PM
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);
ef57137f
PB
490}
491
68a93982 492typedef struct {
493 void *(*start_routine)(void *);
494 void *arg;
495 char *name;
496} QemuThreadArgs;
497
498static void *qemu_thread_start(void *args)
499{
500 QemuThreadArgs *qemu_thread_args = args;
501 void *(*start_routine)(void *) = qemu_thread_args->start_routine;
502 void *arg = qemu_thread_args->arg;
a458774a 503 void *r;
68a93982 504
479a5747 505#ifdef CONFIG_THREAD_SETNAME_BYTHREAD
68a93982 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 */
d820fa5b 509 if (name_threads && qemu_thread_args->name) {
479a5747 510# if defined(CONFIG_PTHREAD_SETNAME_NP_W_TID)
d820fa5b 511 pthread_setname_np(pthread_self(), qemu_thread_args->name);
479a5747
RB
512# elif defined(CONFIG_PTHREAD_SETNAME_NP_WO_TID)
513 pthread_setname_np(qemu_thread_args->name);
514# endif
d820fa5b
PX
515 }
516#endif
ce9f0e5b 517 QEMU_TSAN_ANNOTATE_THREAD_NAME(qemu_thread_args->name);
68a93982 518 g_free(qemu_thread_args->name);
519 g_free(qemu_thread_args);
a458774a
PM
520 pthread_cleanup_push(qemu_thread_atexit_notify, NULL);
521 r = start_routine(arg);
522 pthread_cleanup_pop(1);
523 return r;
5c312079
DDAG
524}
525
4900116e 526void qemu_thread_create(QemuThread *thread, const char *name,
e5d355d1 527 void *(*start_routine)(void*),
cf218714 528 void *arg, int mode)
e5d355d1 529{
cf218714 530 sigset_t set, oldset;
e5d355d1 531 int err;
8763046b 532 pthread_attr_t attr;
d820fa5b 533 QemuThreadArgs *qemu_thread_args;
e5d355d1 534
8763046b
JK
535 err = pthread_attr_init(&attr);
536 if (err) {
537 error_exit(err, __func__);
538 }
55541c8a 539
68a93982 540 if (mode == QEMU_THREAD_DETACHED) {
541 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
542 }
543
cf218714 544 /* Leave signal handling to the iothread. */
55541c8a 545 sigfillset(&set);
21a43af0
RB
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 */
55541c8a 551 pthread_sigmask(SIG_SETMASK, &set, &oldset);
55541c8a 552
d820fa5b
PX
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;
557
558 err = pthread_create(&thread->thread, &attr,
559 qemu_thread_start, qemu_thread_args);
4900116e 560
68a93982 561 if (err)
562 error_exit(err, __func__);
563
55541c8a 564 pthread_sigmask(SIG_SETMASK, &oldset, NULL);
8763046b
JK
565
566 pthread_attr_destroy(&attr);
e5d355d1
AL
567}
568
b7680cb6 569void qemu_thread_get_self(QemuThread *thread)
e5d355d1
AL
570{
571 thread->thread = pthread_self();
572}
573
2d797b65 574bool qemu_thread_is_self(QemuThread *thread)
e5d355d1 575{
b7680cb6 576 return pthread_equal(pthread_self(), thread->thread);
e5d355d1
AL
577}
578
313b1d69
CC
579void qemu_thread_exit(void *retval)
580{
581 pthread_exit(retval);
582}
8763046b
JK
583
584void *qemu_thread_join(QemuThread *thread)
585{
586 int err;
587 void *ret;
588
589 err = pthread_join(thread->thread, &ret);
590 if (err) {
591 error_exit(err, __func__);
592 }
593 return ret;
594}