From ed9164a3549f93204d6b096136cda2ce54e9f03a Mon Sep 17 00:00:00 2001 From: Olivier Hainque Date: Tue, 9 Apr 2013 18:06:53 +0200 Subject: Check effective suspension of TCG thread On multi-core systems, SuspendThread does not guaranty immediate thread suspension. We add busy loop to wait for effective thread suspension after call to ThreadSuspend(). Signed-off-by: Fabien Chouteau Reviewed-by: Paolo Bonzini Signed-off-by: Stefan Weil --- cpus.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'cpus.c') diff --git a/cpus.c b/cpus.c index e919dd7fb6..97e9ab4c07 100644 --- a/cpus.c +++ b/cpus.c @@ -862,9 +862,29 @@ static void qemu_cpu_kick_thread(CPUState *cpu) } #else /* _WIN32 */ if (!qemu_cpu_is_self(cpu)) { - SuspendThread(cpu->hThread); + CONTEXT tcgContext; + + if (SuspendThread(cpu->hThread) == (DWORD)-1) { + fprintf(stderr, "qemu:%s: GetLastError:%d\n", __func__, + GetLastError()); + exit(1); + } + + /* On multi-core systems, we are not sure that the thread is actually + * suspended until we can get the context. + */ + tcgContext.ContextFlags = CONTEXT_CONTROL; + while (GetThreadContext(cpu->hThread, &tcgContext) != 0) { + continue; + } + cpu_signal(0); - ResumeThread(cpu->hThread); + + if (ResumeThread(cpu->hThread) == (DWORD)-1) { + fprintf(stderr, "qemu:%s: GetLastError:%d\n", __func__, + GetLastError()); + exit(1); + } } #endif } -- cgit v1.2.1