From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:60597) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UsdOD-0005rl-De for qemu-devel@nongnu.org; Fri, 28 Jun 2013 14:27:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UsdO7-0000NO-IA for qemu-devel@nongnu.org; Fri, 28 Jun 2013 14:27:21 -0400 Received: from mail-ee0-x22a.google.com ([2a00:1450:4013:c00::22a]:44603) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UsdO7-0000N5-7z for qemu-devel@nongnu.org; Fri, 28 Jun 2013 14:27:15 -0400 Received: by mail-ee0-f42.google.com with SMTP id c4so1221179eek.1 for ; Fri, 28 Jun 2013 11:27:14 -0700 (PDT) Received: from playground.lan (net-37-116-217-184.cust.dsl.vodafone.it. [37.116.217.184]) by mx.google.com with ESMTPSA id o5sm12035344eef.5.2013.06.28.11.27.12 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Fri, 28 Jun 2013 11:27:13 -0700 (PDT) Sender: Paolo Bonzini From: Paolo Bonzini Date: Fri, 28 Jun 2013 20:26:28 +0200 Message-Id: <1372444009-11544-10-git-send-email-pbonzini@redhat.com> In-Reply-To: <1372444009-11544-1-git-send-email-pbonzini@redhat.com> References: <1372444009-11544-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [PATCH 09/30] qemu-thread: register threads with RCU List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Signed-off-by: Paolo Bonzini --- docs/rcu.txt | 13 +++++++------ util/qemu-thread-posix.c | 28 +++++++++++++++++++++++++++- util/qemu-thread-win32.c | 2 ++ 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/docs/rcu.txt b/docs/rcu.txt index 4869ec7..118a28a 100644 --- a/docs/rcu.txt +++ b/docs/rcu.txt @@ -122,8 +122,8 @@ on many POSIX systems other than Linux and Solaris). For this reason, QEMU's RCU implementation resorts to manual annotation of "quiescent states", i.e. points where no RCU read-side critical -section can be active. All threads that participate in the RCU mechanism -need to annotate such points. +section can be active. All threads created with qemu_thread_create +participate in the RCU mechanism and need to annotate such points. Marking quiescent states is done with the following three APIs: @@ -144,8 +144,8 @@ Marking quiescent states is done with the following three APIs: thread. -Furthermore, threads that participate in the RCU mechanism must communicate -this fact using the following APIs: +The following APIs can be used to use RCU in a thread that is not +created with qemu_thread_create(): void rcu_register_thread(void); @@ -160,8 +160,9 @@ this fact using the following APIs: either manually or by using the QemuCond/QemuSemaphore/QemuEvent APIs. -Note that these APIs are relatively heavyweight, and should _not_ be -nested. +Note that these APIs are relatively heavyweight, should _not_ be +nested, and should not be called in threads that are created with +qemu_thread_create(). DIFFERENCES WITH LINUX diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c index 8178f9b..2df3382 100644 --- a/util/qemu-thread-posix.c +++ b/util/qemu-thread-posix.c @@ -26,6 +26,7 @@ #endif #include "qemu/thread.h" #include "qemu/atomic.h" +#include "qemu/rcu.h" static void error_exit(int err, const char *msg) { @@ -384,6 +385,26 @@ void qemu_event_wait(QemuEvent *ev) } +typedef struct QemuThreadData { + /* Passed to win32_start_routine. */ + void *(*start_routine)(void *); + void *arg; +} QemuThreadData; + +static void *thread_start_routine(void *arg) +{ + QemuThreadData *data = (QemuThreadData *) arg; + void *(*start_routine)(void *) = data->start_routine; + void *thread_arg = data->arg; + void *ret; + + rcu_register_thread(); + g_free(data); + ret = start_routine(thread_arg); + rcu_unregister_thread(); + return ret; +} + void qemu_thread_create(QemuThread *thread, void *(*start_routine)(void*), void *arg, int mode) @@ -391,6 +412,11 @@ void qemu_thread_create(QemuThread *thread, sigset_t set, oldset; int err; pthread_attr_t attr; + QemuThreadData *data; + + data = g_malloc(sizeof(*data)); + data->start_routine = start_routine; + data->arg = arg; err = pthread_attr_init(&attr); if (err) { @@ -406,7 +432,7 @@ void qemu_thread_create(QemuThread *thread, /* Leave signal handling to the iothread. */ sigfillset(&set); pthread_sigmask(SIG_SETMASK, &set, &oldset); - err = pthread_create(&thread->thread, &attr, start_routine, arg); + err = pthread_create(&thread->thread, &attr, thread_start_routine, data); if (err) error_exit(err, __func__); diff --git a/util/qemu-thread-win32.c b/util/qemu-thread-win32.c index de49f1e..18978be 100644 --- a/util/qemu-thread-win32.c +++ b/util/qemu-thread-win32.c @@ -295,6 +295,7 @@ static unsigned __stdcall win32_start_routine(void *arg) data = NULL; } qemu_thread_data = data; + rcu_register_thread(); qemu_thread_exit(start_routine(thread_arg)); abort(); } @@ -310,6 +311,7 @@ void qemu_thread_exit(void *arg) data->exited = true; LeaveCriticalSection(&data->cs); } + rcu_unregister_thread(); _endthreadex(0); } -- 1.8.1.4