accel/qtest: Support qtest accelerator for Windows

Currently signal SIGIPI [=SIGUSR1] is used to kick the dummy CPU
when qtest accelerator is used. However SIGUSR1 is unsupported on
Windows. To support Windows, we add a QemuSemaphore CPUState::sem
to kick the dummy CPU instead for Windows.

Signed-off-by: Xuzhou Cheng <xuzhou.cheng@windriver.com>
Signed-off-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20221028045736.679903-2-bin.meng@windriver.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
This commit is contained in:
Xuzhou Cheng 2022-10-28 12:57:26 +08:00 committed by Thomas Huth
parent 8f4bcbcf11
commit c9923550b4
5 changed files with 20 additions and 9 deletions

View file

@ -21,8 +21,6 @@
static void *dummy_cpu_thread_fn(void *arg) static void *dummy_cpu_thread_fn(void *arg)
{ {
CPUState *cpu = arg; CPUState *cpu = arg;
sigset_t waitset;
int r;
rcu_register_thread(); rcu_register_thread();
@ -32,8 +30,13 @@ static void *dummy_cpu_thread_fn(void *arg)
cpu->can_do_io = 1; cpu->can_do_io = 1;
current_cpu = cpu; current_cpu = cpu;
#ifndef _WIN32
sigset_t waitset;
int r;
sigemptyset(&waitset); sigemptyset(&waitset);
sigaddset(&waitset, SIG_IPI); sigaddset(&waitset, SIG_IPI);
#endif
/* signal CPU creation */ /* signal CPU creation */
cpu_thread_signal_created(cpu); cpu_thread_signal_created(cpu);
@ -41,6 +44,7 @@ static void *dummy_cpu_thread_fn(void *arg)
do { do {
qemu_mutex_unlock_iothread(); qemu_mutex_unlock_iothread();
#ifndef _WIN32
do { do {
int sig; int sig;
r = sigwait(&waitset, &sig); r = sigwait(&waitset, &sig);
@ -49,6 +53,9 @@ static void *dummy_cpu_thread_fn(void *arg)
perror("sigwait"); perror("sigwait");
exit(1); exit(1);
} }
#else
qemu_sem_wait(&cpu->sem);
#endif
qemu_mutex_lock_iothread(); qemu_mutex_lock_iothread();
qemu_wait_io_event(cpu); qemu_wait_io_event(cpu);
} while (!cpu->unplug); } while (!cpu->unplug);
@ -69,4 +76,7 @@ void dummy_start_vcpu_thread(CPUState *cpu)
cpu->cpu_index); cpu->cpu_index);
qemu_thread_create(cpu->thread, thread_name, dummy_cpu_thread_fn, cpu, qemu_thread_create(cpu->thread, thread_name, dummy_cpu_thread_fn, cpu,
QEMU_THREAD_JOINABLE); QEMU_THREAD_JOINABLE);
#ifdef _WIN32
qemu_sem_init(&cpu->sem, 0);
#endif
} }

View file

@ -16,5 +16,5 @@ dummy_ss.add(files(
'dummy-cpus.c', 'dummy-cpus.c',
)) ))
specific_ss.add_all(when: ['CONFIG_SOFTMMU', 'CONFIG_POSIX'], if_true: dummy_ss) specific_ss.add_all(when: ['CONFIG_SOFTMMU'], if_true: dummy_ss)
specific_ss.add_all(when: ['CONFIG_XEN'], if_true: dummy_ss) specific_ss.add_all(when: ['CONFIG_XEN'], if_true: dummy_ss)

View file

@ -1,2 +1 @@
qtest_module_ss.add(when: ['CONFIG_SOFTMMU', 'CONFIG_POSIX'], qtest_module_ss.add(when: ['CONFIG_SOFTMMU'], if_true: files('qtest.c'))
if_true: files('qtest.c'))

View file

@ -333,6 +333,7 @@ struct CPUState {
struct QemuThread *thread; struct QemuThread *thread;
#ifdef _WIN32 #ifdef _WIN32
HANDLE hThread; HANDLE hThread;
QemuSemaphore sem;
#endif #endif
int thread_id; int thread_id;
bool running, has_waiter; bool running, has_waiter;

View file

@ -437,18 +437,19 @@ void qemu_wait_io_event(CPUState *cpu)
void cpus_kick_thread(CPUState *cpu) void cpus_kick_thread(CPUState *cpu)
{ {
#ifndef _WIN32
int err;
if (cpu->thread_kicked) { if (cpu->thread_kicked) {
return; return;
} }
cpu->thread_kicked = true; cpu->thread_kicked = true;
err = pthread_kill(cpu->thread->thread, SIG_IPI);
#ifndef _WIN32
int err = pthread_kill(cpu->thread->thread, SIG_IPI);
if (err && err != ESRCH) { if (err && err != ESRCH) {
fprintf(stderr, "qemu:%s: %s", __func__, strerror(err)); fprintf(stderr, "qemu:%s: %s", __func__, strerror(err));
exit(1); exit(1);
} }
#else
qemu_sem_post(&cpu->sem);
#endif #endif
} }