Statistics
| Branch: | Revision:

root / qemu-thread.c @ 845f2c28

History | View | Annotate | Download (3.3 kB)

1 e5d355d1 aliguori
/*
2 e5d355d1 aliguori
 * Wrappers around mutex/cond/thread functions
3 e5d355d1 aliguori
 *
4 e5d355d1 aliguori
 * Copyright Red Hat, Inc. 2009
5 e5d355d1 aliguori
 *
6 e5d355d1 aliguori
 * Author:
7 e5d355d1 aliguori
 *  Marcelo Tosatti <mtosatti@redhat.com>
8 e5d355d1 aliguori
 *
9 e5d355d1 aliguori
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
10 e5d355d1 aliguori
 * See the COPYING file in the top-level directory.
11 e5d355d1 aliguori
 *
12 e5d355d1 aliguori
 */
13 e5d355d1 aliguori
#include <stdlib.h>
14 e5d355d1 aliguori
#include <stdio.h>
15 e5d355d1 aliguori
#include <errno.h>
16 e5d355d1 aliguori
#include <time.h>
17 e5d355d1 aliguori
#include <signal.h>
18 e5d355d1 aliguori
#include <stdint.h>
19 e5d355d1 aliguori
#include <string.h>
20 e5d355d1 aliguori
#include "qemu-thread.h"
21 e5d355d1 aliguori
22 e5d355d1 aliguori
static void error_exit(int err, const char *msg)
23 e5d355d1 aliguori
{
24 e5d355d1 aliguori
    fprintf(stderr, "qemu: %s: %s\n", msg, strerror(err));
25 e5d355d1 aliguori
    exit(1);
26 e5d355d1 aliguori
}
27 e5d355d1 aliguori
28 e5d355d1 aliguori
void qemu_mutex_init(QemuMutex *mutex)
29 e5d355d1 aliguori
{
30 e5d355d1 aliguori
    int err;
31 e5d355d1 aliguori
32 e5d355d1 aliguori
    err = pthread_mutex_init(&mutex->lock, NULL);
33 e5d355d1 aliguori
    if (err)
34 e5d355d1 aliguori
        error_exit(err, __func__);
35 e5d355d1 aliguori
}
36 e5d355d1 aliguori
37 e5d355d1 aliguori
void qemu_mutex_lock(QemuMutex *mutex)
38 e5d355d1 aliguori
{
39 e5d355d1 aliguori
    int err;
40 e5d355d1 aliguori
41 e5d355d1 aliguori
    err = pthread_mutex_lock(&mutex->lock);
42 e5d355d1 aliguori
    if (err)
43 e5d355d1 aliguori
        error_exit(err, __func__);
44 e5d355d1 aliguori
}
45 e5d355d1 aliguori
46 e5d355d1 aliguori
int qemu_mutex_trylock(QemuMutex *mutex)
47 e5d355d1 aliguori
{
48 e5d355d1 aliguori
    return pthread_mutex_trylock(&mutex->lock);
49 e5d355d1 aliguori
}
50 e5d355d1 aliguori
51 e5d355d1 aliguori
static void timespec_add_ms(struct timespec *ts, uint64_t msecs)
52 e5d355d1 aliguori
{
53 e5d355d1 aliguori
    ts->tv_sec = ts->tv_sec + (long)(msecs / 1000);
54 e5d355d1 aliguori
    ts->tv_nsec = (ts->tv_nsec + ((long)msecs % 1000) * 1000000);
55 e5d355d1 aliguori
    if (ts->tv_nsec >= 1000000000) {
56 e5d355d1 aliguori
        ts->tv_nsec -= 1000000000;
57 e5d355d1 aliguori
        ts->tv_sec++;
58 e5d355d1 aliguori
    }
59 e5d355d1 aliguori
}
60 e5d355d1 aliguori
61 e5d355d1 aliguori
int qemu_mutex_timedlock(QemuMutex *mutex, uint64_t msecs)
62 e5d355d1 aliguori
{
63 e5d355d1 aliguori
    int err;
64 e5d355d1 aliguori
    struct timespec ts;
65 e5d355d1 aliguori
66 e5d355d1 aliguori
    clock_gettime(CLOCK_REALTIME, &ts);
67 e5d355d1 aliguori
    timespec_add_ms(&ts, msecs);
68 e5d355d1 aliguori
69 e5d355d1 aliguori
    err = pthread_mutex_timedlock(&mutex->lock, &ts);
70 e5d355d1 aliguori
    if (err && err != ETIMEDOUT)
71 e5d355d1 aliguori
        error_exit(err, __func__);
72 e5d355d1 aliguori
    return err;
73 e5d355d1 aliguori
}
74 e5d355d1 aliguori
75 e5d355d1 aliguori
void qemu_mutex_unlock(QemuMutex *mutex)
76 e5d355d1 aliguori
{
77 e5d355d1 aliguori
    int err;
78 e5d355d1 aliguori
79 e5d355d1 aliguori
    err = pthread_mutex_unlock(&mutex->lock);
80 e5d355d1 aliguori
    if (err)
81 e5d355d1 aliguori
        error_exit(err, __func__);
82 e5d355d1 aliguori
}
83 e5d355d1 aliguori
84 e5d355d1 aliguori
void qemu_cond_init(QemuCond *cond)
85 e5d355d1 aliguori
{
86 e5d355d1 aliguori
    int err;
87 e5d355d1 aliguori
88 e5d355d1 aliguori
    err = pthread_cond_init(&cond->cond, NULL);
89 e5d355d1 aliguori
    if (err)
90 e5d355d1 aliguori
        error_exit(err, __func__);
91 e5d355d1 aliguori
}
92 e5d355d1 aliguori
93 e5d355d1 aliguori
void qemu_cond_signal(QemuCond *cond)
94 e5d355d1 aliguori
{
95 e5d355d1 aliguori
    int err;
96 e5d355d1 aliguori
97 e5d355d1 aliguori
    err = pthread_cond_signal(&cond->cond);
98 e5d355d1 aliguori
    if (err)
99 e5d355d1 aliguori
        error_exit(err, __func__);
100 e5d355d1 aliguori
}
101 e5d355d1 aliguori
102 e5d355d1 aliguori
void qemu_cond_broadcast(QemuCond *cond)
103 e5d355d1 aliguori
{
104 e5d355d1 aliguori
    int err;
105 e5d355d1 aliguori
106 e5d355d1 aliguori
    err = pthread_cond_broadcast(&cond->cond);
107 e5d355d1 aliguori
    if (err)
108 e5d355d1 aliguori
        error_exit(err, __func__);
109 e5d355d1 aliguori
}
110 e5d355d1 aliguori
111 e5d355d1 aliguori
void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex)
112 e5d355d1 aliguori
{
113 e5d355d1 aliguori
    int err;
114 e5d355d1 aliguori
115 e5d355d1 aliguori
    err = pthread_cond_wait(&cond->cond, &mutex->lock);
116 e5d355d1 aliguori
    if (err)
117 e5d355d1 aliguori
        error_exit(err, __func__);
118 e5d355d1 aliguori
}
119 e5d355d1 aliguori
120 e5d355d1 aliguori
int qemu_cond_timedwait(QemuCond *cond, QemuMutex *mutex, uint64_t msecs)
121 e5d355d1 aliguori
{
122 e5d355d1 aliguori
    struct timespec ts;
123 e5d355d1 aliguori
    int err;
124 e5d355d1 aliguori
125 e5d355d1 aliguori
    clock_gettime(CLOCK_REALTIME, &ts);
126 e5d355d1 aliguori
    timespec_add_ms(&ts, msecs);
127 e5d355d1 aliguori
128 e5d355d1 aliguori
    err = pthread_cond_timedwait(&cond->cond, &mutex->lock, &ts);
129 e5d355d1 aliguori
    if (err && err != ETIMEDOUT)
130 e5d355d1 aliguori
        error_exit(err, __func__);
131 e5d355d1 aliguori
    return err;
132 e5d355d1 aliguori
}
133 e5d355d1 aliguori
134 e5d355d1 aliguori
void qemu_thread_create(QemuThread *thread,
135 e5d355d1 aliguori
                       void *(*start_routine)(void*),
136 e5d355d1 aliguori
                       void *arg)
