Statistics
| Branch: | Revision:

root / qemu-thread.c @ 313b1d69

History | View | Annotate | Download (3.8 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 313b1d69 Corentin Chary
void qemu_mutex_destroy(QemuMutex *mutex)
38 313b1d69 Corentin Chary
{
39 313b1d69 Corentin Chary
    int err;
40 313b1d69 Corentin Chary
41 313b1d69 Corentin Chary
    err = pthread_mutex_destroy(&mutex->lock);
42 313b1d69 Corentin Chary
    if (err)
43 313b1d69 Corentin Chary
        error_exit(err, __func__);
44 313b1d69 Corentin Chary
}
45 313b1d69 Corentin Chary
46 e5d355d1 aliguori
void qemu_mutex_lock(QemuMutex *mutex)
47 e5d355d1 aliguori
{
48 e5d355d1 aliguori
    int err;
49 e5d355d1 aliguori
50 e5d355d1 aliguori
    err = pthread_mutex_lock(&mutex->lock);
51 e5d355d1 aliguori
    if (err)
52 e5d355d1 aliguori
        error_exit(err, __func__);
53 e5d355d1 aliguori
}
54 e5d355d1 aliguori
55 e5d355d1 aliguori
int qemu_mutex_trylock(QemuMutex *mutex)
56 e5d355d1 aliguori
{
57 e5d355d1 aliguori
    return pthread_mutex_trylock(&mutex->lock);
58 e5d355d1 aliguori
}
59 e5d355d1 aliguori
60 e5d355d1 aliguori
static void timespec_add_ms(struct timespec *ts, uint64_t msecs)
61 e5d355d1 aliguori
{
62 e5d355d1 aliguori
    ts->tv_sec = ts->tv_sec + (long)(msecs / 1000);
63 e5d355d1 aliguori
    ts->tv_nsec = (ts->tv_nsec + ((long)msecs % 1000) * 1000000);
64 e5d355d1 aliguori
    if (ts->tv_nsec >= 1000000000) {
65 e5d355d1 aliguori
        ts->tv_nsec -= 1000000000;
66 e5d355d1 aliguori
        ts->tv_sec++;
67 e5d355d1 aliguori
    }
68 e5d355d1 aliguori
}
69 e5d355d1 aliguori
70 e5d355d1 aliguori
int qemu_mutex_timedlock(QemuMutex *mutex, uint64_t msecs)
71 e5d355d1 aliguori
{
72 e5d355d1 aliguori
    int err;
73 e5d355d1 aliguori
    struct timespec ts;
74 e5d355d1 aliguori
75 e5d355d1 aliguori
    clock_gettime(CLOCK_REALTIME, &ts);
76 e5d355d1 aliguori
    timespec_add_ms(&ts, msecs);
77 e5d355d1 aliguori
78 e5d355d1 aliguori
    err = pthread_mutex_timedlock(&mutex->lock, &ts);
79 e5d355d1 aliguori
    if (err && err != ETIMEDOUT)
80 e5d355d1 aliguori
        error_exit(err, __func__);
81 e5d355d1 aliguori
    return err;
82 e5d355d1 aliguori
}
83 e5d355d1 aliguori
84 e5d355d1 aliguori
void qemu_mutex_unlock(QemuMutex *mutex)
85 e5d355d1 aliguori
{
86 e5d355d1 aliguori
    int err;
87 e5d355d1 aliguori
88 e5d355d1 aliguori
    err = pthread_mutex_unlock(&mutex->lock);
89 e5d355d1 aliguori
    if (err)
90 e5d355d1 aliguori
        error_exit(err, __func__);
91 e5d355d1 aliguori
}
92 e5d355d1 aliguori
93 e5d355d1 aliguori
void qemu_cond_init(QemuCond *cond)
94 e5d355d1 aliguori
{
95 e5d355d1 aliguori
    int err;
96 e5d355d1 aliguori
97 e5d355d1 aliguori
    err = pthread_cond_init(&cond->cond, NULL);
98 e5d355d1 aliguori
    if (err)
99 e5d355d1 aliguori
        error_exit(err, __func__);
100 e5d355d1 aliguori
}
101 e5d355d1 aliguori
102 313b1d69 Corentin Chary
void qemu_cond_destroy(QemuCond *cond)
103 313b1d69 Corentin Chary
{
104 313b1d69 Corentin Chary
    int err;
105 313b1d69 Corentin Chary
106 313b1d69 Corentin Chary
    err = pthread_cond_destroy(&cond->cond);
107 313b1d69 Corentin Chary
    if (err)
108 313b1d69 Corentin Chary
        error_exit(err, __func__);
109 313b1d69 Corentin Chary
}
110 313b1d69 Corentin Chary
111 e5d355d1 aliguori
void qemu_cond_signal(QemuCond *cond)
112 e5d355d1 aliguori
{
113 e5d355d1 aliguori
    int err;
114 e5d355d1 aliguori
115 e5d355d1 aliguori
    err = pthread_cond_signal(&cond->cond);
116 e5d355d1 aliguori
    if (err)
117 e5d355d1 aliguori
        error_exit(err, __func__);
118 e5d355d1 aliguori
}
119 e5d355d1 aliguori
120 e5d355d1 aliguori
void qemu_cond_broadcast(QemuCond *cond)
121 e5d355d1 aliguori
{
122 e5d355d1 aliguori
    int err;
123 e5d355d1 aliguori
124 e5d355d1 aliguori
    err = pthread_cond_broadcast(&cond->cond);
125 e5d355d1 aliguori
    if (err)
126 e5d355d1 aliguori
        error_exit(err, __func__);
127 e5d355d1 aliguori
}
128 e5d355d1 aliguori
129 e5d355d1 aliguori
void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex)
130 e5d355d1 aliguori
{
131 e5d355d1 aliguori
    int err;
132 e5d355d1 aliguori
133 e5d355d1 aliguori
    err = pthread_cond_wait(&cond->cond, &mutex->lock);
134 e5d355d1 aliguori
    if (err)
135 e5d355d1 aliguori
        error_exit(err, __func__);
136 e5d355d1 aliguori
}
137 e5d355d1 aliguori
138 e5d355d1 aliguori
int qemu_cond_timedwait(QemuCond *cond, QemuMutex *mutex, uint64_t msecs)
139 e5d355d1 aliguori
{
140 e5d355d1 aliguori
    struct timespec ts;
141 e5d355d1 aliguori
    int err;
142 e5d355d1 aliguori
143 e5d355d1 aliguori
    clock_gettime(CLOCK_REALTIME, &ts);
144 e5d355d1 aliguori
    timespec_add_ms(&ts, msecs);
145 e5d355d1 aliguori
146 e5d355d1 aliguori
    err = pthread_cond_timedwait(&cond->cond, &mutex->lock, &ts);
147 e5d355d1 aliguori
    if (err && err != ETIMEDOUT)
148 e5d355d1 aliguori
        error_exit(err, __func__);
149 e5d355d1 aliguori
    return err;
150 e5d355d1 aliguori
}
151 e5d355d1 aliguori
152 e5d355d1 aliguori
void qemu_thread_create(QemuThread *thread,
153 e5d355d1 aliguori
                       void *(*start_routine)(void*),
154 e5d355d1 aliguori
                       void *arg)
