aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile7
-rw-r--r--Makefile.target6
-rwxr-xr-xconfigure41
-rw-r--r--qemu-thread.c163
-rw-r--r--qemu-thread.h40
5 files changed, 243 insertions, 14 deletions
diff --git a/Makefile b/Makefile
index ed887de56..0f40cdac3 100644
--- a/Makefile
+++ b/Makefile
@@ -30,7 +30,8 @@ else
DOCS=
endif
-LIBS+=$(AIOLIBS)
+LIBS+=$(PTHREADLIBS)
+LIBS+=$(CLOCKLIBS)
ifdef CONFIG_SOLARIS
LIBS+=-lsocket -lnsl -lresolv
@@ -170,6 +171,10 @@ ifdef CONFIG_COCOA
OBJS+=cocoa.o
endif
+ifdef CONFIG_IOTHREAD
+OBJS+=qemu-thread.o
+endif
+
ifdef CONFIG_SLIRP
CPPFLAGS+=-I$(SRC_PATH)/slirp
SLIRP_OBJS=cksum.o if.o ip_icmp.o ip_input.o ip_output.o \
diff --git a/Makefile.target b/Makefile.target
index 21715873a..82ada5a0e 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -318,7 +318,8 @@ endif
OBJS= main.o syscall.o strace.o mmap.o signal.o path.o thunk.o \
elfload.o linuxload.o uaccess.o envlist.o
-LIBS+= $(AIOLIBS)
+LIBS+= $(PTHREADLIBS)
+LIBS+= $(CLOCKLIBS)
ifdef TARGET_HAS_BFLT
OBJS+= flatload.o
endif
@@ -694,7 +695,8 @@ ifdef CONFIG_SLIRP
CPPFLAGS+=-I$(SRC_PATH)/slirp
endif
-LIBS+=$(AIOLIBS)
+LIBS+=$(PTHREADLIBS)
+LIBS+=$(CLOCKLIBS)
# specific flags are needed for non soft mmu emulator
ifdef CONFIG_STATIC
LDFLAGS+=-static
diff --git a/configure b/configure
index b7b7b01d4..2f4ccfb40 100755
--- a/configure
+++ b/configure
@@ -181,7 +181,9 @@ bsd_user="no"
build_docs="no"
uname_release=""
curses="yes"
+pthread="yes"
aio="yes"
+io_thread="no"
nptl="yes"
mixemu="no"
bluez="yes"
@@ -479,8 +481,12 @@ for opt do
;;
--enable-mixemu) mixemu="yes"
;;
+ --disable-pthread) pthread="no"
+ ;;
--disable-aio) aio="no"
;;
+ --enable-io-thread) io_thread="yes"
+ ;;
--disable-blobs) blobs="no"
;;
--kerneldir=*) kerneldir="$optarg"
@@ -611,7 +617,9 @@ echo " --oss-lib path to OSS library"
echo " --enable-uname-release=R Return R for uname -r in usermode emulation"
echo " --sparc_cpu=V Build qemu for Sparc architecture v7, v8, v8plus, v8plusa, v9"
echo " --disable-vde disable support for vde network"
+echo " --disable-pthread disable pthread support"
echo " --disable-aio disable AIO support"
+echo " --enable-io-thread enable IO thread"
echo " --disable-blobs disable installing provided firmware blobs"
echo " --kerneldir=PATH look for kernel includes in PATH"
echo ""
@@ -1123,21 +1131,26 @@ EOF
fi
##########################################
-# AIO probe
-AIOLIBS=""
+# pthread probe
+PTHREADLIBS=""
-if test "$aio" = "yes" ; then
- aio=no
- cat > $TMPC << EOF
+if test "$pthread" = yes; then
+ pthread=no
+cat > $TMPC << EOF
#include <pthread.h>
int main(void) { pthread_mutex_t lock; return 0; }
EOF
- if $cc $ARCH_CFLAGS -o $TMPE $AIOLIBS $TMPC 2> /dev/null ; then
- aio=yes
- AIOLIBS="-lpthread"
+ if $cc $ARCH_CFLAGS -o $TMPE $PTHREADLIBS $TMPC 2> /dev/null ; then
+ pthread=yes
+ PTHREADLIBS="-lpthread"
fi
fi
+if test "$pthread" = no; then
+ aio=no
+ io_thread=no
+fi
+
##########################################
# iovec probe
cat > $TMPC <<EOF
@@ -1231,6 +1244,7 @@ fi
##########################################
# Do we need librt
+CLOCKLIBS=""
cat > $TMPC <<EOF
#include <signal.h>
#include <time.h>
@@ -1245,8 +1259,7 @@ elif $cc $ARCH_CFLAGS -o $TMPE $TMPC -lrt > /dev/null 2> /dev/null ; then
fi
if test "$rt" = "yes" ; then
- # Hack, we should have a general purpose LIBS for this sort of thing
- AIOLIBS="$AIOLIBS -lrt"
+ CLOCKLIBS="-lrt"
fi
if test "$mingw32" = "yes" ; then
@@ -1324,6 +1337,7 @@ echo "uname -r $uname_release"
echo "NPTL support $nptl"
echo "vde support $vde"
echo "AIO support $aio"
+echo "IO thread $io_thread"
echo "Install blobs $blobs"
echo "KVM support $kvm"
echo "fdt support $fdt"
@@ -1376,7 +1390,8 @@ echo "ARCH_LDFLAGS=$ARCH_LDFLAGS" >> $config_mak
echo "CFLAGS=$CFLAGS" >> $config_mak
echo "LDFLAGS=$LDFLAGS" >> $config_mak
echo "EXESUF=$EXESUF" >> $config_mak
-echo "AIOLIBS=$AIOLIBS" >> $config_mak
+echo "PTHREADLIBS=$PTHREADLIBS" >> $config_mak
+echo "CLOCKLIBS=$CLOCKLIBS" >> $config_mak
case "$cpu" in
i386)
echo "ARCH=i386" >> $config_mak
@@ -1640,6 +1655,10 @@ if test "$aio" = "yes" ; then
echo "#define CONFIG_AIO 1" >> $config_h
echo "CONFIG_AIO=yes" >> $config_mak
fi
+if test "$io_thread" = "yes" ; then
+ echo "CONFIG_IOTHREAD=yes" >> $config_mak
+ echo "#define CONFIG_IOTHREAD 1" >> $config_h
+fi
if test "$blobs" = "yes" ; then
echo "INSTALL_BLOBS=yes" >> $config_mak
fi
diff --git a/qemu-thread.c b/qemu-thread.c
new file mode 100644
index 000000000..719cfcddd
--- /dev/null
+++ b/qemu-thread.c
@@ -0,0 +1,163 @@
+/*
+ * Wrappers around mutex/cond/thread functions
+ *
+ * Copyright Red Hat, Inc. 2009
+ *
+ * Author:
+ * Marcelo Tosatti <mtosatti@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <time.h>
+#include <signal.h>
+#include <stdint.h>
+#include <string.h>
+#include "qemu-thread.h"
+
+static void error_exit(int err, const char *msg)
+{
+ fprintf(stderr, "qemu: %s: %s\n", msg, strerror(err));
+ exit(1);
+}
+
+void qemu_mutex_init(QemuMutex *mutex)
+{
+ int err;
+
+ err = pthread_mutex_init(&mutex->lock, NULL);
+ if (err)
+ error_exit(err, __func__);
+}
+
+void qemu_mutex_lock(QemuMutex *mutex)
+{
+ int err;
+
+ err = pthread_mutex_lock(&mutex->lock);
+ if (err)
+ error_exit(err, __func__);
+}
+
+int qemu_mutex_trylock(QemuMutex *mutex)
+{
+ return pthread_mutex_trylock(&mutex->lock);
+}
+
+static void timespec_add_ms(struct timespec *ts, uint64_t msecs)
+{
+ ts->tv_sec = ts->tv_sec + (long)(msecs / 1000);
+ ts->tv_nsec = (ts->tv_nsec + ((long)msecs % 1000) * 1000000);
+ if (ts->tv_nsec >= 1000000000) {
+ ts->tv_nsec -= 1000000000;
+ ts->tv_sec++;
+ }
+}
+
+int qemu_mutex_timedlock(QemuMutex *mutex, uint64_t msecs)
+{
+ int err;
+ struct timespec ts;
+
+ clock_gettime(CLOCK_REALTIME, &ts);
+ timespec_add_ms(&ts, msecs);
+
+ err = pthread_mutex_timedlock(&mutex->lock, &ts);
+ if (err && err != ETIMEDOUT)
+ error_exit(err, __func__);
+ return err;
+}
+
+void qemu_mutex_unlock(QemuMutex *mutex)
+{
+ int err;
+
+ err = pthread_mutex_unlock(&mutex->lock);
+ if (err)
+ error_exit(err, __func__);
+}
+
+void qemu_cond_init(QemuCond *cond)
+{
+ int err;
+
+ err = pthread_cond_init(&cond->cond, NULL);
+ if (err)
+ error_exit(err, __func__);
+}
+
+void qemu_cond_signal(QemuCond *cond)
+{
+ int err;
+
+ err = pthread_cond_signal(&cond->cond);
+ if (err)
+ error_exit(err, __func__);
+}
+
+void qemu_cond_broadcast(QemuCond *cond)
+{
+ int err;
+
+ err = pthread_cond_broadcast(&cond->cond);
+ if (err)
+ error_exit(err, __func__);
+}
+
+void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex)
+{
+ int err;
+
+ err = pthread_cond_wait(&cond->cond, &mutex->lock);
+ if (err)
+ error_exit(err, __func__);
+}
+
+int qemu_cond_timedwait(QemuCond *cond, QemuMutex *mutex, uint64_t msecs)
+{
+ struct timespec ts;
+ int err;
+
+ clock_gettime(CLOCK_REALTIME, &ts);
+ timespec_add_ms(&ts, msecs);
+
+ err = pthread_cond_timedwait(&cond->cond, &mutex->lock, &ts);
+ if (err && err != ETIMEDOUT)
+ error_exit(err, __func__);
+ return err;
+}
+
+void qemu_thread_create(QemuThread *thread,
+ void *(*start_routine)(void*),
+ void *arg)
+{
+ int err;
+
+ err = pthread_create(&thread->thread, NULL, start_routine, arg);
+ if (err)
+ error_exit(err, __func__);
+}
+
+void qemu_thread_signal(QemuThread *thread, int sig)
+{
+ int err;
+
+ err = pthread_kill(thread->thread, sig);
+ if (err)
+ error_exit(err, __func__);
+}
+
+void qemu_thread_self(QemuThread *thread)
+{
+ thread->thread = pthread_self();
+}
+
+int qemu_thread_equal(QemuThread *thread1, QemuThread *thread2)
+{
+ return (thread1->thread == thread2->thread);
+}
+
diff --git a/qemu-thread.h b/qemu-thread.h
new file mode 100644
index 000000000..5ef4a3aed
--- /dev/null
+++ b/qemu-thread.h
@@ -0,0 +1,40 @@
+#ifndef __QEMU_THREAD_H
+#define __QEMU_THREAD_H 1
+#include "semaphore.h"
+#include "pthread.h"
+
+struct QemuMutex {
+ pthread_mutex_t lock;
+};
+
+struct QemuCond {
+ pthread_cond_t cond;
+};
+
+struct QemuThread {
+ pthread_t thread;
+};
+
+typedef struct QemuMutex QemuMutex;
+typedef struct QemuCond QemuCond;
+typedef struct QemuThread QemuThread;
+
+void qemu_mutex_init(QemuMutex *mutex);
+void qemu_mutex_lock(QemuMutex *mutex);
+int qemu_mutex_trylock(QemuMutex *mutex);
+int qemu_mutex_timedlock(QemuMutex *mutex, uint64_t msecs);
+void qemu_mutex_unlock(QemuMutex *mutex);
+
+void qemu_cond_init(QemuCond *cond);
+void qemu_cond_signal(QemuCond *cond);
+void qemu_cond_broadcast(QemuCond *cond);
+void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex);
+int qemu_cond_timedwait(QemuCond *cond, QemuMutex *mutex, uint64_t msecs);
+
+void qemu_thread_create(QemuThread *thread,
+ void *(*start_routine)(void*),
+ void *arg);
+void qemu_thread_signal(QemuThread *thread, int sig);
+void qemu_thread_self(QemuThread *thread);
+int qemu_thread_equal(QemuThread *thread1, QemuThread *thread2);
+#endif