File:  [Qemu by Fabrice Bellard] / qemu / qemu-thread.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 18:24:04 2018 UTC (3 years, 1 month ago) by root
Branches: qemu, MAIN
CVS tags: qemu0150, qemu0141, qemu0140, qemu0130, HEAD
qemu 0.13.0

    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 <stdlib.h>
   14: #include <stdio.h>
   15: #include <errno.h>
   16: #include <time.h>
   17: #include <signal.h>
   18: #include <stdint.h>
   19: #include <string.h>
   20: #include "qemu-thread.h"
   21: 
   22: static void error_exit(int err, const char *msg)
   23: {
   24:     fprintf(stderr, "qemu: %s: %s\n", msg, strerror(err));
   25:     exit(1);
   26: }
   27: 
   28: void qemu_mutex_init(QemuMutex *mutex)
   29: {
   30:     int err;
   31: 
   32:     err = pthread_mutex_init(&mutex->lock, NULL);
   33:     if (err)
   34:         error_exit(err, __func__);
   35: }
   36: 
   37: void qemu_mutex_destroy(QemuMutex *mutex)
   38: {
   39:     int err;
   40: 
   41:     err = pthread_mutex_destroy(&mutex->lock);
   42:     if (err)
   43:         error_exit(err, __func__);
   44: }
   45: 
   46: void qemu_mutex_lock(QemuMutex *mutex)
   47: {
   48:     int err;
   49: 
   50:     err = pthread_mutex_lock(&mutex->lock);
   51:     if (err)
   52:         error_exit(err, __func__);
   53: }
   54: 
   55: int qemu_mutex_trylock(QemuMutex *mutex)
   56: {
   57:     return pthread_mutex_trylock(&mutex->lock);
   58: }
   59: 
   60: static void timespec_add_ms(struct timespec *ts, uint64_t msecs)
   61: {
   62:     ts->tv_sec = ts->tv_sec + (long)(msecs / 1000);
   63:     ts->tv_nsec = (ts->tv_nsec + ((long)msecs % 1000) * 1000000);
   64:     if (ts->tv_nsec >= 1000000000) {
   65:         ts->tv_nsec -= 1000000000;
   66:         ts->tv_sec++;
   67:     }
   68: }
   69: 
   70: int qemu_mutex_timedlock(QemuMutex *mutex, uint64_t msecs)
   71: {
   72:     int err;
   73:     struct timespec ts;
   74: 
   75:     clock_gettime(CLOCK_REALTIME, &ts);
   76:     timespec_add_ms(&ts, msecs);
   77: 
   78:     err = pthread_mutex_timedlock(&mutex->lock, &ts);
   79:     if (err && err != ETIMEDOUT)
   80:         error_exit(err, __func__);
   81:     return err;
   82: }
   83: 
   84: void qemu_mutex_unlock(QemuMutex *mutex)
   85: {
   86:     int err;
   87: 
   88:     err = pthread_mutex_unlock(&mutex->lock);
   89:     if (err)
   90:         error_exit(err, __func__);
   91: }
   92: 
   93: void qemu_cond_init(QemuCond *cond)
   94: {
   95:     int err;
   96: 
   97:     err = pthread_cond_init(&cond->cond, NULL);
   98:     if (err)
   99:         error_exit(err, __func__);
  100: }
  101: 
  102: void qemu_cond_destroy(QemuCond *cond)
  103: {
  104:     int err;
  105: 
  106:     err = pthread_cond_destroy(&cond->cond);
  107:     if (err)
  108:         error_exit(err, __func__);
  109: }
  110: 
  111: void qemu_cond_signal(QemuCond *cond)
  112: {
  113:     int err;
  114: 
  115:     err = pthread_cond_signal(&cond->cond);
  116:     if (err)
  117:         error_exit(err, __func__);
  118: }
  119: 
  120: void qemu_cond_broadcast(QemuCond *cond)
  121: {
  122:     int err;
  123: 
  124:     err = pthread_cond_broadcast(&cond->cond);
  125:     if (err)
  126:         error_exit(err, __func__);
  127: }
  128: 
  129: void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex)
  130: {
  131:     int err;
  132: 
  133:     err = pthread_cond_wait(&cond->cond, &mutex->lock);
  134:     if (err)
  135:         error_exit(err, __func__);
  136: }
  137: 
  138: int qemu_cond_timedwait(QemuCond *cond, QemuMutex *mutex, uint64_t msecs)
  139: {
  140:     struct timespec ts;
  141:     int err;
  142: 
  143:     clock_gettime(CLOCK_REALTIME, &ts);
  144:     timespec_add_ms(&ts, msecs);
  145: 
  146:     err = pthread_cond_timedwait(&cond->cond, &mutex->lock, &ts);
  147:     if (err && err != ETIMEDOUT)
  148:         error_exit(err, __func__);
  149:     return err;
  150: }
  151: 
  152: void qemu_thread_create(QemuThread *thread,
  153:                        void *(*start_routine)(void*),
  154:                        void *arg)
  155: {
  156:     int err;
  157: 
  158:     /* Leave signal handling to the iothread.  */
  159:     sigset_t set, oldset;
  160: 
  161:     sigfillset(&set);
  162:     pthread_sigmask(SIG_SETMASK, &set, &oldset);
  163:     err = pthread_create(&thread->thread, NULL, start_routine, arg);
  164:     if (err)
  165:         error_exit(err, __func__);
  166: 
  167:     pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  168: }
  169: 
  170: void qemu_thread_signal(QemuThread *thread, int sig)
  171: {
  172:     int err;
  173: 
  174:     err = pthread_kill(thread->thread, sig);
  175:     if (err)
  176:         error_exit(err, __func__);
  177: }
  178: 
  179: void qemu_thread_self(QemuThread *thread)
  180: {
  181:     thread->thread = pthread_self();
  182: }
  183: 
  184: int qemu_thread_equal(QemuThread *thread1, QemuThread *thread2)
  185: {
  186:    return pthread_equal(thread1->thread, thread2->thread);
  187: }
  188: 
  189: void qemu_thread_exit(void *retval)
  190: {
  191:     pthread_exit(retval);
  192: }

unix.superglobalmegacorp.com