root / qemu-thread.c @ 16415335
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 | e5d355d1 | aliguori | return (thread1->thread == thread2->thread);
|
162 | e5d355d1 | aliguori | } |