|
|
|
@ -854,13 +854,32 @@ static void *qemu_tcg_cpu_thread_fn(void *arg) |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
static void qemu_cpu_kick_thread(CPUState *env) |
|
|
|
{ |
|
|
|
#ifndef _WIN32 |
|
|
|
int err; |
|
|
|
|
|
|
|
err = pthread_kill(env->thread->thread, SIG_IPI); |
|
|
|
if (err) { |
|
|
|
fprintf(stderr, "qemu:%s: %s", __func__, strerror(err)); |
|
|
|
exit(1); |
|
|
|
} |
|
|
|
#else /* _WIN32 */ |
|
|
|
if (!qemu_cpu_is_self(env)) { |
|
|
|
SuspendThread(env->thread->thread); |
|
|
|
cpu_signal(0); |
|
|
|
ResumeThread(env->thread->thread); |
|
|
|
} |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
void qemu_cpu_kick(void *_env) |
|
|
|
{ |
|
|
|
CPUState *env = _env; |
|
|
|
|
|
|
|
qemu_cond_broadcast(env->halt_cond); |
|
|
|
if (!env->thread_kicked) { |
|
|
|
qemu_thread_signal(env->thread, SIG_IPI); |
|
|
|
qemu_cpu_kick_thread(env); |
|
|
|
env->thread_kicked = true; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -871,7 +890,7 @@ void qemu_cpu_kick_self(void) |
|
|
|
assert(cpu_single_env); |
|
|
|
|
|
|
|
if (!cpu_single_env->thread_kicked) { |
|
|
|
qemu_thread_signal(cpu_single_env->thread, SIG_IPI); |
|
|
|
qemu_cpu_kick_thread(cpu_single_env); |
|
|
|
cpu_single_env->thread_kicked = true; |
|
|
|
} |
|
|
|
#else |
|
|
|
@ -893,7 +912,7 @@ void qemu_mutex_lock_iothread(void) |
|
|
|
} else { |
|
|
|
qemu_mutex_lock(&qemu_fair_mutex); |
|
|
|
if (qemu_mutex_trylock(&qemu_global_mutex)) { |
|
|
|
qemu_thread_signal(tcg_cpu_thread, SIG_IPI); |
|
|
|
qemu_cpu_kick_thread(first_cpu); |
|
|
|
qemu_mutex_lock(&qemu_global_mutex); |
|
|
|
} |
|
|
|
qemu_mutex_unlock(&qemu_fair_mutex); |
|
|
|
|