From: Anthony Liguori <aliguori@linux.vnet.ibm.com>
To: Aurelien Jarno <aurelien@aurel32.net>
Cc: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>,
Marcelo Tosatti <mtosatti@redhat.com>,
qemu-devel@nongnu.org, Paul Brook <paul@codesourcery.com>,
Arun Bharadwaj <arun@linux.vnet.ibm.com>,
Paulo Bonzini <pbonzini@redhat.com>
Subject: Re: [Qemu-devel] [PATCH 3/7] Add support for glib based threading and convert qemu thread to use it
Date: Tue, 25 Jan 2011 09:34:01 -0600 [thread overview]
Message-ID: <4D3EED69.3030407@linux.vnet.ibm.com> (raw)
In-Reply-To: <20110125142448.GI23331@hall.aurel32.net>
On 01/25/2011 08:24 AM, Aurelien Jarno wrote:
> On Mon, Jan 24, 2011 at 03:00:41PM -0600, Anthony Liguori wrote:
>
>> GLib is an extremely common library that has a portable thread implementation
>> along with tons of other goodies.
>>
>> GLib and GObject have a fantastic amount of infrastructure we can leverage in
>> QEMU including an object oriented programming infrastructure.
>>
>> Short term, it has a very nice thread pool implementation that we could leverage
>> in something like virtio-9p.
>>
>> Signed-off-by: Anthony Liguori<aliguori@us.ibm.com>
>>
>> diff --git a/Makefile b/Makefile
>> index 6d601ee..bf24d1b 100644
>> --- a/Makefile
>> +++ b/Makefile
>> @@ -104,6 +104,8 @@ audio/audio.o audio/fmodaudio.o: QEMU_CFLAGS += $(FMOD_CFLAGS)
>>
>> QEMU_CFLAGS+=$(CURL_CFLAGS)
>>
>> +QEMU_CFLAGS+=$(GLIB_CFLAGS)
>> +
>> ui/cocoa.o: ui/cocoa.m
>>
>> ui/sdl.o audio/sdlaudio.o ui/sdl_zoom.o baum.o: QEMU_CFLAGS += $(SDL_CFLAGS)
>> diff --git a/Makefile.objs b/Makefile.objs
>> index c3e52c5..283e62a 100644
>> --- a/Makefile.objs
>> +++ b/Makefile.objs
>> @@ -316,3 +316,5 @@ vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
>>
>> vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS)
>>
>> +vl.o: QEMU_CFLAGS+=$(GLIB_CFLAGS)
>> +
>> diff --git a/Makefile.target b/Makefile.target
>> index e15b1c4..2c1c90e 100644
>> --- a/Makefile.target
>> +++ b/Makefile.target
>> @@ -204,6 +204,7 @@ QEMU_CFLAGS += $(VNC_TLS_CFLAGS)
>> QEMU_CFLAGS += $(VNC_SASL_CFLAGS)
>> QEMU_CFLAGS += $(VNC_JPEG_CFLAGS)
>> QEMU_CFLAGS += $(VNC_PNG_CFLAGS)
>> +QEMU_CFLAGS += $(GLIB_CFLAGS)
>>
>> # xen backend driver support
>> obj-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o
>> diff --git a/configure b/configure
>> index d5ac074..820fde9 100755
>> --- a/configure
>> +++ b/configure
>> @@ -1658,6 +1658,17 @@ EOF
>> fi
>>
>> ##########################################
>> +# glib support probe
>> +if $pkg_config --modversion gthread-2.0> /dev/null 2>&1 ; then
>> + glib_cflags=`$pkg_config --cflags gthread-2.0 2>/dev/null`
>> + glib_libs=`$pkg_config --libs gthread-2.0 2>/dev/null`
>> + libs_softmmu="$glib_libs $libs_softmmu"
>> +else
>> + echo "glib-2.0 required to compile QEMU"
>> + exit 1
>> +fi
>> +
>> +##########################################
>> # kvm probe
>> if test "$kvm" != "no" ; then
>> cat> $TMPC<<EOF
>> @@ -2677,6 +2688,7 @@ if test "$bluez" = "yes" ; then
>> echo "CONFIG_BLUEZ=y">> $config_host_mak
>> echo "BLUEZ_CFLAGS=$bluez_cflags">> $config_host_mak
>> fi
>> +echo "GLIB_CFLAGS=$glib_cflags">> $config_host_mak
>> if test "$xen" = "yes" ; then
>> echo "CONFIG_XEN=y">> $config_host_mak
>> fi
>> diff --git a/qemu-thread.c b/qemu-thread.c
>> index fbc78fe..2c521ab 100644
>> --- a/qemu-thread.c
>> +++ b/qemu-thread.c
>> @@ -10,183 +10,142 @@
>> * 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>
>>
> Why removing<signal.h>?
>
It looked like unnecessary includes crept in so I remove them all. It
still built for me but apparently not for you. I'll update accordingly.
Maybe we should put signal.h in qemu-common.h?
Regards,
Anthony Liguori
>> -#include "qemu-thread.h"
>>
>> -static void error_exit(int err, const char *msg)
>> -{
>> - fprintf(stderr, "qemu: %s: %s\n", msg, strerror(err));
>> - exit(1);
>> -}
>> +#include "qemu-common.h"
>> +#include "qemu-thread.h"
>>
>> void qemu_mutex_init(QemuMutex *mutex)
>> {
>> - int err;
>> -
>> - err = pthread_mutex_init(&mutex->lock, NULL);
>> - if (err)
>> - error_exit(err, __func__);
>> + g_static_mutex_init(&mutex->lock);
>> }
>>
>> void qemu_mutex_destroy(QemuMutex *mutex)
>> {
>> - int err;
>> -
>> - err = pthread_mutex_destroy(&mutex->lock);
>> - if (err)
>> - error_exit(err, __func__);
>> + g_static_mutex_free(&mutex->lock);
>> }
>>
>> void qemu_mutex_lock(QemuMutex *mutex)
>> {
>> - int err;
>> -
>> - err = pthread_mutex_lock(&mutex->lock);
>> - if (err)
>> - error_exit(err, __func__);
>> + g_static_mutex_lock(&mutex->lock);
>> }
>>
>> 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;
>> + return g_static_mutex_trylock(&mutex->lock);
>> }
>>
>> void qemu_mutex_unlock(QemuMutex *mutex)
>> {
>> - int err;
>> -
>> - err = pthread_mutex_unlock(&mutex->lock);
>> - if (err)
>> - error_exit(err, __func__);
>> + g_static_mutex_unlock(&mutex->lock);
>> }
>>
>> void qemu_cond_init(QemuCond *cond)
>> {
>> - int err;
>> -
>> - err = pthread_cond_init(&cond->cond, NULL);
>> - if (err)
>> - error_exit(err, __func__);
>> + cond->cond = g_cond_new();
>> }
>>
>> void qemu_cond_destroy(QemuCond *cond)
>> {
>> - int err;
>> -
>> - err = pthread_cond_destroy(&cond->cond);
>> - if (err)
>> - error_exit(err, __func__);
>> + g_cond_free(cond->cond);
>> }
>>
>> void qemu_cond_signal(QemuCond *cond)
>> {
>> - int err;
>> -
>> - err = pthread_cond_signal(&cond->cond);
>> - if (err)
>> - error_exit(err, __func__);
>> + g_cond_signal(cond->cond);
>> }
>>
>> void qemu_cond_broadcast(QemuCond *cond)
>> {
>> - int err;
>> -
>> - err = pthread_cond_broadcast(&cond->cond);
>> - if (err)
>> - error_exit(err, __func__);
>> + g_cond_broadcast(cond->cond);
>> }
>>
>> void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex)
>> {
>> - int err;
>> -
>> - err = pthread_cond_wait(&cond->cond,&mutex->lock);
>> - if (err)
>> - error_exit(err, __func__);
>> + g_cond_wait(cond->cond, g_static_mutex_get_mutex(&mutex->lock));
>> }
>>
>> int qemu_cond_timedwait(QemuCond *cond, QemuMutex *mutex, uint64_t msecs)
>> {
>> - struct timespec ts;
>> - int err;
>> + GTimeVal abs_time;
>> +
>> + assert(cond->cond != NULL);
>>
>> - clock_gettime(CLOCK_REALTIME,&ts);
>> - timespec_add_ms(&ts, msecs);
>> + g_get_current_time(&abs_time);
>> + g_time_val_add(&abs_time, msecs * 1000); /* MSEC to USEC */
>>
>> - err = pthread_cond_timedwait(&cond->cond,&mutex->lock,&ts);
>> - if (err&& err != ETIMEDOUT)
>> - error_exit(err, __func__);
>> - return err;
>> + return g_cond_timed_wait(cond->cond,
>> + g_static_mutex_get_mutex(&mutex->lock),&abs_time);
>> +}
>> +
>> +struct trampoline_data
>> +{
>> + QemuThread *thread;
>> + void *(*startfn)(void *);
>> + void *opaque;
>> + QemuMutex lock;
>> +};
>> +
>> +static gpointer thread_trampoline(gpointer data)
>> +{
>> + struct trampoline_data *td = data;
>> + gpointer retval;
>> +
>> + td->thread->tid = pthread_self();
>> + qemu_mutex_unlock(&td->lock);
>> +
>> + retval = td->startfn(td->opaque);
>> + qemu_free(td);
>> +
>> + return retval;
>> }
>>
>> void qemu_thread_create(QemuThread *thread,
>> - void *(*start_routine)(void*),
>> - void *arg)
>> + void *(*start_routine)(void*),
>> + void *arg)
>> {
>> - int err;
>> + struct trampoline_data *td = qemu_malloc(sizeof(*td));
>> + sigset_t set, old;
>>
>> - /* Leave signal handling to the iothread. */
>> - sigset_t set, oldset;
>> + td->startfn = start_routine;
>> + td->opaque = arg;
>> + td->thread = thread;
>> + qemu_mutex_init(&td->lock);
>> +
>> + /* on behalf of the new thread */
>> + qemu_mutex_lock(&td->lock);
>>
>> sigfillset(&set);
>>
> If it is still in use here? This simply doesn't build:
>
> qemu-thread.c: In function ‘q_thread_create_nosignal’:
> qemu-thread.c:34: error: implicit declaration of function ‘sigfillset’
> qemu-thread.c:34: error: nested extern declaration of ‘sigfillset’
> qemu-thread.c:35: error: implicit declaration of function ‘pthread_sigmask’
> qemu-thread.c:35: error: nested extern declaration of ‘pthread_sigmask’
> qemu-thread.c:35: error: ‘SIG_SETMASK’ undeclared (first use in this function)
> qemu-thread.c:35: error: (Each undeclared identifier is reported only once
> qemu-thread.c:35: error: for each function it appears in.)
> qemu-thread.c: In function ‘qemu_sthread_create’:
> qemu-thread.c:80: error: ‘SIG_SETMASK’ undeclared (first use in this function)
> qemu-thread.c: In function ‘qemu_sthread_signal’:
> qemu-thread.c:96: error: implicit declaration of function ‘pthread_kill’
> qemu-thread.c:96: error: nested extern declaration of ‘pthread_kill’
>
>
>
>> - pthread_sigmask(SIG_SETMASK,&set,&oldset);
>> - err = pthread_create(&thread->thread, NULL, start_routine, arg);
>> - if (err)
>> - error_exit(err, __func__);
>> + pthread_sigmask(SIG_SETMASK,&set,&old);
>> + thread->thread = g_thread_create(thread_trampoline, td, TRUE, NULL);
>> + pthread_sigmask(SIG_SETMASK,&old, NULL);
>> +
>> + /* we're transfering ownership of this lock to the thread so we no
>> + * longer hold it here */
>>
>> - pthread_sigmask(SIG_SETMASK,&oldset, NULL);
>> + qemu_mutex_lock(&td->lock);
>> + /* validate tid */
>> + qemu_mutex_unlock(&td->lock);
>> +
>> + qemu_mutex_destroy(&td->lock);
>> }
>>
>> void qemu_thread_signal(QemuThread *thread, int sig)
>> {
>> - int err;
>> -
>> - err = pthread_kill(thread->thread, sig);
>> - if (err)
>> - error_exit(err, __func__);
>> + pthread_kill(thread->tid, sig);
>> }
>>
>> void qemu_thread_self(QemuThread *thread)
>> {
>> - thread->thread = pthread_self();
>> + thread->thread = g_thread_self();
>> + thread->tid = pthread_self();
>> }
>>
>> int qemu_thread_equal(QemuThread *thread1, QemuThread *thread2)
>> {
>> - return pthread_equal(thread1->thread, thread2->thread);
>> + return (thread1->thread == thread2->thread);
>> }
>>
>> void qemu_thread_exit(void *retval)
>> {
>> - pthread_exit(retval);
>> + g_thread_exit(retval);
>> }
>> diff --git a/qemu-thread.h b/qemu-thread.h
>> index 19bb30c..dc22a60 100644
>> --- a/qemu-thread.h
>> +++ b/qemu-thread.h
>> @@ -1,18 +1,19 @@
>> #ifndef __QEMU_THREAD_H
>> #define __QEMU_THREAD_H 1
>> -#include "semaphore.h"
>> -#include "pthread.h"
>> +#include<glib.h>
>> +#include<pthread.h>
>>
>> struct QemuMutex {
>> - pthread_mutex_t lock;
>> + GStaticMutex lock;
>> };
>>
>> struct QemuCond {
>> - pthread_cond_t cond;
>> + GCond *cond;
>> };
>>
>> struct QemuThread {
>> - pthread_t thread;
>> + GThread *thread;
>> + pthread_t tid;
>> };
>>
>> typedef struct QemuMutex QemuMutex;
>> diff --git a/vl.c b/vl.c
>> index 0292184..bbe0931 100644
>> --- a/vl.c
>> +++ b/vl.c
>> @@ -165,6 +165,8 @@ int main(int argc, char **argv)
>>
>> #include "ui/qemu-spice.h"
>>
>> +#include<glib.h>
>> +
>> //#define DEBUG_NET
>> //#define DEBUG_SLIRP
>>
>> @@ -1918,6 +1920,8 @@ int main(int argc, char **argv, char **envp)
>> atexit(qemu_run_exit_notifiers);
>> error_set_progname(argv[0]);
>>
>> + g_thread_init(NULL);
>> +
>> init_clocks();
>>
>> qemu_cache_utils_init(envp);
>> --
>> 1.7.0.4
>>
>>
>>
>>
>
next prev parent reply other threads:[~2011-01-25 15:34 UTC|newest]
Thread overview: 101+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-01-24 21:00 [Qemu-devel] [RFC 0/7] Introduce hard dependency on glib Anthony Liguori
2011-01-24 21:00 ` [Qemu-devel] [PATCH 1/7] io-thread: make sure to initialize qemu_work_cond and qemu_cpu_cond Anthony Liguori
2011-02-08 8:53 ` [Qemu-devel] " Jan Kiszka
2011-02-08 9:01 ` Anthony Liguori
2011-01-24 21:00 ` [Qemu-devel] [PATCH 2/7] Enable I/O thread and VNC threads by default Anthony Liguori
2011-01-24 22:28 ` [Qemu-devel] " Anthony Liguori
2011-01-25 9:17 ` Edgar E. Iglesias
2011-01-25 13:34 ` Marcelo Tosatti
2011-02-07 10:12 ` Marcelo Tosatti
2011-02-07 16:03 ` Marcelo Tosatti
2011-02-07 16:23 ` Paolo Bonzini
2011-02-07 17:10 ` Jan Kiszka
2011-02-07 21:02 ` Anthony Liguori
2011-02-07 21:45 ` Aurelien Jarno
2011-02-08 2:09 ` Anthony Liguori
2011-02-08 7:26 ` Aurelien Jarno
2011-02-08 8:08 ` Paolo Bonzini
2011-02-08 8:50 ` Jan Kiszka
2011-02-08 9:05 ` Aurelien Jarno
2011-02-08 9:12 ` Anthony Liguori
2011-02-08 9:49 ` Paolo Bonzini
2011-02-08 9:51 ` Jan Kiszka
2011-02-08 9:58 ` Aurelien Jarno
2011-02-08 10:03 ` Jan Kiszka
2011-02-08 10:06 ` Aurelien Jarno
2011-02-08 10:16 ` Alexander Graf
2011-02-08 10:17 ` Stefan Hajnoczi
2011-02-08 10:27 ` Aurelien Jarno
2011-02-08 10:31 ` Paolo Bonzini
2011-02-08 10:40 ` Jan Kiszka
2011-02-08 18:05 ` Anthony Liguori
2011-02-08 11:29 ` Aurelien Jarno
2011-02-08 12:38 ` Riku Voipio
2011-02-08 10:21 ` Jan Kiszka
2011-02-08 10:26 ` Aurelien Jarno
2011-02-08 10:30 ` Jan Kiszka
2011-02-08 17:58 ` Anthony Liguori
2011-02-08 11:07 ` Tristan Gingold
2011-02-08 11:46 ` Aurelien Jarno
2011-02-08 12:07 ` Paolo Bonzini
2011-02-08 19:21 ` Anthony Liguori
2011-02-08 11:15 ` Aurelien Jarno
2011-02-08 12:10 ` Paolo Bonzini
2011-02-08 13:31 ` Aurelien Jarno
2011-02-08 15:08 ` Aurelien Jarno
2011-02-09 17:35 ` Aurelien Jarno
2011-02-09 20:07 ` Anthony Liguori
2011-02-11 0:03 ` Marcelo Tosatti
2011-02-08 19:17 ` Anthony Liguori
2011-02-08 13:30 ` Aurelien Jarno
2011-02-08 20:54 ` Anthony Liguori
2011-02-08 15:09 ` Aurelien Jarno
2011-02-09 17:13 ` Blue Swirl
2011-02-09 22:16 ` [Qemu-devel] " Stefan Weil
2011-02-10 7:34 ` Paolo Bonzini
2011-02-10 9:54 ` Paolo Bonzini
2011-02-10 19:46 ` Stefan Weil
2011-02-08 10:06 ` [Qemu-devel] " Paolo Bonzini
2011-02-07 18:35 ` Edgar E. Iglesias
2011-02-07 20:44 ` Aurelien Jarno
2011-02-07 21:30 ` Scott Wood
2011-02-07 20:47 ` Edgar E. Iglesias
2011-01-25 8:33 ` [Qemu-devel] [PATCH 0/2] vnc: the lost parts Corentin Chary
2011-01-25 8:33 ` [Qemu-devel] [PATCH 1/2] vl.c: set NULL upon deleting handlers in qemu_set_fd_handler2() Corentin Chary
2011-01-25 10:03 ` Stefan Hajnoczi
2011-01-25 10:13 ` Corentin Chary
2011-01-25 10:26 ` Stefan Hajnoczi
2011-01-25 12:05 ` Yoshiaki Tamura
2011-01-25 8:33 ` [Qemu-devel] [PATCH 2/2] vnc: qemu can die if the client is disconnected while updating screen Corentin Chary
2011-01-24 21:00 ` [Qemu-devel] [PATCH 3/7] Add support for glib based threading and convert qemu thread to use it Anthony Liguori
2011-01-25 14:24 ` Aurelien Jarno
2011-01-25 15:34 ` Anthony Liguori [this message]
2011-02-02 17:32 ` [Qemu-devel] " Paolo Bonzini
2011-02-02 17:35 ` Anthony Liguori
2011-01-24 21:00 ` [Qemu-devel] [PATCH 4/7] Get rid of QemuMutex and teach its callers about GStaticMutex Anthony Liguori
2011-01-24 22:24 ` [Qemu-devel] " Jan Kiszka
2011-01-25 0:02 ` Anthony Liguori
2011-01-25 7:39 ` Jan Kiszka
2011-01-24 21:00 ` [Qemu-devel] [PATCH 5/7] threads: get rid of QemuCond and teach callers about GCond Anthony Liguori
2011-01-24 21:00 ` [Qemu-devel] [PATCH 6/7] Teach vnc server to use GThread directly Anthony Liguori
2011-01-26 10:39 ` Stefan Hajnoczi
2011-01-24 21:00 ` [Qemu-devel] [PATCH 7/7] Rename QemuThread to QemuSThread to indicate that it is not a generic thread Anthony Liguori
2011-01-24 21:28 ` [Qemu-devel] Re: [RFC 0/7] Introduce hard dependency on glib Paolo Bonzini
2011-01-24 22:01 ` Anthony Liguori
2011-01-25 10:41 ` Paolo Bonzini
2011-01-25 11:14 ` Daniel P. Berrange
2011-01-25 11:21 ` Paolo Bonzini
2011-01-25 0:24 ` [Qemu-devel] " Anthony Liguori
2011-01-25 6:51 ` Edgar E. Iglesias
2011-01-25 10:24 ` Stefan Hajnoczi
2011-01-25 11:51 ` Gerd Hoffmann
2011-01-25 12:04 ` Daniel P. Berrange
2011-01-25 14:48 ` Stefano Stabellini
2011-01-25 17:48 ` Anthony Liguori
2011-01-25 18:12 ` Stefano Stabellini
2011-01-25 14:23 ` Aurelien Jarno
2011-01-25 15:35 ` Anthony Liguori
[not found] ` <20110126044710.GU9566@redhat.com>
2011-01-26 15:53 ` Anthony Liguori
2011-01-26 21:23 ` Stefan Hajnoczi
2011-01-26 22:12 ` Anthony Liguori
2011-01-26 17:48 ` Johannes Stezenbach
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4D3EED69.3030407@linux.vnet.ibm.com \
--to=aliguori@linux.vnet.ibm.com \
--cc=arun@linux.vnet.ibm.com \
--cc=aurelien@aurel32.net \
--cc=mtosatti@redhat.com \
--cc=paul@codesourcery.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@linux.vnet.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).