137 e5d355d1 aliguori
{
138 e5d355d1 aliguori
    int err;
139 e5d355d1 aliguori
140 e5d355d1 aliguori
    err = pthread_create(&thread->thread, NULL, start_routine, arg);
141 e5d355d1 aliguori
    if (err)
142 e5d355d1 aliguori
        error_exit(err, __func__);
143 e5d355d1 aliguori
}
144 e5d355d1 aliguori
145 e5d355d1 aliguori
void qemu_thread_signal(QemuThread *thread, int sig)
146 e5d355d1 aliguori
{
147 e5d355d1 aliguori
    int err;
148 e5d355d1 aliguori
149 e5d355d1 aliguori
    err = pthread_kill(thread->thread, sig);
150 e5d355d1 aliguori
    if (err)
151 e5d355d1 aliguori
        error_exit(err, __func__);
152 e5d355d1 aliguori
}
153 e5d355d1 aliguori
154 e5d355d1 aliguori
void qemu_thread_self(QemuThread *thread)
155 e5d355d1 aliguori
{
156 e5d355d1 aliguori
    thread->thread = pthread_self();
157 e5d355d1 aliguori
}
158 e5d355d1 aliguori
159 e5d355d1 aliguori
int qemu_thread_equal(QemuThread *thread1, QemuThread *thread2)
160 e5d355d1 aliguori
{
161 609f2fab Sebastian Herbszt
   return pthread_equal(thread1->thread, thread2->thread);
162 e5d355d1 aliguori
}