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,7 +30,8 @@ else | ||
30 | DOCS= | 30 | DOCS= |
31 | endif | 31 | endif |
32 | 32 | ||
33 | -LIBS+=$(AIOLIBS) | 33 | +LIBS+=$(PTHREADLIBS) |
34 | +LIBS+=$(CLOCKLIBS) | ||
34 | 35 | ||
35 | ifdef CONFIG_SOLARIS | 36 | ifdef CONFIG_SOLARIS |
36 | LIBS+=-lsocket -lnsl -lresolv | 37 | LIBS+=-lsocket -lnsl -lresolv |
@@ -170,6 +171,10 @@ ifdef CONFIG_COCOA | @@ -170,6 +171,10 @@ ifdef CONFIG_COCOA | ||
170 | OBJS+=cocoa.o | 171 | OBJS+=cocoa.o |
171 | endif | 172 | endif |
172 | 173 | ||
174 | +ifdef CONFIG_IOTHREAD | ||
175 | +OBJS+=qemu-thread.o | ||
176 | +endif | ||
177 | + | ||
173 | ifdef CONFIG_SLIRP | 178 | ifdef CONFIG_SLIRP |
174 | CPPFLAGS+=-I$(SRC_PATH)/slirp | 179 | CPPFLAGS+=-I$(SRC_PATH)/slirp |
175 | SLIRP_OBJS=cksum.o if.o ip_icmp.o ip_input.o ip_output.o \ | 180 | SLIRP_OBJS=cksum.o if.o ip_icmp.o ip_input.o ip_output.o \ |
Makefile.target
@@ -318,7 +318,8 @@ endif | @@ -318,7 +318,8 @@ endif | ||
318 | 318 | ||
319 | OBJS= main.o syscall.o strace.o mmap.o signal.o path.o thunk.o \ | 319 | OBJS= main.o syscall.o strace.o mmap.o signal.o path.o thunk.o \ |
320 | elfload.o linuxload.o uaccess.o envlist.o | 320 | elfload.o linuxload.o uaccess.o envlist.o |
321 | -LIBS+= $(AIOLIBS) | 321 | +LIBS+= $(PTHREADLIBS) |
322 | +LIBS+= $(CLOCKLIBS) | ||
322 | ifdef TARGET_HAS_BFLT | 323 | ifdef TARGET_HAS_BFLT |
323 | OBJS+= flatload.o | 324 | OBJS+= flatload.o |
324 | endif | 325 | endif |
@@ -694,7 +695,8 @@ ifdef CONFIG_SLIRP | @@ -694,7 +695,8 @@ ifdef CONFIG_SLIRP | ||
694 | CPPFLAGS+=-I$(SRC_PATH)/slirp | 695 | CPPFLAGS+=-I$(SRC_PATH)/slirp |
695 | endif | 696 | endif |
696 | 697 | ||
697 | -LIBS+=$(AIOLIBS) | 698 | +LIBS+=$(PTHREADLIBS) |
699 | +LIBS+=$(CLOCKLIBS) | ||
698 | # specific flags are needed for non soft mmu emulator | 700 | # specific flags are needed for non soft mmu emulator |
699 | ifdef CONFIG_STATIC | 701 | ifdef CONFIG_STATIC |
700 | LDFLAGS+=-static | 702 | LDFLAGS+=-static |
configure
@@ -181,7 +181,9 @@ bsd_user="no" | @@ -181,7 +181,9 @@ bsd_user="no" | ||
181 | build_docs="no" | 181 | build_docs="no" |
182 | uname_release="" | 182 | uname_release="" |
183 | curses="yes" | 183 | curses="yes" |
184 | +pthread="yes" | ||
184 | aio="yes" | 185 | aio="yes" |
186 | +io_thread="no" | ||
185 | nptl="yes" | 187 | nptl="yes" |
186 | mixemu="no" | 188 | mixemu="no" |
187 | bluez="yes" | 189 | bluez="yes" |
@@ -479,8 +481,12 @@ for opt do | @@ -479,8 +481,12 @@ for opt do | ||
479 | ;; | 481 | ;; |
480 | --enable-mixemu) mixemu="yes" | 482 | --enable-mixemu) mixemu="yes" |
481 | ;; | 483 | ;; |
484 | + --disable-pthread) pthread="no" | ||
485 | + ;; | ||
482 | --disable-aio) aio="no" | 486 | --disable-aio) aio="no" |
483 | ;; | 487 | ;; |
488 | + --enable-io-thread) io_thread="yes" | ||
489 | + ;; | ||
484 | --disable-blobs) blobs="no" | 490 | --disable-blobs) blobs="no" |
485 | ;; | 491 | ;; |
486 | --kerneldir=*) kerneldir="$optarg" | 492 | --kerneldir=*) kerneldir="$optarg" |
@@ -611,7 +617,9 @@ echo " --oss-lib path to OSS library" | @@ -611,7 +617,9 @@ echo " --oss-lib path to OSS library" | ||
611 | echo " --enable-uname-release=R Return R for uname -r in usermode emulation" | 617 | echo " --enable-uname-release=R Return R for uname -r in usermode emulation" |
612 | echo " --sparc_cpu=V Build qemu for Sparc architecture v7, v8, v8plus, v8plusa, v9" | 618 | echo " --sparc_cpu=V Build qemu for Sparc architecture v7, v8, v8plus, v8plusa, v9" |
613 | echo " --disable-vde disable support for vde network" | 619 | echo " --disable-vde disable support for vde network" |
620 | +echo " --disable-pthread disable pthread support" | ||
614 | echo " --disable-aio disable AIO support" | 621 | echo " --disable-aio disable AIO support" |
622 | +echo " --enable-io-thread enable IO thread" | ||
615 | echo " --disable-blobs disable installing provided firmware blobs" | 623 | echo " --disable-blobs disable installing provided firmware blobs" |
616 | echo " --kerneldir=PATH look for kernel includes in PATH" | 624 | echo " --kerneldir=PATH look for kernel includes in PATH" |
617 | echo "" | 625 | echo "" |
@@ -1123,21 +1131,26 @@ EOF | @@ -1123,21 +1131,26 @@ EOF | ||
1123 | fi | 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 | #include <pthread.h> | 1140 | #include <pthread.h> |
1133 | int main(void) { pthread_mutex_t lock; return 0; } | 1141 | int main(void) { pthread_mutex_t lock; return 0; } |
1134 | EOF | 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 | fi | 1146 | fi |
1139 | fi | 1147 | fi |
1140 | 1148 | ||
1149 | +if test "$pthread" = no; then | ||
1150 | + aio=no | ||
1151 | + io_thread=no | ||
1152 | +fi | ||
1153 | + | ||
1141 | ########################################## | 1154 | ########################################## |
1142 | # iovec probe | 1155 | # iovec probe |
1143 | cat > $TMPC <<EOF | 1156 | cat > $TMPC <<EOF |
@@ -1231,6 +1244,7 @@ fi | @@ -1231,6 +1244,7 @@ fi | ||
1231 | 1244 | ||
1232 | ########################################## | 1245 | ########################################## |
1233 | # Do we need librt | 1246 | # Do we need librt |
1247 | +CLOCKLIBS="" | ||
1234 | cat > $TMPC <<EOF | 1248 | cat > $TMPC <<EOF |
1235 | #include <signal.h> | 1249 | #include <signal.h> |
1236 | #include <time.h> | 1250 | #include <time.h> |
@@ -1245,8 +1259,7 @@ elif $cc $ARCH_CFLAGS -o $TMPE $TMPC -lrt > /dev/null 2> /dev/null ; then | @@ -1245,8 +1259,7 @@ elif $cc $ARCH_CFLAGS -o $TMPE $TMPC -lrt > /dev/null 2> /dev/null ; then | ||
1245 | fi | 1259 | fi |
1246 | 1260 | ||
1247 | if test "$rt" = "yes" ; then | 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 | fi | 1263 | fi |
1251 | 1264 | ||
1252 | if test "$mingw32" = "yes" ; then | 1265 | if test "$mingw32" = "yes" ; then |
@@ -1324,6 +1337,7 @@ echo "uname -r $uname_release" | @@ -1324,6 +1337,7 @@ echo "uname -r $uname_release" | ||
1324 | echo "NPTL support $nptl" | 1337 | echo "NPTL support $nptl" |
1325 | echo "vde support $vde" | 1338 | echo "vde support $vde" |
1326 | echo "AIO support $aio" | 1339 | echo "AIO support $aio" |
1340 | +echo "IO thread $io_thread" | ||
1327 | echo "Install blobs $blobs" | 1341 | echo "Install blobs $blobs" |
1328 | echo "KVM support $kvm" | 1342 | echo "KVM support $kvm" |
1329 | echo "fdt support $fdt" | 1343 | echo "fdt support $fdt" |
@@ -1376,7 +1390,8 @@ echo "ARCH_LDFLAGS=$ARCH_LDFLAGS" >> $config_mak | @@ -1376,7 +1390,8 @@ echo "ARCH_LDFLAGS=$ARCH_LDFLAGS" >> $config_mak | ||
1376 | echo "CFLAGS=$CFLAGS" >> $config_mak | 1390 | echo "CFLAGS=$CFLAGS" >> $config_mak |
1377 | echo "LDFLAGS=$LDFLAGS" >> $config_mak | 1391 | echo "LDFLAGS=$LDFLAGS" >> $config_mak |
1378 | echo "EXESUF=$EXESUF" >> $config_mak | 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 | case "$cpu" in | 1395 | case "$cpu" in |
1381 | i386) | 1396 | i386) |
1382 | echo "ARCH=i386" >> $config_mak | 1397 | echo "ARCH=i386" >> $config_mak |
@@ -1640,6 +1655,10 @@ if test "$aio" = "yes" ; then | @@ -1640,6 +1655,10 @@ if test "$aio" = "yes" ; then | ||
1640 | echo "#define CONFIG_AIO 1" >> $config_h | 1655 | echo "#define CONFIG_AIO 1" >> $config_h |
1641 | echo "CONFIG_AIO=yes" >> $config_mak | 1656 | echo "CONFIG_AIO=yes" >> $config_mak |
1642 | fi | 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 | if test "$blobs" = "yes" ; then | 1662 | if test "$blobs" = "yes" ; then |
1644 | echo "INSTALL_BLOBS=yes" >> $config_mak | 1663 | echo "INSTALL_BLOBS=yes" >> $config_mak |
1645 | fi | 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 |