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:
aliguori 2009-04-24 18:03:15 +00:00
parent d9f75a4eb4
commit e5d355d12e
5 changed files with 243 additions and 14 deletions

View File

@ -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 \

View File

@ -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
View File

@ -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
View 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
View 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