aboutsummaryrefslogtreecommitdiff
path: root/cpus.c
diff options
context:
space:
mode:
authorOlivier Hainque <hainque@adacore.com>2013-04-09 18:06:53 +0200
committerStefan Weil <sw@weilnetz.de>2013-04-12 18:27:16 +0200
commited9164a3549f93204d6b096136cda2ce54e9f03a (patch)
tree990cd43823c5f8292a38e070a691a7bbc0ec0bee /cpus.c
parent93b48c201eb6c0404d15550a0eaa3c0f7937e35e (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>
Diffstat (limited to 'cpus.c')
-rw-r--r--cpus.c24
1 files changed, 22 insertions, 2 deletions
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
}