Statistics
| Branch: | Revision:

root / qemu-thread-posix.c @ 9257d46d

History | View | Annotate | Download (3.8 kB)

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_get_self(QemuThread *thread)
180
{
181
    thread->thread = pthread_self();
182
}
183

    
184
int qemu_thread_is_self(QemuThread *thread)
185
{
186
   return pthread_equal(pthread_self(), thread->thread);
187
}
188

    
189
void qemu_thread_exit(void *retval)
190
{
191
    pthread_exit(retval);
192
}