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 | ... | ... |