root / qemu-thread.c @ 8e00128d
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 | } |