diff options
author | Olivier Hainque <hainque@adacore.com> | 2013-04-09 18:06:53 +0200 |
---|---|---|
committer | Stefan Weil <sw@weilnetz.de> | 2013-04-12 18:27:16 +0200 |
commit | ed9164a3549f93204d6b096136cda2ce54e9f03a (patch) | |
tree | 990cd43823c5f8292a38e070a691a7bbc0ec0bee | |
parent | 93b48c201eb6c0404d15550a0eaa3c0f7937e35e (diff) |
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 <chouteau@adacore.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefan Weil <sw@weilnetz.de>
-rw-r--r-- | cpus.c | 24 |
1 files changed, 22 insertions, 2 deletions
@@ -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 } |