155 e5d355d1 aliguori
{
156 e5d355d1 aliguori
    int err;
157 e5d355d1 aliguori
158 55541c8a Paolo Bonzini
    /* Leave signal handling to the iothread.  */
159 55541c8a Paolo Bonzini
    sigset_t set, oldset;
160 55541c8a Paolo Bonzini
161 55541c8a Paolo Bonzini
    sigfillset(&set);
162 55541c8a Paolo Bonzini
    pthread_sigmask(SIG_SETMASK, &set, &oldset);
163 e5d355d1 aliguori
    err = pthread_create(&thread->thread, NULL, start_routine, arg);
164 e5d355d1 aliguori
    if (err)
165 e5d355d1 aliguori
        error_exit(err, __func__);
166 55541c8a Paolo Bonzini
167 55541c8a Paolo Bonzini
    pthread_sigmask(SIG_SETMASK, &oldset, NULL);
168 e5d355d1 aliguori
}
169 e5d355d1 aliguori
170 e5d355d1 aliguori
void qemu_thread_signal(QemuThread *thread, int sig)
171 e5d355d1 aliguori
{
172 e5d355d1 aliguori
    int err;
173 e5d355d1 aliguori
174 e5d355d1 aliguori
    err = pthread_kill(thread->thread, sig);
175 e5d355d1 aliguori
    if (err)
176 e5d355d1 aliguori
        error_exit(err, __func__);
177 e5d355d1 aliguori
}
178 e5d355d1 aliguori
179 e5d355d1 aliguori
void qemu_thread_self(QemuThread *thread)
180 e5d355d1 aliguori
{
181 e5d355d1 aliguori
    thread->thread = pthread_self();
182 e5d355d1 aliguori
}
183 e5d355d1 aliguori
184 e5d355d1 aliguori
int qemu_thread_equal(QemuThread *thread1, QemuThread *thread2)
185 e5d355d1 aliguori
{
186 609f2fab Sebastian Herbszt
   return pthread_equal(thread1->thread, thread2->thread);
187 e5d355d1 aliguori
}
188 e5d355d1 aliguori
189 313b1d69 Corentin Chary
void qemu_thread_exit(void *retval)
190 313b1d69 Corentin Chary
{
191 313b1d69 Corentin Chary
    pthread_exit(retval);
192 313b1d69 Corentin Chary
}