Commit e5d355d12ed417fbde1c707121ec8fb4070d7667
1 parent
d9f75a4e
qemu: mutex/thread/cond wrappers and configure tweaks (Marcelo Tosatti)
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@7237 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
243 additions
and
14 deletions
Makefile
... | ... | @@ -30,7 +30,8 @@ else |
30 | 30 | DOCS= |
31 | 31 | endif |
32 | 32 | |
33 | -LIBS+=$(AIOLIBS) | |
33 | +LIBS+=$(PTHREADLIBS) | |
34 | +LIBS+=$(CLOCKLIBS) | |
34 | 35 | |
35 | 36 | ifdef CONFIG_SOLARIS |
36 | 37 | LIBS+=-lsocket -lnsl -lresolv |
... | ... | @@ -170,6 +171,10 @@ ifdef CONFIG_COCOA |
170 | 171 | OBJS+=cocoa.o |
171 | 172 | endif |
172 | 173 | |
174 | +ifdef CONFIG_IOTHREAD | |
175 | +OBJS+=qemu-thread.o | |
176 | +endif | |
177 | + | |
173 | 178 | ifdef CONFIG_SLIRP |
174 | 179 | CPPFLAGS+=-I$(SRC_PATH)/slirp |
175 | 180 | SLIRP_OBJS=cksum.o if.o ip_icmp.o ip_input.o ip_output.o \ | ... | ... |
Makefile.target
... | ... | @@ -318,7 +318,8 @@ endif |
318 | 318 | |
319 | 319 | OBJS= main.o syscall.o strace.o mmap.o signal.o path.o thunk.o \ |
320 | 320 | elfload.o linuxload.o uaccess.o envlist.o |
321 | -LIBS+= $(AIOLIBS) | |
321 | +LIBS+= $(PTHREADLIBS) | |
322 | +LIBS+= $(CLOCKLIBS) | |
322 | 323 | ifdef TARGET_HAS_BFLT |
323 | 324 | OBJS+= flatload.o |
324 | 325 | endif |
... | ... | @@ -694,7 +695,8 @@ ifdef CONFIG_SLIRP |
694 | 695 | CPPFLAGS+=-I$(SRC_PATH)/slirp |
695 | 696 | endif |
696 | 697 | |
697 | -LIBS+=$(AIOLIBS) | |
698 | +LIBS+=$(PTHREADLIBS) | |
699 | +LIBS+=$(CLOCKLIBS) | |
698 | 700 | # specific flags are needed for non soft mmu emulator |
699 | 701 | ifdef CONFIG_STATIC |
700 | 702 | LDFLAGS+=-static | ... | ... |
configure
... | ... | @@ -181,7 +181,9 @@ bsd_user="no" |
181 | 181 | build_docs="no" |
182 | 182 | uname_release="" |
183 | 183 | curses="yes" |
184 | +pthread="yes" | |
184 | 185 | aio="yes" |
186 | +io_thread="no" | |
185 | 187 | nptl="yes" |
186 | 188 | mixemu="no" |
187 | 189 | bluez="yes" |
... | ... | @@ -479,8 +481,12 @@ for opt do |
479 | 481 | ;; |
480 | 482 | --enable-mixemu) mixemu="yes" |
481 | 483 | ;; |
484 | + --disable-pthread) pthread="no" | |
485 | + ;; | |
482 | 486 | --disable-aio) aio="no" |
483 | 487 | ;; |
488 | + --enable-io-thread) io_thread="yes" | |
489 | + ;; | |
484 | 490 | --disable-blobs) blobs="no" |
485 | 491 | ;; |
486 | 492 | --kerneldir=*) kerneldir="$optarg" |
... | ... | @@ -611,7 +617,9 @@ echo " --oss-lib path to OSS library" |
611 | 617 | echo " --enable-uname-release=R Return R for uname -r in usermode emulation" |
612 | 618 | echo " --sparc_cpu=V Build qemu for Sparc architecture v7, v8, v8plus, v8plusa, v9" |
613 | 619 | echo " --disable-vde disable support for vde network" |
620 | +echo " --disable-pthread disable pthread support" | |
614 | 621 | echo " --disable-aio disable AIO support" |
622 | +echo " --enable-io-thread enable IO thread" | |
615 | 623 | echo " --disable-blobs disable installing provided firmware blobs" |
616 | 624 | echo " --kerneldir=PATH look for kernel includes in PATH" |
617 | 625 | echo "" |
... | ... | @@ -1123,21 +1131,26 @@ EOF |
1123 | 1131 | fi |
1124 | 1132 | |
1125 | 1133 | ########################################## |
1126 | -# AIO probe | |
1127 | -AIOLIBS="" | |
1134 | +# pthread probe | |
1135 | +PTHREADLIBS="" | |
1128 | 1136 | |
1129 | -if test "$aio" = "yes" ; then | |
1130 | - aio=no | |
1131 | - cat > $TMPC << EOF | |
1137 | +if test "$pthread" = yes; then | |
1138 | + pthread=no | |
1139 | +cat > $TMPC << EOF | |
1132 | 1140 | #include <pthread.h> |
1133 | 1141 | int main(void) { pthread_mutex_t lock; return 0; } |
1134 | 1142 | EOF |
1135 | - if $cc $ARCH_CFLAGS -o $TMPE $AIOLIBS $TMPC 2> /dev/null ; then | |
1136 | - aio=yes | |
1137 | - AIOLIBS="-lpthread" | |
1143 | + if $cc $ARCH_CFLAGS -o $TMPE $PTHREADLIBS $TMPC 2> /dev/null ; then | |
1144 | + pthread=yes | |
1145 | + PTHREADLIBS="-lpthread" | |
1138 | 1146 | fi |
1139 | 1147 | fi |
1140 | 1148 | |
1149 | +if test "$pthread" = no; then | |
1150 | + aio=no | |
1151 | + io_thread=no | |
1152 | +fi | |
1153 | + | |
1141 | 1154 | ########################################## |
1142 | 1155 | # iovec probe |
1143 | 1156 | cat > $TMPC <<EOF |
... | ... | @@ -1231,6 +1244,7 @@ fi |
1231 | 1244 | |
1232 | 1245 | ########################################## |
1233 | 1246 | # Do we need librt |
1247 | +CLOCKLIBS="" | |
1234 | 1248 | cat > $TMPC <<EOF |
1235 | 1249 | #include <signal.h> |
1236 | 1250 | #include <time.h> |
... | ... | @@ -1245,8 +1259,7 @@ elif $cc $ARCH_CFLAGS -o $TMPE $TMPC -lrt > /dev/null 2> /dev/null ; then |
1245 | 1259 | fi |
1246 | 1260 | |
1247 | 1261 | if test "$rt" = "yes" ; then |
1248 | - # Hack, we should have a general purpose LIBS for this sort of thing | |
1249 | - AIOLIBS="$AIOLIBS -lrt" | |
1262 | + CLOCKLIBS="-lrt" | |
1250 | 1263 | fi |
1251 | 1264 | |
1252 | 1265 | if test "$mingw32" = "yes" ; then |
... | ... | @@ -1324,6 +1337,7 @@ echo "uname -r $uname_release" |
1324 | 1337 | echo "NPTL support $nptl" |
1325 | 1338 | echo "vde support $vde" |
1326 | 1339 | echo "AIO support $aio" |
1340 | +echo "IO thread $io_thread" | |
1327 | 1341 | echo "Install blobs $blobs" |
1328 | 1342 | echo "KVM support $kvm" |
1329 | 1343 | echo "fdt support $fdt" |
... | ... | @@ -1376,7 +1390,8 @@ echo "ARCH_LDFLAGS=$ARCH_LDFLAGS" >> $config_mak |
1376 | 1390 | echo "CFLAGS=$CFLAGS" >> $config_mak |
1377 | 1391 | echo "LDFLAGS=$LDFLAGS" >> $config_mak |
1378 | 1392 | echo "EXESUF=$EXESUF" >> $config_mak |
1379 | -echo "AIOLIBS=$AIOLIBS" >> $config_mak | |
1393 | +echo "PTHREADLIBS=$PTHREADLIBS" >> $config_mak | |
1394 | +echo "CLOCKLIBS=$CLOCKLIBS" >> $config_mak | |
1380 | 1395 | case "$cpu" in |
1381 | 1396 | i386) |
1382 | 1397 | echo "ARCH=i386" >> $config_mak |
... | ... | @@ -1640,6 +1655,10 @@ if test "$aio" = "yes" ; then |
1640 | 1655 | echo "#define CONFIG_AIO 1" >> $config_h |
1641 | 1656 | echo "CONFIG_AIO=yes" >> $config_mak |
1642 | 1657 | fi |
1658 | +if test "$io_thread" = "yes" ; then | |
1659 | + echo "CONFIG_IOTHREAD=yes" >> $config_mak | |
1660 | + echo "#define CONFIG_IOTHREAD 1" >> $config_h | |
1661 | +fi | |
1643 | 1662 | if test "$blobs" = "yes" ; then |
1644 | 1663 | echo "INSTALL_BLOBS=yes" >> $config_mak |
1645 | 1664 | fi | ... | ... |
qemu-thread.c
0 → 100644
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_lock(QemuMutex *mutex) | |
38 | +{ | |
39 | + int err; | |
40 | + | |
41 | + err = pthread_mutex_lock(&mutex->lock); | |
42 | + if (err) | |
43 | + error_exit(err, __func__); | |
44 | +} | |
45 | + | |
46 | +int qemu_mutex_trylock(QemuMutex *mutex) | |
47 | +{ | |
48 | + return pthread_mutex_trylock(&mutex->lock); | |
49 | +} | |
50 | + | |
51 | +static void timespec_add_ms(struct timespec *ts, uint64_t msecs) | |
52 | +{ | |
53 | + ts->tv_sec = ts->tv_sec + (long)(msecs / 1000); | |
54 | + ts->tv_nsec = (ts->tv_nsec + ((long)msecs % 1000) * 1000000); | |
55 | + if (ts->tv_nsec >= 1000000000) { | |
56 | + ts->tv_nsec -= 1000000000; | |
57 | + ts->tv_sec++; | |
58 | + } | |
59 | +} | |
60 | + | |
61 | +int qemu_mutex_timedlock(QemuMutex *mutex, uint64_t msecs) | |
62 | +{ | |
63 | + int err; | |
64 | + struct timespec ts; | |
65 | + | |
66 | + clock_gettime(CLOCK_REALTIME, &ts); | |
67 | + timespec_add_ms(&ts, msecs); | |
68 | + | |
69 | + err = pthread_mutex_timedlock(&mutex->lock, &ts); | |
70 | + if (err && err != ETIMEDOUT) | |
71 | + error_exit(err, __func__); | |
72 | + return err; | |
73 | +} | |
74 | + | |
75 | +void qemu_mutex_unlock(QemuMutex *mutex) | |
76 | +{ | |
77 | + int err; | |
78 | + | |
79 | + err = pthread_mutex_unlock(&mutex->lock); | |
80 | + if (err) | |
81 | + error_exit(err, __func__); | |
82 | +} | |
83 | + | |
84 | +void qemu_cond_init(QemuCond *cond) | |
85 | +{ | |
86 | + int err; | |
87 | + | |
88 | + err = pthread_cond_init(&cond->cond, NULL); | |
89 | + if (err) | |
90 | + error_exit(err, __func__); | |
91 | +} | |
92 | + | |
93 | +void qemu_cond_signal(QemuCond *cond) | |
94 | +{ | |
95 | + int err; | |
96 | + | |
97 | + err = pthread_cond_signal(&cond->cond); | |
98 | + if (err) | |
99 | + error_exit(err, __func__); | |
100 | +} | |
101 | + | |
102 | +void qemu_cond_broadcast(QemuCond *cond) | |
103 | +{ | |
104 | + int err; | |
105 | + | |
106 | + err = pthread_cond_broadcast(&cond->cond); | |
107 | + if (err) | |
108 | + error_exit(err, __func__); | |
109 | +} | |
110 | + | |
111 | +void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex) | |
112 | +{ | |
113 | + int err; | |
114 | + | |
115 | + err = pthread_cond_wait(&cond->cond, &mutex->lock); | |
116 | + if (err) | |
117 | + error_exit(err, __func__); | |
118 | +} | |
119 | + | |
120 | +int qemu_cond_timedwait(QemuCond *cond, QemuMutex *mutex, uint64_t msecs) | |
121 | +{ | |
122 | + struct timespec ts; | |
123 | + int err; | |
124 | + | |
125 | + clock_gettime(CLOCK_REALTIME, &ts); | |
126 | + timespec_add_ms(&ts, msecs); | |
127 | + | |
128 | + err = pthread_cond_timedwait(&cond->cond, &mutex->lock, &ts); | |
129 | + if (err && err != ETIMEDOUT) | |
130 | + error_exit(err, __func__); | |
131 | + return err; | |
132 | +} | |
133 | + | |
134 | +void qemu_thread_create(QemuThread *thread, | |
135 | + void *(*start_routine)(void*), | |
136 | + void *arg) | |
137 | +{ | |
138 | + int err; | |
139 | + | |
140 | + err = pthread_create(&thread->thread, NULL, start_routine, arg); | |
141 | + if (err) | |
142 | + error_exit(err, __func__); | |
143 | +} | |
144 | + | |
145 | +void qemu_thread_signal(QemuThread *thread, int sig) | |
146 | +{ | |
147 | + int err; | |
148 | + | |
149 | + err = pthread_kill(thread->thread, sig); | |
150 | + if (err) | |
151 | + error_exit(err, __func__); | |
152 | +} | |
153 | + | |
154 | +void qemu_thread_self(QemuThread *thread) | |
155 | +{ | |
156 | + thread->thread = pthread_self(); | |
157 | +} | |
158 | + | |
159 | +int qemu_thread_equal(QemuThread *thread1, QemuThread *thread2) | |
160 | +{ | |
161 | + return (thread1->thread == thread2->thread); | |
162 | +} | |
163 | + | ... | ... |
qemu-thread.h
0 → 100644
1 | +#ifndef __QEMU_THREAD_H | |
2 | +#define __QEMU_THREAD_H 1 | |
3 | +#include "semaphore.h" | |
4 | +#include "pthread.h" | |
5 | + | |
6 | +struct QemuMutex { | |
7 | + pthread_mutex_t lock; | |
8 | +}; | |
9 | + | |
10 | +struct QemuCond { | |
11 | + pthread_cond_t cond; | |
12 | +}; | |
13 | + | |
14 | +struct QemuThread { | |
15 | + pthread_t thread; | |
16 | +}; | |
17 | + | |
18 | +typedef struct QemuMutex QemuMutex; | |
19 | +typedef struct QemuCond QemuCond; | |
20 | +typedef struct QemuThread QemuThread; | |
21 | + | |
22 | +void qemu_mutex_init(QemuMutex *mutex); | |
23 | +void qemu_mutex_lock(QemuMutex *mutex); | |
24 | +int qemu_mutex_trylock(QemuMutex *mutex); | |
25 | +int qemu_mutex_timedlock(QemuMutex *mutex, uint64_t msecs); | |
26 | +void qemu_mutex_unlock(QemuMutex *mutex); | |
27 | + | |
28 | +void qemu_cond_init(QemuCond *cond); | |
29 | +void qemu_cond_signal(QemuCond *cond); | |
30 | +void qemu_cond_broadcast(QemuCond *cond); | |
31 | +void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex); | |
32 | +int qemu_cond_timedwait(QemuCond *cond, QemuMutex *mutex, uint64_t msecs); | |
33 | + | |
34 | +void qemu_thread_create(QemuThread *thread, | |
35 | + void *(*start_routine)(void*), | |
36 | + void *arg); | |
37 | +void qemu_thread_signal(QemuThread *thread, int sig); | |
38 | +void qemu_thread_self(QemuThread *thread); | |
39 | +int qemu_thread_equal(QemuThread *thread1, QemuThread *thread2); | |
40 | +#endif | ... | ... |