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=
|
DOCS=
|
||||||
endif
|
endif
|
||||||
|
|
||||||
LIBS+=$(AIOLIBS)
|
LIBS+=$(PTHREADLIBS)
|
||||||
|
LIBS+=$(CLOCKLIBS)
|
||||||
|
|
||||||
ifdef CONFIG_SOLARIS
|
ifdef CONFIG_SOLARIS
|
||||||
LIBS+=-lsocket -lnsl -lresolv
|
LIBS+=-lsocket -lnsl -lresolv
|
||||||
@ -170,6 +171,10 @@ ifdef CONFIG_COCOA
|
|||||||
OBJS+=cocoa.o
|
OBJS+=cocoa.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_IOTHREAD
|
||||||
|
OBJS+=qemu-thread.o
|
||||||
|
endif
|
||||||
|
|
||||||
ifdef CONFIG_SLIRP
|
ifdef CONFIG_SLIRP
|
||||||
CPPFLAGS+=-I$(SRC_PATH)/slirp
|
CPPFLAGS+=-I$(SRC_PATH)/slirp
|
||||||
SLIRP_OBJS=cksum.o if.o ip_icmp.o ip_input.o ip_output.o \
|
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 \
|
OBJS= main.o syscall.o strace.o mmap.o signal.o path.o thunk.o \
|
||||||
elfload.o linuxload.o uaccess.o envlist.o
|
elfload.o linuxload.o uaccess.o envlist.o
|
||||||
LIBS+= $(AIOLIBS)
|
LIBS+= $(PTHREADLIBS)
|
||||||
|
LIBS+= $(CLOCKLIBS)
|
||||||
ifdef TARGET_HAS_BFLT
|
ifdef TARGET_HAS_BFLT
|
||||||
OBJS+= flatload.o
|
OBJS+= flatload.o
|
||||||
endif
|
endif
|
||||||
@ -694,7 +695,8 @@ ifdef CONFIG_SLIRP
|
|||||||
CPPFLAGS+=-I$(SRC_PATH)/slirp
|
CPPFLAGS+=-I$(SRC_PATH)/slirp
|
||||||
endif
|
endif
|
||||||
|
|
||||||
LIBS+=$(AIOLIBS)
|
LIBS+=$(PTHREADLIBS)
|
||||||
|
LIBS+=$(CLOCKLIBS)
|
||||||
# specific flags are needed for non soft mmu emulator
|
# specific flags are needed for non soft mmu emulator
|
||||||
ifdef CONFIG_STATIC
|
ifdef CONFIG_STATIC
|
||||||
LDFLAGS+=-static
|
LDFLAGS+=-static
|
||||||
|
41
configure
vendored
41
configure
vendored
@ -181,7 +181,9 @@ bsd_user="no"
|
|||||||
build_docs="no"
|
build_docs="no"
|
||||||
uname_release=""
|
uname_release=""
|
||||||
curses="yes"
|
curses="yes"
|
||||||
|
pthread="yes"
|
||||||
aio="yes"
|
aio="yes"
|
||||||
|
io_thread="no"
|
||||||
nptl="yes"
|
nptl="yes"
|
||||||
mixemu="no"
|
mixemu="no"
|
||||||
bluez="yes"
|
bluez="yes"
|
||||||
@ -479,8 +481,12 @@ for opt do
|
|||||||
;;
|
;;
|
||||||
--enable-mixemu) mixemu="yes"
|
--enable-mixemu) mixemu="yes"
|
||||||
;;
|
;;
|
||||||
|
--disable-pthread) pthread="no"
|
||||||
|
;;
|
||||||
--disable-aio) aio="no"
|
--disable-aio) aio="no"
|
||||||
;;
|
;;
|
||||||
|
--enable-io-thread) io_thread="yes"
|
||||||
|
;;
|
||||||
--disable-blobs) blobs="no"
|
--disable-blobs) blobs="no"
|
||||||
;;
|
;;
|
||||||
--kerneldir=*) kerneldir="$optarg"
|
--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 " --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 " --sparc_cpu=V Build qemu for Sparc architecture v7, v8, v8plus, v8plusa, v9"
|
||||||
echo " --disable-vde disable support for vde network"
|
echo " --disable-vde disable support for vde network"
|
||||||
|
echo " --disable-pthread disable pthread support"
|
||||||
echo " --disable-aio disable AIO support"
|
echo " --disable-aio disable AIO support"
|
||||||
|
echo " --enable-io-thread enable IO thread"
|
||||||
echo " --disable-blobs disable installing provided firmware blobs"
|
echo " --disable-blobs disable installing provided firmware blobs"
|
||||||
echo " --kerneldir=PATH look for kernel includes in PATH"
|
echo " --kerneldir=PATH look for kernel includes in PATH"
|
||||||
echo ""
|
echo ""
|
||||||
@ -1123,21 +1131,26 @@ EOF
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
##########################################
|
##########################################
|
||||||
# AIO probe
|
# pthread probe
|
||||||
AIOLIBS=""
|
PTHREADLIBS=""
|
||||||
|
|
||||||
if test "$aio" = "yes" ; then
|
if test "$pthread" = yes; then
|
||||||
aio=no
|
pthread=no
|
||||||
cat > $TMPC << EOF
|
cat > $TMPC << EOF
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
int main(void) { pthread_mutex_t lock; return 0; }
|
int main(void) { pthread_mutex_t lock; return 0; }
|
||||||
EOF
|
EOF
|
||||||
if $cc $ARCH_CFLAGS -o $TMPE $AIOLIBS $TMPC 2> /dev/null ; then
|
if $cc $ARCH_CFLAGS -o $TMPE $PTHREADLIBS $TMPC 2> /dev/null ; then
|
||||||
aio=yes
|
pthread=yes
|
||||||
AIOLIBS="-lpthread"
|
PTHREADLIBS="-lpthread"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test "$pthread" = no; then
|
||||||
|
aio=no
|
||||||
|
io_thread=no
|
||||||
|
fi
|
||||||
|
|
||||||
##########################################
|
##########################################
|
||||||
# iovec probe
|
# iovec probe
|
||||||
cat > $TMPC <<EOF
|
cat > $TMPC <<EOF
|
||||||
@ -1231,6 +1244,7 @@ fi
|
|||||||
|
|
||||||
##########################################
|
##########################################
|
||||||
# Do we need librt
|
# Do we need librt
|
||||||
|
CLOCKLIBS=""
|
||||||
cat > $TMPC <<EOF
|
cat > $TMPC <<EOF
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@ -1245,8 +1259,7 @@ elif $cc $ARCH_CFLAGS -o $TMPE $TMPC -lrt > /dev/null 2> /dev/null ; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$rt" = "yes" ; then
|
if test "$rt" = "yes" ; then
|
||||||
# Hack, we should have a general purpose LIBS for this sort of thing
|
CLOCKLIBS="-lrt"
|
||||||
AIOLIBS="$AIOLIBS -lrt"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$mingw32" = "yes" ; then
|
if test "$mingw32" = "yes" ; then
|
||||||
@ -1324,6 +1337,7 @@ echo "uname -r $uname_release"
|
|||||||
echo "NPTL support $nptl"
|
echo "NPTL support $nptl"
|
||||||
echo "vde support $vde"
|
echo "vde support $vde"
|
||||||
echo "AIO support $aio"
|
echo "AIO support $aio"
|
||||||
|
echo "IO thread $io_thread"
|
||||||
echo "Install blobs $blobs"
|
echo "Install blobs $blobs"
|
||||||
echo "KVM support $kvm"
|
echo "KVM support $kvm"
|
||||||
echo "fdt support $fdt"
|
echo "fdt support $fdt"
|
||||||
@ -1376,7 +1390,8 @@ echo "ARCH_LDFLAGS=$ARCH_LDFLAGS" >> $config_mak
|
|||||||
echo "CFLAGS=$CFLAGS" >> $config_mak
|
echo "CFLAGS=$CFLAGS" >> $config_mak
|
||||||
echo "LDFLAGS=$LDFLAGS" >> $config_mak
|
echo "LDFLAGS=$LDFLAGS" >> $config_mak
|
||||||
echo "EXESUF=$EXESUF" >> $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
|
case "$cpu" in
|
||||||
i386)
|
i386)
|
||||||
echo "ARCH=i386" >> $config_mak
|
echo "ARCH=i386" >> $config_mak
|
||||||
@ -1640,6 +1655,10 @@ if test "$aio" = "yes" ; then
|
|||||||
echo "#define CONFIG_AIO 1" >> $config_h
|
echo "#define CONFIG_AIO 1" >> $config_h
|
||||||
echo "CONFIG_AIO=yes" >> $config_mak
|
echo "CONFIG_AIO=yes" >> $config_mak
|
||||||
fi
|
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
|
if test "$blobs" = "yes" ; then
|
||||||
echo "INSTALL_BLOBS=yes" >> $config_mak
|
echo "INSTALL_BLOBS=yes" >> $config_mak
|
||||||
fi
|
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