Home | History | Annotate | Download | only in qemu
      1 /*
      2  * Wrappers around mutex/cond/thread functions
      3  *
      4  * Copyright Red Hat, Inc. 2009
      5  *
      6  * Author:
      7  *  Marcelo Tosatti <mtosatti (at) 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_lock(QemuMutex *mutex)
     38 {
     39     int err;
     40 
     41     err = pthread_mutex_lock(&mutex->lock);
     42     if (err)
     43         error_exit(err, __func__);
     44 }
     45 
     46 int qemu_mutex_trylock(QemuMutex *mutex)
     47 {
     48     return pthread_mutex_trylock(&mutex->lock);
     49 }
     50 
     51 static void timespec_add_ms(struct timespec *ts, uint64_t msecs)
     52 {
     53     ts->tv_sec = ts->tv_sec + (long)(msecs / 1000);
     54     ts->tv_nsec = (ts->tv_nsec + ((long)msecs % 1000) * 1000000);
     55     if (ts->tv_nsec >= 1000000000) {
     56         ts->tv_nsec -= 1000000000;
     57         ts->tv_sec++;
     58     }
     59 }
     60 
     61 int qemu_mutex_timedlock(QemuMutex *mutex, uint64_t msecs)
     62 {
     63     int err;
     64     struct timespec ts;
     65 
     66     clock_gettime(CLOCK_REALTIME, &ts);
     67     timespec_add_ms(&ts, msecs);
     68 
     69     err = pthread_mutex_timedlock(&mutex->lock, &ts);
     70     if (err && err != ETIMEDOUT)
     71         error_exit(err, __func__);
     72     return err;
     73 }
     74 
     75 void qemu_mutex_unlock(QemuMutex *mutex)
     76 {
     77     int err;
     78 
     79     err = pthread_mutex_unlock(&mutex->lock);
     80     if (err)
     81         error_exit(err, __func__);
     82 }
     83 
     84 void qemu_cond_init(QemuCond *cond)
     85 {
     86     int err;
     87 
     88     err = pthread_cond_init(&cond->cond, NULL);
     89     if (err)
     90         error_exit(err, __func__);
     91 }
     92 
     93 void qemu_cond_signal(QemuCond *cond)
     94 {
     95     int err;
     96 
     97     err = pthread_cond_signal(&cond->cond);
     98     if (err)
     99         error_exit(err, __func__);
    100 }
    101 
    102 void qemu_cond_broadcast(QemuCond *cond)
    103 {
    104     int err;
    105 
    106     err = pthread_cond_broadcast(&cond->cond);
    107     if (err)
    108         error_exit(err, __func__);
    109 }
    110 
    111 void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex)
    112 {
    113     int err;
    114 
    115     err = pthread_cond_wait(&cond->cond, &mutex->lock);
    116     if (err)
    117         error_exit(err, __func__);
    118 }
    119 
    120 int qemu_cond_timedwait(QemuCond *cond, QemuMutex *mutex, uint64_t msecs)
    121 {
    122     struct timespec ts;
    123     int err;
    124 
    125     clock_gettime(CLOCK_REALTIME, &ts);
    126     timespec_add_ms(&ts, msecs);
    127 
    128     err = pthread_cond_timedwait(&cond->cond, &mutex->lock, &ts);
    129     if (err && err != ETIMEDOUT)
    130         error_exit(err, __func__);
    131     return err;
    132 }
    133 
    134 void qemu_thread_create(QemuThread *thread,
    135                        void *(*start_routine)(void*),
    136                        void *arg)
    137 {
    138     int err;
    139 
    140     err = pthread_create(&thread->thread, NULL, start_routine, arg);
    141     if (err)
    142         error_exit(err, __func__);
    143 }
    144 
    145 void qemu_thread_signal(QemuThread *thread, int sig)
    146 {
    147     int err;
    148 
    149     err = pthread_kill(thread->thread, sig);
    150     if (err)
    151         error_exit(err, __func__);
    152 }
    153 
    154 void qemu_thread_self(QemuThread *thread)
    155 {
    156     thread->thread = pthread_self();
    157 }
    158 
    159 int qemu_thread_equal(QemuThread *thread1, QemuThread *thread2)
    160 {
    161    return pthread_equal(thread1->thread, thread2->thread);
    162 }
    163 
    164