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
This commit is contained in:
parent
d9f75a4eb4
commit
e5d355d12e
7
Makefile
7
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 \
|
||||
|
@ -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
|
||||
|
41
configure
vendored
41
configure
vendored
@ -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
|
||||
|
163
qemu-thread.c
Normal file
163
qemu-thread.c
Normal file
@ -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);
|
||||
}
|
||||
|
40
qemu-thread.h
Normal file
40
qemu-thread.h
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user