#include "gdbstub.h"
#include "dma.h"
#include "kvm.h"
-#include "exec-all.h"
#include "qemu-thread.h"
#include "cpus.h"
+
+#ifndef _WIN32
#include "compatfd.h"
+#endif
#ifdef SIGRTMIN
#define SIG_IPI (SIGRTMIN+4)
return true;
}
-static bool all_cpu_threads_idle(void)
+bool all_cpu_threads_idle(void)
{
CPUState *env;
/* EAGAIN is fine, a read must be pending. */
if (ret < 0 && errno != EAGAIN) {
- fprintf(stderr, "qemu_event_increment: write() filed: %s\n",
+ fprintf(stderr, "qemu_event_increment: write() failed: %s\n",
strerror(errno));
exit (1);
}
sigaddset(&set, SIGUSR2);
pthread_sigmask(SIG_UNBLOCK, &set, NULL);
+ /*
+ * SIG_IPI must be blocked in the main thread and must not be caught
+ * by sigwait() in the signal thread. Otherwise, the cpu thread will
+ * not catch it reliably.
+ */
+ sigemptyset(&set);
+ sigaddset(&set, SIG_IPI);
+ pthread_sigmask(SIG_BLOCK, &set, NULL);
+
sigemptyset(&set);
sigaddset(&set, SIGIO);
sigaddset(&set, SIGALRM);
- sigaddset(&set, SIG_IPI);
sigaddset(&set, SIGBUS);
- pthread_sigmask(SIG_BLOCK, &set, NULL);
#else
sigemptyset(&set);
sigaddset(&set, SIGBUS);
sigaddset(&set, SIGALRM);
}
#endif
+ pthread_sigmask(SIG_BLOCK, &set, NULL);
sigfd = qemu_signalfd(&set);
if (sigfd == -1) {
CPUState *env;
while (all_cpu_threads_idle()) {
+ /* Start accounting real time to the virtual clock if the CPUs
+ are idle. */
+ qemu_clock_warp(vm_clock);
qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex);
}
while (1) {
cpu_exec_all();
- if (use_icount && qemu_next_deadline() <= 0) {
+ if (use_icount && qemu_next_icount_deadline() <= 0) {
qemu_notify_event();
}
qemu_tcg_wait_io_event();
qemu_icount -= (env->icount_decr.u16.low + env->icount_extra);
env->icount_decr.u16.low = 0;
env->icount_extra = 0;
- count = qemu_icount_round (qemu_next_deadline());
+ count = qemu_icount_round(qemu_next_icount_deadline());
qemu_icount += count;
decr = (count > 0xffff) ? 0xffff : count;
count -= decr;
{
int r;
+ /* Account partial waits to the vm_clock. */
+ qemu_clock_warp(vm_clock);
+
if (next_cpu == NULL) {
next_cpu = first_cpu;
}
cpu_set_log(mask);
}
+void set_cpu_log_filename(const char *optarg)
+{
+ cpu_set_log_filename(optarg);
+}
+
/* Return the virtual CPU time, based on the instruction counter. */
int64_t cpu_get_icount(void)
{