From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55652) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V9dMI-0007Oo-RM for qemu-devel@nongnu.org; Wed, 14 Aug 2013 11:51:45 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1V9dMC-0007sP-Ef for qemu-devel@nongnu.org; Wed, 14 Aug 2013 11:51:38 -0400 Received: from mail-qa0-f49.google.com ([209.85.216.49]:45482) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V9dMC-0007sI-9z for qemu-devel@nongnu.org; Wed, 14 Aug 2013 11:51:32 -0400 Received: by mail-qa0-f49.google.com with SMTP id cr7so1160728qab.1 for ; Wed, 14 Aug 2013 08:51:31 -0700 (PDT) From: Mike Day Date: Wed, 14 Aug 2013 11:50:40 -0400 Message-Id: <1376495450-5133-5-git-send-email-ncmike@ncultra.org> In-Reply-To: <1376495450-5133-1-git-send-email-ncmike@ncultra.org> References: <1376495450-5133-1-git-send-email-ncmike@ncultra.org> Subject: [Qemu-devel] [RFC PATCH 04/14] qemu-thread: register threads with RCU List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Paolo Bonzini From: Paolo Bonzini Signed-off-by: Paolo Bonzini Reviewed-by: Mike Day --- 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 19e4840..5736676 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 37dd298..2371176 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) { @@ -388,6 +389,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) @@ -395,6 +416,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) { @@ -410,7 +436,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 27a5217..0c4850d 100644 --- a/util/qemu-thread-win32.c +++ b/util/qemu-thread-win32.c @@ -278,6 +278,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(); } @@ -293,6 +294,7 @@ void qemu_thread_exit(void *arg) data->exited = true; LeaveCriticalSection(&data->cs); } + rcu_unregister_thread(); _endthreadex(0); } -- 1.8.3.1