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" 19 #include "qemu/bitmap.h" 20 21 #ifdef CONFIG_PTHREAD_SET_NAME_NP 22 #include <pthread_np.h> 23 #endif 24 25 static bool name_threads; 26 27 void qemu_thread_naming(bool enable) 28 { 29 name_threads = enable; 30 31 #if !defined CONFIG_PTHREAD_SETNAME_NP_W_TID && \ 32 !defined CONFIG_PTHREAD_SETNAME_NP_WO_TID && \ 33 !defined CONFIG_PTHREAD_SET_NAME_NP 34 /* This is a debugging option, not fatal */ 35 if (enable) { 36 fprintf(stderr, "qemu: thread naming not supported on this host\n"); 37 } 38 #endif 39 } 40 41 static void error_exit(int err, const char *msg) 42 { 43 fprintf(stderr, "qemu: %s: %s\n", msg, strerror(err)); 44 abort(); 45 } 46 47 static inline clockid_t qemu_timedwait_clockid(void) 48 { 49 #ifdef CONFIG_PTHREAD_CONDATTR_SETCLOCK 50 return CLOCK_MONOTONIC; 51 #else 52 return CLOCK_REALTIME; 53 #endif 54 } 55 56 static void compute_abs_deadline(struct timespec *ts, int ms) 57 { 58 clock_gettime(qemu_timedwait_clockid(), ts); 59 ts->tv_nsec += (ms % 1000) * 1000000; 60 ts->tv_sec += ms / 1000; 61 if (ts->tv_nsec >= 1000000000) { 62 ts->tv_sec++; 63 ts->tv_nsec -= 1000000000; 64 } 65 } 66 67 void qemu_mutex_init(QemuMutex *mutex) 68 { 69 int err; 70 71 err = pthread_mutex_init(&mutex->lock, NULL); 72 if (err) 73 error_exit(err, __func__); 74 qemu_mutex_post_init(mutex); 75 } 76 77 void qemu_mutex_destroy(QemuMutex *mutex) 78 { 79 int err; 80 81 assert(mutex->initialized); 82 mutex->initialized = false; 83 err = pthread_mutex_destroy(&mutex->lock); 84 if (err) 85 error_exit(err, __func__); 86 } 87 88 void qemu_mutex_lock_impl(QemuMutex *mutex, const char *file, const int line) 89 { 90 int err; 91 92 assert(mutex->initialized); 93 qemu_mutex_pre_lock(mutex, file, line); 94 err = pthread_mutex_lock(&mutex->lock); 95 if (err) 96 error_exit(err, __func__); 97 qemu_mutex_post_lock(mutex, file, line); 98 } 99 100 int qemu_mutex_trylock_impl(QemuMutex *mutex, const char *file, const int line) 101 { 102 int err; 103 104 assert(mutex->initialized); 105 err = pthread_mutex_trylock(&mutex->lock); 106 if (err == 0) { 107 qemu_mutex_post_lock(mutex, file, line); 108 return 0; 109 } 110 if (err != EBUSY) { 111 error_exit(err, __func__); 112 } 113 return -EBUSY; 114 } 115 116 void qemu_mutex_unlock_impl(QemuMutex *mutex, const char *file, const int line) 117 { 118 int err; 119 120 assert(mutex->initialized); 121 qemu_mutex_pre_unlock(mutex, file, line); 122 err = pthread_mutex_unlock(&mutex->lock); 123 if (err) 124 error_exit(err, __func__); 125 } 126 127 void qemu_rec_mutex_init(QemuRecMutex *mutex) 128 { 129 int err; 130 pthread_mutexattr_t attr; 131 132 pthread_mutexattr_init(&attr); 133 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); 134 err = pthread_mutex_init(&mutex->m.lock, &attr); 135 pthread_mutexattr_destroy(&attr); 136 if (err) { 137 error_exit(err, __func__); 138 } 139 mutex->m.initialized = true; 140 } 141 142 void qemu_rec_mutex_destroy(QemuRecMutex *mutex) 143 { 144 qemu_mutex_destroy(&mutex->m); 145 } 146 147 void qemu_rec_mutex_lock_impl(QemuRecMutex *mutex, const char *file, int line) 148 { 149 qemu_mutex_lock_impl(&mutex->m, file, line); 150 } 151 152 int qemu_rec_mutex_trylock_impl(QemuRecMutex *mutex, const char *file, int line) 153 { 154 return qemu_mutex_trylock_impl(&mutex->m, file, line); 155 } 156 157 void qemu_rec_mutex_unlock_impl(QemuRecMutex *mutex, const char *file, int line) 158 { 159 qemu_mutex_unlock_impl(&mutex->m, file, line); 160 } 161 162 void qemu_cond_init(QemuCond *cond) 163 { 164 pthread_condattr_t attr; 165 int err; 166 167 err = pthread_condattr_init(&attr); 168 if (err) { 169 error_exit(err, __func__); 170 } 171 #ifdef CONFIG_PTHREAD_CONDATTR_SETCLOCK 172 err = pthread_condattr_setclock(&attr, qemu_timedwait_clockid()); 173 if (err) { 174 error_exit(err, __func__); 175 } 176 #endif 177 err = pthread_cond_init(&cond->cond, &attr); 178 if (err) { 179 error_exit(err, __func__); 180 } 181 err = pthread_condattr_destroy(&attr); 182 if (err) { 183 error_exit(err, __func__); 184 } 185 cond->initialized = true; 186 } 187 188 void qemu_cond_destroy(QemuCond *cond) 189 { 190 int err; 191 192 assert(cond->initialized); 193 cond->initialized = false; 194 err = pthread_cond_destroy(&cond->cond); 195 if (err) 196 error_exit(err, __func__); 197 } 198 199 void qemu_cond_signal(QemuCond *cond) 200 { 201 int err; 202 203 assert(cond->initialized); 204 err = pthread_cond_signal(&cond->cond); 205 if (err) 206 error_exit(err, __func__); 207 } 208 209 void qemu_cond_broadcast(QemuCond *cond) 210 { 211 int err; 212 213 assert(cond->initialized); 214 err = pthread_cond_broadcast(&cond->cond); 215 if (err) 216 error_exit(err, __func__); 217 } 218 219 void qemu_cond_wait_impl(QemuCond *cond, QemuMutex *mutex, const char *file, const int line) 220 { 221 int err; 222 223 assert(cond->initialized); 224 qemu_mutex_pre_unlock(mutex, file, line); 225 err = pthread_cond_wait(&cond->cond, &mutex->lock); 226 qemu_mutex_post_lock(mutex, file, line); 227 if (err) 228 error_exit(err, __func__); 229 } 230 231 static bool TSA_NO_TSA 232 qemu_cond_timedwait_ts(QemuCond *cond, QemuMutex *mutex, struct timespec *ts, 233 const char *file, const int line) 234 { 235 int err; 236 237 assert(cond->initialized); 238 trace_qemu_mutex_unlock(mutex, file, line); 239 err = pthread_cond_timedwait(&cond->cond, &mutex->lock, ts); 240 trace_qemu_mutex_locked(mutex, file, line); 241 if (err && err != ETIMEDOUT) { 242 error_exit(err, __func__); 243 } 244 return err != ETIMEDOUT; 245 } 246 247 bool qemu_cond_timedwait_impl(QemuCond *cond, QemuMutex *mutex, int ms, 248 const char *file, const int line) 249 { 250 struct timespec ts; 251 252 compute_abs_deadline(&ts, ms); 253 return qemu_cond_timedwait_ts(cond, mutex, &ts, file, line); 254 } 255 256 void qemu_sem_init(QemuSemaphore *sem, int init) 257 { 258 qemu_mutex_init(&sem->mutex); 259 qemu_cond_init(&sem->cond); 260 261 if (init < 0) { 262 error_exit(EINVAL, __func__); 263 } 264 sem->count = init; 265 } 266 267 void qemu_sem_destroy(QemuSemaphore *sem) 268 { 269 qemu_cond_destroy(&sem->cond); 270 qemu_mutex_destroy(&sem->mutex); 271 } 272 273 void qemu_sem_post(QemuSemaphore *sem) 274 { 275 qemu_mutex_lock(&sem->mutex); 276 if (sem->count == UINT_MAX) { 277 error_exit(EINVAL, __func__); 278 } else { 279 sem->count++; 280 qemu_cond_signal(&sem->cond); 281 } 282 qemu_mutex_unlock(&sem->mutex); 283 } 284 285 int qemu_sem_timedwait(QemuSemaphore *sem, int ms) 286 { 287 bool rc = true; 288 struct timespec ts; 289 290 compute_abs_deadline(&ts, ms); 291 qemu_mutex_lock(&sem->mutex); 292 while (sem->count == 0) { 293 if (ms == 0) { 294 rc = false; 295 } else { 296 rc = qemu_cond_timedwait_ts(&sem->cond, &sem->mutex, &ts, 297 __FILE__, __LINE__); 298 } 299 if (!rc) { /* timeout */ 300 break; 301 } 302 } 303 if (rc) { 304 --sem->count; 305 } 306 qemu_mutex_unlock(&sem->mutex); 307 return (rc ? 0 : -1); 308 } 309 310 void qemu_sem_wait(QemuSemaphore *sem) 311 { 312 qemu_mutex_lock(&sem->mutex); 313 while (sem->count == 0) { 314 qemu_cond_wait(&sem->cond, &sem->mutex); 315 } 316 --sem->count; 317 qemu_mutex_unlock(&sem->mutex); 318 } 319 320 #ifdef __linux__ 321 #include "qemu/futex.h" 322 #else 323 static inline void qemu_futex_wake(QemuEvent *ev, int n) 324 { 325 assert(ev->initialized); 326 pthread_mutex_lock(&ev->lock); 327 if (n == 1) { 328 pthread_cond_signal(&ev->cond); 329 } else { 330 pthread_cond_broadcast(&ev->cond); 331 } 332 pthread_mutex_unlock(&ev->lock); 333 } 334 335 static inline void qemu_futex_wait(QemuEvent *ev, unsigned val) 336 { 337 assert(ev->initialized); 338 pthread_mutex_lock(&ev->lock); 339 if (ev->value == val) { 340 pthread_cond_wait(&ev->cond, &ev->lock); 341 } 342 pthread_mutex_unlock(&ev->lock); 343 } 344 #endif 345 346 /* Valid transitions: 347 * - free->set, when setting the event 348 * - busy->set, when setting the event, followed by qemu_futex_wake 349 * - set->free, when resetting the event 350 * - free->busy, when waiting 351 * 352 * set->busy does not happen (it can be observed from the outside but 353 * it really is set->free->busy). 354 * 355 * busy->free provably cannot happen; to enforce it, the set->free transition 356 * is done with an OR, which becomes a no-op if the event has concurrently 357 * transitioned to free or busy. 358 */ 359 360 #define EV_SET 0 361 #define EV_FREE 1 362 #define EV_BUSY -1 363 364 void qemu_event_init(QemuEvent *ev, bool init) 365 { 366 #ifndef __linux__ 367 pthread_mutex_init(&ev->lock, NULL); 368 pthread_cond_init(&ev->cond, NULL); 369 #endif 370 371 ev->value = (init ? EV_SET : EV_FREE); 372 ev->initialized = true; 373 } 374 375 void qemu_event_destroy(QemuEvent *ev) 376 { 377 assert(ev->initialized); 378 ev->initialized = false; 379 #ifndef __linux__ 380 pthread_mutex_destroy(&ev->lock); 381 pthread_cond_destroy(&ev->cond); 382 #endif 383 } 384 385 void qemu_event_set(QemuEvent *ev) 386 { 387 /* qemu_event_set has release semantics, but because it *loads* 388 * ev->value we need a full memory barrier here. 389 */ 390 assert(ev->initialized); 391 smp_mb(); 392 if (qatomic_read(&ev->value) != EV_SET) { 393 if (qatomic_xchg(&ev->value, EV_SET) == EV_BUSY) { 394 /* There were waiters, wake them up. */ 395 qemu_futex_wake(ev, INT_MAX); 396 } 397 } 398 } 399 400 void qemu_event_reset(QemuEvent *ev) 401 { 402 unsigned value; 403 404 assert(ev->initialized); 405 value = qatomic_read(&ev->value); 406 smp_mb_acquire(); 407 if (value == EV_SET) { 408 /* 409 * If there was a concurrent reset (or even reset+wait), 410 * do nothing. Otherwise change EV_SET->EV_FREE. 411 */ 412 qatomic_or(&ev->value, EV_FREE); 413 } 414 } 415 416 void qemu_event_wait(QemuEvent *ev) 417 { 418 unsigned value; 419 420 assert(ev->initialized); 421 value = qatomic_read(&ev->value); 422 smp_mb_acquire(); 423 if (value != EV_SET) { 424 if (value == EV_FREE) { 425 /* 426 * Leave the event reset and tell qemu_event_set that there 427 * are waiters. No need to retry, because there cannot be 428 * a concurrent busy->free transition. After the CAS, the 429 * event will be either set or busy. 430 */ 431 if (qatomic_cmpxchg(&ev->value, EV_FREE, EV_BUSY) == EV_SET) { 432 return; 433 } 434 } 435 qemu_futex_wait(ev, EV_BUSY); 436 } 437 } 438 439 static __thread NotifierList thread_exit; 440 441 /* 442 * Note that in this implementation you can register a thread-exit 443 * notifier for the main thread, but it will never be called. 444 * This is OK because main thread exit can only happen when the 445 * entire process is exiting, and the API allows notifiers to not 446 * be called on process exit. 447 */ 448 void qemu_thread_atexit_add(Notifier *notifier) 449 { 450 notifier_list_add(&thread_exit, notifier); 451 } 452 453 void qemu_thread_atexit_remove(Notifier *notifier) 454 { 455 notifier_remove(notifier); 456 } 457 458 static void qemu_thread_atexit_notify(void *arg) 459 { 460 /* 461 * Called when non-main thread exits (via qemu_thread_exit() 462 * or by returning from its start routine.) 463 */ 464 notifier_list_notify(&thread_exit, NULL); 465 } 466 467 typedef struct { 468 void *(*start_routine)(void *); 469 void *arg; 470 char *name; 471 } QemuThreadArgs; 472 473 static void *qemu_thread_start(void *args) 474 { 475 QemuThreadArgs *qemu_thread_args = args; 476 void *(*start_routine)(void *) = qemu_thread_args->start_routine; 477 void *arg = qemu_thread_args->arg; 478 void *r; 479 480 /* Attempt to set the threads name; note that this is for debug, so 481 * we're not going to fail if we can't set it. 482 */ 483 if (name_threads && qemu_thread_args->name) { 484 # if defined(CONFIG_PTHREAD_SETNAME_NP_W_TID) 485 pthread_setname_np(pthread_self(), qemu_thread_args->name); 486 # elif defined(CONFIG_PTHREAD_SETNAME_NP_WO_TID) 487 pthread_setname_np(qemu_thread_args->name); 488 # elif defined(CONFIG_PTHREAD_SET_NAME_NP) 489 pthread_set_name_np(pthread_self(), qemu_thread_args->name); 490 # endif 491 } 492 QEMU_TSAN_ANNOTATE_THREAD_NAME(qemu_thread_args->name); 493 g_free(qemu_thread_args->name); 494 g_free(qemu_thread_args); 495 496 /* 497 * GCC 11 with glibc 2.17 on PowerPC reports 498 * 499 * qemu-thread-posix.c:540:5: error: ‘__sigsetjmp’ accessing 656 bytes 500 * in a region of size 528 [-Werror=stringop-overflow=] 501 * 540 | pthread_cleanup_push(qemu_thread_atexit_notify, NULL); 502 * | ^~~~~~~~~~~~~~~~~~~~ 503 * 504 * which is clearly nonsense. 505 */ 506 #pragma GCC diagnostic push 507 #ifndef __clang__ 508 #pragma GCC diagnostic ignored "-Wstringop-overflow" 509 #endif 510 511 pthread_cleanup_push(qemu_thread_atexit_notify, NULL); 512 r = start_routine(arg); 513 pthread_cleanup_pop(1); 514 515 #pragma GCC diagnostic pop 516 517 return r; 518 } 519 520 void qemu_thread_create(QemuThread *thread, const char *name, 521 void *(*start_routine)(void*), 522 void *arg, int mode) 523 { 524 sigset_t set, oldset; 525 int err; 526 pthread_attr_t attr; 527 QemuThreadArgs *qemu_thread_args; 528 529 err = pthread_attr_init(&attr); 530 if (err) { 531 error_exit(err, __func__); 532 } 533 534 if (mode == QEMU_THREAD_DETACHED) { 535 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 536 } 537 538 /* Leave signal handling to the iothread. */ 539 sigfillset(&set); 540 /* Blocking the signals can result in undefined behaviour. */ 541 sigdelset(&set, SIGSEGV); 542 sigdelset(&set, SIGFPE); 543 sigdelset(&set, SIGILL); 544 /* TODO avoid SIGBUS loss on macOS */ 545 pthread_sigmask(SIG_SETMASK, &set, &oldset); 546 547 qemu_thread_args = g_new0(QemuThreadArgs, 1); 548 qemu_thread_args->name = g_strdup(name); 549 qemu_thread_args->start_routine = start_routine; 550 qemu_thread_args->arg = arg; 551 552 err = pthread_create(&thread->thread, &attr, 553 qemu_thread_start, qemu_thread_args); 554 555 if (err) 556 error_exit(err, __func__); 557 558 pthread_sigmask(SIG_SETMASK, &oldset, NULL); 559 560 pthread_attr_destroy(&attr); 561 } 562 563 int qemu_thread_set_affinity(QemuThread *thread, unsigned long *host_cpus, 564 unsigned long nbits) 565 { 566 #if defined(CONFIG_PTHREAD_AFFINITY_NP) 567 const size_t setsize = CPU_ALLOC_SIZE(nbits); 568 unsigned long value; 569 cpu_set_t *cpuset; 570 int err; 571 572 cpuset = CPU_ALLOC(nbits); 573 g_assert(cpuset); 574 575 CPU_ZERO_S(setsize, cpuset); 576 value = find_first_bit(host_cpus, nbits); 577 while (value < nbits) { 578 CPU_SET_S(value, setsize, cpuset); 579 value = find_next_bit(host_cpus, nbits, value + 1); 580 } 581 582 err = pthread_setaffinity_np(thread->thread, setsize, cpuset); 583 CPU_FREE(cpuset); 584 return err; 585 #else 586 return -ENOSYS; 587 #endif 588 } 589 590 int qemu_thread_get_affinity(QemuThread *thread, unsigned long **host_cpus, 591 unsigned long *nbits) 592 { 593 #if defined(CONFIG_PTHREAD_AFFINITY_NP) 594 unsigned long tmpbits; 595 cpu_set_t *cpuset; 596 size_t setsize; 597 int i, err; 598 599 tmpbits = CPU_SETSIZE; 600 while (true) { 601 setsize = CPU_ALLOC_SIZE(tmpbits); 602 cpuset = CPU_ALLOC(tmpbits); 603 g_assert(cpuset); 604 605 err = pthread_getaffinity_np(thread->thread, setsize, cpuset); 606 if (err) { 607 CPU_FREE(cpuset); 608 if (err != -EINVAL) { 609 return err; 610 } 611 tmpbits *= 2; 612 } else { 613 break; 614 } 615 } 616 617 /* Convert the result into a proper bitmap. */ 618 *nbits = tmpbits; 619 *host_cpus = bitmap_new(tmpbits); 620 for (i = 0; i < tmpbits; i++) { 621 if (CPU_ISSET(i, cpuset)) { 622 set_bit(i, *host_cpus); 623 } 624 } 625 CPU_FREE(cpuset); 626 return 0; 627 #else 628 return -ENOSYS; 629 #endif 630 } 631 632 void qemu_thread_get_self(QemuThread *thread) 633 { 634 thread->thread = pthread_self(); 635 } 636 637 bool qemu_thread_is_self(QemuThread *thread) 638 { 639 return pthread_equal(pthread_self(), thread->thread); 640 } 641 642 void qemu_thread_exit(void *retval) 643 { 644 pthread_exit(retval); 645 } 646 647 void *qemu_thread_join(QemuThread *thread) 648 { 649 int err; 650 void *ret; 651 652 err = pthread_join(thread->thread, &ret); 653 if (err) { 654 error_exit(err, __func__); 655 } 656 return ret; 657 } 658