qemu/qemu-thread.c
<<
>>
Prefs
   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
  22static void error_exit(int err, const char *msg)
  23{
  24    fprintf(stderr, "qemu: %s: %s\n", msg, strerror(err));
  25    exit(1);
  26}
  27
  28void 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
  37void 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
  46int qemu_mutex_trylock(QemuMutex *mutex)
  47{
  48    return pthread_mutex_trylock(&mutex->lock);
  49}
  50
  51static 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
  61int 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
  75void 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
  84void 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
  93void 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
 102void 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
 111void 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
 120int 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
 134void 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
 145void 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
 154void qemu_thread_self(QemuThread *thread)
 155{
 156    thread->thread = pthread_self();
 157}
 158
 159int qemu_thread_equal(QemuThread *thread1, QemuThread *thread2)
 160{
 161   return pthread_equal(thread1->thread, thread2->thread);
 162}
 163
 164