* [Qemu-devel] [PATCH v2 uq/master 00/22] Win32 iothread support
@ 2011-02-26 15:39 Paolo Bonzini
2011-02-26 15:39 ` [Qemu-devel] [PATCH v2 upstream 01/22] unlock iothread during WaitForMultipleObjects Paolo Bonzini
` (23 more replies)
0 siblings, 24 replies; 31+ messages in thread
From: Paolo Bonzini @ 2011-02-26 15:39 UTC (permalink / raw)
To: qemu-devel; +Cc: jan.kiszka, aurelien
After gathering the comments about the two series I sent separately,
here is the full series for Win32 iothread support, ready to be
applied to uq/master.
Patches 1 to 5 are generic Win32 improvements, including the qemu-thread
implementation. Because of complex dependencies, I think it's better
if this part is also routed through uq/master.
Patches 6 to 8 are generic threading improvements, including using
PTHREAD_MUTEX_ERRORCHECK as suggested by Jan.
Patches 9 to 17 eliminate polling, replacing condition variable
timedwait with wait.
Patch 18 removes a redundant condition from the TCG cpu_exec_all
function.
Patches 19 to 21 add all necessary stubs to make iothread compile
with Win32, except the IPI calls. These are provided by patch 22.
Tested on Wine and Linux, not on "real" Windows. The series introduces
a dependency on Windows 2K or newer. I don't think either 95/98/ME
or Windows NT 3.x are reasonable host systems for QEMU, anyway.
I incorporated all suggestions from Jan, including his renaming patch
for qemu_*_is_self, and included Aurelien's sh4 tweak to cpu_halted.
Aurelien Jarno (1):
target-sh4: move intr_at_halt out of cpu_halted()
Jan Kiszka (1):
Refactor thread retrieval and check
Paolo Bonzini (20):
unlock iothread during WaitForMultipleObjects
implement win32 dynticks timer
use win32 timer queues
add win32 qemu-thread implementation
include qemu-thread.h early
add assertions on the owner of a QemuMutex
remove CONFIG_THREAD
inline cpu_halted into sole caller
always qemu_cpu_kick after unhalting a cpu
exit round-robin vcpu loop if cpu->stopped is true
always signal pause_cond after stopping a VCPU
do not use timedwait on qemu_halt_cond
do not use timedwait on qemu_system_cond
do not use timedwait on qemu_pause_cond
do not use timedwait on qemu_cpu_cond
iothread stops the vcpu thread via IPI
move blocking of signals to qemu_signalfd_init
provide dummy signal init functions for win32
protect qemu_cpu_kick_self for Win32
add Win32 IPI service
Makefile.objs | 4 +-
configure | 2 -
cpu-exec.c | 9 +-
cpus.c | 298 +++++++++++++++++-----------------
exec.c | 2 +-
hw/ppc.c | 2 +
hw/sun4m.c | 10 +-
hw/sun4u.c | 4 +-
os-win32.c | 2 +
qemu-common.h | 2 +-
qemu-thread.c => qemu-thread-posix.c | 38 +++--
qemu-thread-posix.h | 18 ++
qemu-thread-win32.c | 260 +++++++++++++++++++++++++++++
qemu-thread-win32.h | 21 +++
qemu-thread.h | 31 ++--
qemu-timer.c | 89 +++++------
target-alpha/exec.h | 11 --
target-arm/exec.h | 13 --
target-cris/exec.h | 11 --
target-i386/exec.h | 12 --
target-i386/kvm.c | 4 +-
target-m68k/exec.h | 10 --
target-microblaze/exec.h | 11 --
target-mips/exec.h | 11 --
target-ppc/exec.h | 11 --
target-s390x/exec.h | 12 --
target-s390x/kvm.c | 1 +
target-sh4/cpu.h | 2 +-
target-sh4/exec.h | 11 --
target-sh4/helper.c | 4 +-
target-sh4/op_helper.c | 1 +
target-sparc/exec.h | 10 --
ui/vnc-jobs-async.c | 2 +-
33 files changed, 562 insertions(+), 367 deletions(-)
rename qemu-thread.c => qemu-thread-posix.c (81%)
create mode 100644 qemu-thread-posix.h
create mode 100644 qemu-thread-win32.c
create mode 100644 qemu-thread-win32.h
--
1.7.4
^ permalink raw reply [flat|nested] 31+ messages in thread
* [Qemu-devel] [PATCH v2 upstream 01/22] unlock iothread during WaitForMultipleObjects
2011-02-26 15:39 [Qemu-devel] [PATCH v2 uq/master 00/22] Win32 iothread support Paolo Bonzini
@ 2011-02-26 15:39 ` Paolo Bonzini
2011-02-26 15:39 ` [Qemu-devel] [PATCH v2 upstream 02/22] implement win32 dynticks timer Paolo Bonzini
` (22 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2011-02-26 15:39 UTC (permalink / raw)
To: qemu-devel; +Cc: jan.kiszka, aurelien
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
os-win32.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/os-win32.c b/os-win32.c
index b214e6a..c971d92 100644
--- a/os-win32.c
+++ b/os-win32.c
@@ -140,7 +140,9 @@ void os_host_main_loop_wait(int *timeout)
int err;
WaitObjects *w = &wait_objects;
+ qemu_mutex_unlock_iothread();
ret = WaitForMultipleObjects(w->num, w->events, FALSE, *timeout);
+ qemu_mutex_lock_iothread();
if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) {
if (w->func[ret - WAIT_OBJECT_0])
w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]);
--
1.7.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PATCH v2 upstream 02/22] implement win32 dynticks timer
2011-02-26 15:39 [Qemu-devel] [PATCH v2 uq/master 00/22] Win32 iothread support Paolo Bonzini
2011-02-26 15:39 ` [Qemu-devel] [PATCH v2 upstream 01/22] unlock iothread during WaitForMultipleObjects Paolo Bonzini
@ 2011-02-26 15:39 ` Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 03/22] use win32 timer queues Paolo Bonzini
` (21 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2011-02-26 15:39 UTC (permalink / raw)
To: qemu-devel; +Cc: jan.kiszka, aurelien
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
qemu-timer.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/qemu-timer.c b/qemu-timer.c
index 88c7b28..122e7ed 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -1004,6 +1004,7 @@ static void win32_stop_timer(struct qemu_alarm_timer *t)
static void win32_rearm_timer(struct qemu_alarm_timer *t)
{
struct qemu_alarm_win32 *data = t->priv;
+ int nearest_delta_ms;
assert(alarm_has_dynticks(t));
if (!active_timers[QEMU_CLOCK_REALTIME] &&
@@ -1013,7 +1014,11 @@ static void win32_rearm_timer(struct qemu_alarm_timer *t)
timeKillEvent(data->timerId);
- data->timerId = timeSetEvent(1,
+ nearest_delta_ms = (qemu_next_alarm_deadline() + 999999) / 1000000;
+ if (nearest_delta_ms < 1) {
+ nearest_delta_ms = 1;
+ }
+ data->timerId = timeSetEvent(nearest_delta_ms,
data->period,
host_alarm_handler,
(DWORD)t,
--
1.7.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PATCH v2 upstream 03/22] use win32 timer queues
2011-02-26 15:39 [Qemu-devel] [PATCH v2 uq/master 00/22] Win32 iothread support Paolo Bonzini
2011-02-26 15:39 ` [Qemu-devel] [PATCH v2 upstream 01/22] unlock iothread during WaitForMultipleObjects Paolo Bonzini
2011-02-26 15:39 ` [Qemu-devel] [PATCH v2 upstream 02/22] implement win32 dynticks timer Paolo Bonzini
@ 2011-02-26 15:40 ` Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 04/22] Refactor thread retrieval and check Paolo Bonzini
` (20 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2011-02-26 15:40 UTC (permalink / raw)
To: qemu-devel; +Cc: jan.kiszka, aurelien
Multimedia timers are only useful for compatibility with Windows NT 4.0
and earlier. Plus, the implementation in Wine is extremely heavyweight.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
qemu-timer.c | 86 +++++++++++++++++++++++----------------------------------
1 files changed, 35 insertions(+), 51 deletions(-)
diff --git a/qemu-timer.c b/qemu-timer.c
index 122e7ed..1939d6b 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -200,11 +200,6 @@ static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
#ifdef _WIN32
-struct qemu_alarm_win32 {
- MMRESULT timerId;
- unsigned int period;
-} alarm_win32_data = {0, 0};
-
static int win32_start_timer(struct qemu_alarm_timer *t);
static void win32_stop_timer(struct qemu_alarm_timer *t);
static void win32_rearm_timer(struct qemu_alarm_timer *t);
@@ -298,9 +293,9 @@ static struct qemu_alarm_timer alarm_timers[] = {
{"unix", unix_start_timer, unix_stop_timer, NULL, NULL},
#else
{"dynticks", win32_start_timer,
- win32_stop_timer, win32_rearm_timer, &alarm_win32_data},
+ win32_stop_timer, win32_rearm_timer, NULL},
{"win32", win32_start_timer,
- win32_stop_timer, NULL, &alarm_win32_data},
+ win32_stop_timer, NULL, NULL},
#endif
{NULL, }
};
@@ -636,9 +631,7 @@ void qemu_run_all_timers(void)
static int64_t qemu_next_alarm_deadline(void);
#ifdef _WIN32
-static void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
- DWORD_PTR dwUser, DWORD_PTR dw1,
- DWORD_PTR dw2)
+static void CALLBACK host_alarm_handler(PVOID lpParam, BOOLEAN unused)
#else
static void host_alarm_handler(int host_signum)
#endif
@@ -961,50 +954,45 @@ static void unix_stop_timer(struct qemu_alarm_timer *t)
static int win32_start_timer(struct qemu_alarm_timer *t)
{
- TIMECAPS tc;
- struct qemu_alarm_win32 *data = t->priv;
- UINT flags;
-
- memset(&tc, 0, sizeof(tc));
- timeGetDevCaps(&tc, sizeof(tc));
-
- data->period = tc.wPeriodMin;
- timeBeginPeriod(data->period);
-
- flags = TIME_CALLBACK_FUNCTION;
- if (alarm_has_dynticks(t))
- flags |= TIME_ONESHOT;
- else
- flags |= TIME_PERIODIC;
-
- data->timerId = timeSetEvent(1, // interval (ms)
- data->period, // resolution
- host_alarm_handler, // function
- (DWORD)t, // parameter
- flags);
-
- if (!data->timerId) {
+ HANDLE hTimer;
+ BOOLEAN success;
+
+ /* If you call ChangeTimerQueueTimer on a one-shot timer (its period
+ is zero) that has already expired, the timer is not updated. Since
+ creating a new timer is relatively expensive, set a bogus one-hour
+ interval in the dynticks case. */
+ success = CreateTimerQueueTimer(&hTimer,
+ NULL,
+ host_alarm_handler,
+ t,
+ 1,
+ alarm_has_dynticks(t) ? 3600000 : 1,
+ WT_EXECUTEINTIMERTHREAD);
+
+ if (!success) {
fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n",
GetLastError());
- timeEndPeriod(data->period);
return -1;
}
+ t->priv = (PVOID) hTimer;
return 0;
}
static void win32_stop_timer(struct qemu_alarm_timer *t)
{
- struct qemu_alarm_win32 *data = t->priv;
+ HANDLE hTimer = t->priv;
- timeKillEvent(data->timerId);
- timeEndPeriod(data->period);
+ if (hTimer) {
+ DeleteTimerQueueTimer(NULL, hTimer, NULL);
+ }
}
static void win32_rearm_timer(struct qemu_alarm_timer *t)
{
- struct qemu_alarm_win32 *data = t->priv;
+ HANDLE hTimer = t->priv;
int nearest_delta_ms;
+ BOOLEAN success;
assert(alarm_has_dynticks(t));
if (!active_timers[QEMU_CLOCK_REALTIME] &&
@@ -1012,25 +1000,21 @@ static void win32_rearm_timer(struct qemu_alarm_timer *t)
!active_timers[QEMU_CLOCK_HOST])
return;
- timeKillEvent(data->timerId);
-
nearest_delta_ms = (qemu_next_alarm_deadline() + 999999) / 1000000;
if (nearest_delta_ms < 1) {
nearest_delta_ms = 1;
}
- data->timerId = timeSetEvent(nearest_delta_ms,
- data->period,
- host_alarm_handler,
- (DWORD)t,
- TIME_ONESHOT | TIME_CALLBACK_FUNCTION);
-
- if (!data->timerId) {
- fprintf(stderr, "Failed to re-arm win32 alarm timer %ld\n",
- GetLastError());
+ success = ChangeTimerQueueTimer(NULL,
+ hTimer,
+ nearest_delta_ms,
+ 3600000);
- timeEndPeriod(data->period);
- exit(1);
+ if (!success) {
+ fprintf(stderr, "Failed to rearm win32 alarm timer: %ld\n",
+ GetLastError());
+ exit(-1);
}
+
}
#endif /* _WIN32 */
--
1.7.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PATCH v2 upstream 04/22] Refactor thread retrieval and check
2011-02-26 15:39 [Qemu-devel] [PATCH v2 uq/master 00/22] Win32 iothread support Paolo Bonzini
` (2 preceding siblings ...)
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 03/22] use win32 timer queues Paolo Bonzini
@ 2011-02-26 15:40 ` Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 05/22] add win32 qemu-thread implementation Paolo Bonzini
` (19 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2011-02-26 15:40 UTC (permalink / raw)
To: qemu-devel; +Cc: jan.kiszka, aurelien
From: Jan Kiszka <jan.kiszka@siemens.com>
We have qemu_cpu_self and qemu_thread_self. The latter is retrieving the
current thread, the former is checking for equality (using CPUState). We
also have qemu_thread_equal which is only used like qemu_cpu_self.
This refactors the interfaces, creating qemu_cpu_is_self and
qemu_thread_is_self as well ass qemu_thread_get_self.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
cpus.c | 22 ++++++++--------------
exec.c | 2 +-
qemu-common.h | 2 +-
qemu-thread.c | 6 +++---
qemu-thread.h | 4 ++--
target-i386/kvm.c | 4 ++--
ui/vnc-jobs-async.c | 2 +-
7 files changed, 18 insertions(+), 24 deletions(-)
diff --git a/cpus.c b/cpus.c
index 0f33945..09ce6fe 100644
--- a/cpus.c
+++ b/cpus.c
@@ -531,7 +531,7 @@ void qemu_init_vcpu(void *_env)
}
}
-int qemu_cpu_self(void *env)
+int qemu_cpu_is_self(void *env)
{
return 1;
}
@@ -699,7 +699,7 @@ int qemu_init_main_loop(void)
qemu_mutex_init(&qemu_global_mutex);
qemu_mutex_lock(&qemu_global_mutex);
- qemu_thread_self(&io_thread);
+ qemu_thread_get_self(&io_thread);
return 0;
}
@@ -714,7 +714,7 @@ void run_on_cpu(CPUState *env, void (*func)(void *data), void *data)
{
struct qemu_work_item wi;
- if (qemu_cpu_self(env)) {
+ if (qemu_cpu_is_self(env)) {
func(data);
return;
}
@@ -808,7 +808,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
int r;
qemu_mutex_lock(&qemu_global_mutex);
- qemu_thread_self(env->thread);
+ qemu_thread_get_self(env->thread);
r = kvm_init_vcpu(env);
if (r < 0) {
@@ -845,7 +845,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
CPUState *env = arg;
qemu_tcg_init_cpu_signals();
- qemu_thread_self(env->thread);
+ qemu_thread_get_self(env->thread);
/* signal CPU creation */
qemu_mutex_lock(&qemu_global_mutex);
@@ -888,14 +888,11 @@ void qemu_cpu_kick_self(void)
}
}
-int qemu_cpu_self(void *_env)
+int qemu_cpu_is_self(void *_env)
{
CPUState *env = _env;
- QemuThread this;
- qemu_thread_self(&this);
-
- return qemu_thread_equal(&this, env->thread);
+ return qemu_thread_is_self(env->thread);
}
void qemu_mutex_lock_iothread(void)
@@ -1023,10 +1020,7 @@ void cpu_stop_current(void)
void vm_stop(int reason)
{
- QemuThread me;
- qemu_thread_self(&me);
-
- if (!qemu_thread_equal(&me, &io_thread)) {
+ if (!qemu_thread_is_self(&io_thread)) {
qemu_system_vmstop_request(reason);
/*
* FIXME: should not return to device code in case
diff --git a/exec.c b/exec.c
index d611100..439a6f6 100644
--- a/exec.c
+++ b/exec.c
@@ -1640,7 +1640,7 @@ void cpu_interrupt(CPUState *env, int mask)
* If called from iothread context, wake the target cpu in
* case its halted.
*/
- if (!qemu_cpu_self(env)) {
+ if (!qemu_cpu_is_self(env)) {
qemu_cpu_kick(env);
return;
}
diff --git a/qemu-common.h b/qemu-common.h
index 40dad52..958a002 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -289,7 +289,7 @@ void qemu_notify_event(void);
/* Unblock cpu */
void qemu_cpu_kick(void *env);
void qemu_cpu_kick_self(void);
-int qemu_cpu_self(void *env);
+int qemu_cpu_is_self(void *env);
/* work queue */
struct qemu_work_item {
diff --git a/qemu-thread.c b/qemu-thread.c
index fbc78fe..e307773 100644
--- a/qemu-thread.c
+++ b/qemu-thread.c
@@ -176,14 +176,14 @@ void qemu_thread_signal(QemuThread *thread, int sig)
error_exit(err, __func__);
}
-void qemu_thread_self(QemuThread *thread)
+void qemu_thread_get_self(QemuThread *thread)
{
thread->thread = pthread_self();
}
-int qemu_thread_equal(QemuThread *thread1, QemuThread *thread2)
+int qemu_thread_is_self(QemuThread *thread)
{
- return pthread_equal(thread1->thread, thread2->thread);
+ return pthread_equal(pthread_self(), thread->thread);
}
void qemu_thread_exit(void *retval)
diff --git a/qemu-thread.h b/qemu-thread.h
index 19bb30c..add97bf 100644
--- a/qemu-thread.h
+++ b/qemu-thread.h
@@ -37,8 +37,8 @@ void qemu_thread_create(QemuThread *thread,
void *(*start_routine)(void*),
void *arg);
void qemu_thread_signal(QemuThread *thread, int sig);
-void qemu_thread_self(QemuThread *thread);
-int qemu_thread_equal(QemuThread *thread1, QemuThread *thread2);
+void qemu_thread_get_self(QemuThread *thread);
+int qemu_thread_is_self(QemuThread *thread);
void qemu_thread_exit(void *retval);
#endif
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 0aa0a41..1f12cbf 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1355,7 +1355,7 @@ int kvm_arch_put_registers(CPUState *env, int level)
{
int ret;
- assert(cpu_is_stopped(env) || qemu_cpu_self(env));
+ assert(cpu_is_stopped(env) || qemu_cpu_is_self(env));
ret = kvm_getput_regs(env, 1);
if (ret < 0) {
@@ -1403,7 +1403,7 @@ int kvm_arch_get_registers(CPUState *env)
{
int ret;
- assert(cpu_is_stopped(env) || qemu_cpu_self(env));
+ assert(cpu_is_stopped(env) || qemu_cpu_is_self(env));
ret = kvm_getput_regs(env, 0);
if (ret < 0) {
diff --git a/ui/vnc-jobs-async.c b/ui/vnc-jobs-async.c
index f596247..1dfa6c3 100644
--- a/ui/vnc-jobs-async.c
+++ b/ui/vnc-jobs-async.c
@@ -303,7 +303,7 @@ static void *vnc_worker_thread(void *arg)
{
VncJobQueue *queue = arg;
- qemu_thread_self(&queue->thread);
+ qemu_thread_get_self(&queue->thread);
while (!vnc_worker_thread_loop(queue)) ;
vnc_queue_clear(queue);
--
1.7.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PATCH v2 upstream 05/22] add win32 qemu-thread implementation
2011-02-26 15:39 [Qemu-devel] [PATCH v2 uq/master 00/22] Win32 iothread support Paolo Bonzini
` (3 preceding siblings ...)
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 04/22] Refactor thread retrieval and check Paolo Bonzini
@ 2011-02-26 15:40 ` Paolo Bonzini
2011-02-26 16:47 ` Blue Swirl
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 06/22] include qemu-thread.h early Paolo Bonzini
` (18 subsequent siblings)
23 siblings, 1 reply; 31+ messages in thread
From: Paolo Bonzini @ 2011-02-26 15:40 UTC (permalink / raw)
To: qemu-devel; +Cc: jan.kiszka, aurelien
For now, qemu_cond_timedwait and qemu_mutex_timedlock are left as
POSIX-only functions. They can be removed later, once the patches
that remove their uses are in.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
Makefile.objs | 4 +-
qemu-thread.c => qemu-thread-posix.c | 0
qemu-thread-posix.h | 18 +++
qemu-thread-win32.c | 260 ++++++++++++++++++++++++++++++++++
qemu-thread-win32.h | 21 +++
qemu-thread.h | 27 ++--
6 files changed, 313 insertions(+), 17 deletions(-)
rename qemu-thread.c => qemu-thread-posix.c (100%)
create mode 100644 qemu-thread-posix.h
create mode 100644 qemu-thread-win32.c
create mode 100644 qemu-thread-win32.h
diff --git a/Makefile.objs b/Makefile.objs
index 9e98a66..a52f42f 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -142,8 +142,8 @@ endif
common-obj-y += $(addprefix ui/, $(ui-obj-y))
common-obj-y += iov.o acl.o
-common-obj-$(CONFIG_THREAD) += qemu-thread.o
-common-obj-$(CONFIG_POSIX) += compatfd.o
+common-obj-$(CONFIG_POSIX) += qemu-thread-posix.o compatfd.o
+common-obj-$(CONFIG_WIN32) += qemu-thread-win32.o
common-obj-y += notify.o event_notifier.o
common-obj-y += qemu-timer.o qemu-timer-common.o
diff --git a/qemu-thread.c b/qemu-thread-posix.c
similarity index 100%
rename from qemu-thread.c
rename to qemu-thread-posix.c
diff --git a/qemu-thread-posix.h b/qemu-thread-posix.h
new file mode 100644
index 0000000..7af371c
--- /dev/null
+++ b/qemu-thread-posix.h
@@ -0,0 +1,18 @@
+#ifndef __QEMU_THREAD_POSIX_H
+#define __QEMU_THREAD_POSIX_H 1
+#include "pthread.h"
+
+struct QemuMutex {
+ pthread_mutex_t lock;
+};
+
+struct QemuCond {
+ pthread_cond_t cond;
+};
+
+struct QemuThread {
+ pthread_t thread;
+};
+
+void qemu_thread_signal(QemuThread *thread, int sig);
+#endif
diff --git a/qemu-thread-win32.c b/qemu-thread-win32.c
new file mode 100644
index 0000000..89422ce
--- /dev/null
+++ b/qemu-thread-win32.c
@@ -0,0 +1,260 @@
+/*
+ * Win32 implementation for mutex/cond/thread functions
+ *
+ * Copyright Red Hat, Inc. 2010
+ *
+ * Author:
+ * Paolo Bonzini <pbonzini@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+#include "qemu-common.h"
+#include "qemu-thread.h"
+#include <process.h>
+#include <assert.h>
+#include <limits.h>
+
+static void error_exit(int err, const char *msg)
+{
+ char *pstr;
+
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+ NULL, err, 0, (LPTSTR)&pstr, 2, NULL);
+ fprintf(stderr, "qemu: %s: %s\n", msg, pstr);
+ LocalFree(pstr);
+ exit(1);
+}
+
+void qemu_mutex_init(QemuMutex *mutex)
+{
+ mutex->owner = 0;
+ InitializeCriticalSection(&mutex->lock);
+}
+
+void qemu_mutex_lock(QemuMutex *mutex)
+{
+ EnterCriticalSection(&mutex->lock);
+
+ /* Win32 CRITICAL_SECTIONs are recursive. Assert that we're not
+ * using them as such.
+ */
+ assert(mutex->owner == 0);
+ mutex->owner = GetCurrentThreadId();
+}
+
+int qemu_mutex_trylock(QemuMutex *mutex)
+{
+ int owned;
+
+ owned = TryEnterCriticalSection(&mutex->lock);
+ if (owned) {
+ assert(mutex->owner == 0);
+ mutex->owner = GetCurrentThreadId();
+ }
+ return !owned;
+}
+
+void qemu_mutex_unlock(QemuMutex *mutex)
+{
+ assert(mutex->owner == GetCurrentThreadId());
+ mutex->owner = 0;
+ LeaveCriticalSection(&mutex->lock);
+}
+
+void qemu_cond_init(QemuCond *cond)
+{
+ memset(cond, 0, sizeof(*cond));
+
+ cond->sema = CreateSemaphore(NULL, 0, LONG_MAX, NULL);
+ if (!cond->sema) {
+ error_exit(GetLastError(), __func__);
+ }
+ cond->continue_event = CreateEvent(NULL, /* security */
+ FALSE, /* auto-reset */
+ FALSE, /* not signaled */
+ NULL); /* name */
+ if (!cond->continue_event) {
+ error_exit(GetLastError(), __func__);
+ }
+}
+
+void qemu_cond_signal(QemuCond *cond)
+{
+ DWORD result;
+
+ /*
+ * Signal only when there are waiters. cond->waiters is
+ * incremented by pthread_cond_wait under the external lock,
+ * so we are safe about that.
+ */
+ if (cond->waiters == 0) {
+ return;
+ }
+
+ /*
+ * Waiting threads decrement it outside the external lock, but
+ * only if another thread is executing pthread_cond_broadcast and
+ * has the mutex. So, it also cannot be decremented concurrently
+ * with this particular access.
+ */
+ cond->target = cond->waiters - 1;
+ result = SignalObjectAndWait(cond->sema, cond->continue_event,
+ INFINITE, FALSE);
+ if (result == WAIT_ABANDONED || result == WAIT_FAILED) {
+ error_exit(GetLastError(), __func__);
+ }
+}
+
+void qemu_cond_broadcast(QemuCond *cond)
+{
+ BOOLEAN result;
+ /*
+ * As in pthread_cond_signal, access to cond->waiters and
+ * cond->target is locked via the external mutex.
+ */
+ if (cond->waiters == 0) {
+ return;
+ }
+
+ cond->target = 0;
+ result = ReleaseSemaphore(cond->sema, cond->waiters, NULL);
+ if (!result) {
+ error_exit(GetLastError(), __func__);
+ }
+
+ /*
+ * At this point all waiters continue. Each one takes its
+ * slice of the semaphore. Now it's our turn to wait: Since
+ * the external mutex is held, no thread can leave cond_wait,
+ * yet. For this reason, we can be sure that no thread gets
+ * a chance to eat *more* than one slice. OTOH, it means
+ * that the last waiter must send us a wake-up.
+ */
+ WaitForSingleObject(cond->continue_event, INFINITE);
+}
+
+void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex)
+{
+ /*
+ * This access is protected under the mutex.
+ */
+ cond->waiters++;
+
+ /*
+ * Unlock external mutex and wait for signal.
+ * NOTE: we've held mutex locked long enough to increment
+ * waiters count above, so there's no problem with
+ * leaving mutex unlocked before we wait on semaphore.
+ */
+ qemu_mutex_unlock(mutex);
+ WaitForSingleObject(cond->sema, INFINITE);
+
+ /* Now waiters must rendez-vous with the signaling thread and
+ * let it continue. For cond_broadcast this has heavy contention
+ * and triggers thundering herd. So goes life.
+ *
+ * Decrease waiters count. The mutex is not taken, so we have
+ * to do this atomically.
+ *
+ * All waiters contend for the mutex at the end of this function
+ * until the signaling thread relinquishes it. To ensure
+ * each waiter consumes exactly one slice of the semaphore,
+ * the signaling thread stops until it is told by the last
+ * waiter that it can go on.
+ */
+ if (InterlockedDecrement(&cond->waiters) == cond->target) {
+ SetEvent(cond->continue_event);
+ }
+
+ qemu_mutex_lock(mutex);
+}
+
+struct qemu_thread_data {
+ QemuThread *thread;
+ void *(*start_routine)(void *);
+ void *arg;
+};
+
+static int qemu_thread_tls_index = TLS_OUT_OF_INDEXES;
+
+static unsigned __stdcall win32_start_routine(void *arg)
+{
+ struct qemu_thread_data data = *(struct qemu_thread_data *) arg;
+ QemuThread *thread = data.thread;
+
+ free(arg);
+ TlsSetValue(qemu_thread_tls_index, thread);
+
+ /*
+ * Use DuplicateHandle instead of assigning thread->thread in the
+ * creating thread to avoid races. It's simpler this way than with
+ * synchronization.
+ */
+ DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
+ GetCurrentProcess(), &thread->thread,
+ 0, FALSE, DUPLICATE_SAME_ACCESS);
+
+ qemu_thread_exit(data.start_routine(data.arg));
+ abort();
+}
+
+void qemu_thread_exit(void *arg)
+{
+ QemuThread *thread = TlsGetValue(qemu_thread_tls_index);
+ thread->ret = arg;
+ CloseHandle(thread->thread);
+ thread->thread = NULL;
+ ExitThread(0);
+}
+
+static inline void qemu_thread_init(void)
+{
+ if (qemu_thread_tls_index == TLS_OUT_OF_INDEXES) {
+ qemu_thread_tls_index = TlsAlloc();
+ if (qemu_thread_tls_index == TLS_OUT_OF_INDEXES) {
+ error_exit(ERROR_NO_SYSTEM_RESOURCES, __func__);
+ }
+ }
+}
+
+
+void qemu_thread_create(QemuThread *thread,
+ void *(*start_routine)(void *),
+ void *arg)
+{
+ HANDLE hThread;
+
+ struct qemu_thread_data *data;
+ qemu_thread_init();
+ data = qemu_malloc(sizeof *data);
+ data->thread = thread;
+ data->start_routine = start_routine;
+ data->arg = arg;
+
+ hThread = (HANDLE) _beginthreadex(NULL, 0, win32_start_routine,
+ data, 0, NULL);
+ if (!hThread) {
+ error_exit(GetLastError(), __func__);
+ }
+ CloseHandle(hThread);
+}
+
+void qemu_thread_get_self(QemuThread *thread)
+{
+ if (!thread->thread) {
+ /* In the main thread of the process. Initialize the QemuThread
+ pointer in TLS, and use the dummy GetCurrentThread handle as
+ the identifier for qemu_thread_is_self. */
+ qemu_thread_init();
+ TlsSetValue(qemu_thread_tls_index, thread);
+ thread->thread = GetCurrentThread();
+ }
+}
+
+int qemu_thread_is_self(QemuThread *thread)
+{
+ QemuThread *this_thread = TlsGetValue(qemu_thread_tls_index);
+ return this_thread->thread == thread->thread;
+}
diff --git a/qemu-thread-win32.h b/qemu-thread-win32.h
new file mode 100644
index 0000000..878f86a
--- /dev/null
+++ b/qemu-thread-win32.h
@@ -0,0 +1,21 @@
+#ifndef __QEMU_THREAD_WIN32_H
+#define __QEMU_THREAD_WIN32_H 1
+#include "windows.h"
+
+struct QemuMutex {
+ CRITICAL_SECTION lock;
+ LONG owner;
+};
+
+struct QemuCond {
+ LONG waiters, target;
+ HANDLE sema;
+ HANDLE continue_event;
+};
+
+struct QemuThread {
+ HANDLE thread;
+ void *ret;
+};
+
+#endif
diff --git a/qemu-thread.h b/qemu-thread.h
index add97bf..acdb6b2 100644
--- a/qemu-thread.h
+++ b/qemu-thread.h
@@ -1,24 +1,16 @@
#ifndef __QEMU_THREAD_H
#define __QEMU_THREAD_H 1
-#include "semaphore.h"
-#include "pthread.h"
-
-struct QemuMutex {
- pthread_mutex_t lock;
-};
-
-struct QemuCond {
- pthread_cond_t cond;
-};
-
-struct QemuThread {
- pthread_t thread;
-};
typedef struct QemuMutex QemuMutex;
typedef struct QemuCond QemuCond;
typedef struct QemuThread QemuThread;
+#ifdef _WIN32
+#include "qemu-thread-win32.h"
+#else
+#include "qemu-thread-posix.h"
+#endif
+
void qemu_mutex_init(QemuMutex *mutex);
void qemu_mutex_destroy(QemuMutex *mutex);
void qemu_mutex_lock(QemuMutex *mutex);
@@ -28,6 +20,12 @@ void qemu_mutex_unlock(QemuMutex *mutex);
void qemu_cond_init(QemuCond *cond);
void qemu_cond_destroy(QemuCond *cond);
+
+/*
+ * IMPORTANT: The implementation does not guarantee that pthread_cond_signal
+ * and pthread_cond_broadcast can be called except while the same mutex is
+ * held as in the corresponding pthread_cond_wait calls!
+ */
void qemu_cond_signal(QemuCond *cond);
void qemu_cond_broadcast(QemuCond *cond);
void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex);
@@ -36,7 +34,6 @@ int qemu_cond_timedwait(QemuCond *cond, QemuMutex *mutex, uint64_t msecs);
void qemu_thread_create(QemuThread *thread,
void *(*start_routine)(void*),
void *arg);
-void qemu_thread_signal(QemuThread *thread, int sig);
void qemu_thread_get_self(QemuThread *thread);
int qemu_thread_is_self(QemuThread *thread);
void qemu_thread_exit(void *retval);
--
1.7.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PATCH v2 upstream 06/22] include qemu-thread.h early
2011-02-26 15:39 [Qemu-devel] [PATCH v2 uq/master 00/22] Win32 iothread support Paolo Bonzini
` (4 preceding siblings ...)
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 05/22] add win32 qemu-thread implementation Paolo Bonzini
@ 2011-02-26 15:40 ` Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 07/22] add assertions on the owner of a QemuMutex Paolo Bonzini
` (17 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2011-02-26 15:40 UTC (permalink / raw)
To: qemu-devel; +Cc: jan.kiszka, aurelien
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
cpus.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/cpus.c b/cpus.c
index 09ce6fe..c5743c4 100644
--- a/cpus.c
+++ b/cpus.c
@@ -32,6 +32,7 @@
#include "kvm.h"
#include "exec-all.h"
+#include "qemu-thread.h"
#include "cpus.h"
#include "compatfd.h"
@@ -592,8 +593,6 @@ void vm_stop(int reason)
#else /* CONFIG_IOTHREAD */
-#include "qemu-thread.h"
-
QemuMutex qemu_global_mutex;
static QemuMutex qemu_fair_mutex;
--
1.7.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PATCH v2 upstream 07/22] add assertions on the owner of a QemuMutex
2011-02-26 15:39 [Qemu-devel] [PATCH v2 uq/master 00/22] Win32 iothread support Paolo Bonzini
` (5 preceding siblings ...)
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 06/22] include qemu-thread.h early Paolo Bonzini
@ 2011-02-26 15:40 ` Paolo Bonzini
2011-02-27 9:33 ` [Qemu-devel] " Jan Kiszka
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 08/22] remove CONFIG_THREAD Paolo Bonzini
` (16 subsequent siblings)
23 siblings, 1 reply; 31+ messages in thread
From: Paolo Bonzini @ 2011-02-26 15:40 UTC (permalink / raw)
To: qemu-devel; +Cc: jan.kiszka, aurelien
These are already present in the Win32 implementation, add them to
the pthread wrappers as well. Use PTHREAD_MUTEX_ERRORCHECK for mutex
operations, and track the owner separately for cond_signal/broadcast.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
qemu-thread-posix.c | 23 +++++++++++++++++++++--
qemu-thread-posix.h | 1 +
2 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/qemu-thread-posix.c b/qemu-thread-posix.c
index e307773..a4c6e25 100644
--- a/qemu-thread-posix.c
+++ b/qemu-thread-posix.c
@@ -16,9 +16,12 @@
#include <time.h>
#include <signal.h>
#include <stdint.h>
+#include <assert.h>
#include <string.h>
#include "qemu-thread.h"
+static pthread_t pthread_null;
+
static void error_exit(int err, const char *msg)
{
fprintf(stderr, "qemu: %s: %s\n", msg, strerror(err));
@@ -28,8 +31,13 @@ static void error_exit(int err, const char *msg)
void qemu_mutex_init(QemuMutex *mutex)
{
int err;
+ pthread_mutexattr_t mutexattr;
- err = pthread_mutex_init(&mutex->lock, NULL);
+ mutex->owner = pthread_null;
+ pthread_mutexattr_init(&mutexattr);
+ pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_ERRORCHECK);
+ err = pthread_mutex_init(&mutex->lock, &mutexattr);
+ pthread_mutexattr_destroy(&mutexattr);
if (err)
error_exit(err, __func__);
}
@@ -48,13 +56,20 @@ void qemu_mutex_lock(QemuMutex *mutex)
int err;
err = pthread_mutex_lock(&mutex->lock);
+ mutex->owner = pthread_self();
if (err)
error_exit(err, __func__);
}
int qemu_mutex_trylock(QemuMutex *mutex)
{
- return pthread_mutex_trylock(&mutex->lock);
+ int err;
+ err = pthread_mutex_trylock(&mutex->lock);
+ if (err == 0) {
+ mutex->owner = pthread_self();
+ }
+
+ return !!err;
}
static void timespec_add_ms(struct timespec *ts, uint64_t msecs)
@@ -85,6 +100,7 @@ void qemu_mutex_unlock(QemuMutex *mutex)
{
int err;
+ mutex->owner = pthread_null;
err = pthread_mutex_unlock(&mutex->lock);
if (err)
error_exit(err, __func__);
@@ -130,7 +146,10 @@ void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex)
{
int err;
+ assert(pthread_equal(mutex->owner, pthread_self()));
+ mutex->owner = pthread_null;
err = pthread_cond_wait(&cond->cond, &mutex->lock);
+ mutex->owner = pthread_self();
if (err)
error_exit(err, __func__);
}
diff --git a/qemu-thread-posix.h b/qemu-thread-posix.h
index 7af371c..11978db 100644
--- a/qemu-thread-posix.h
+++ b/qemu-thread-posix.h
@@ -4,6 +4,7 @@
struct QemuMutex {
pthread_mutex_t lock;
+ pthread_t owner;
};
struct QemuCond {
--
1.7.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PATCH v2 upstream 08/22] remove CONFIG_THREAD
2011-02-26 15:39 [Qemu-devel] [PATCH v2 uq/master 00/22] Win32 iothread support Paolo Bonzini
` (6 preceding siblings ...)
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 07/22] add assertions on the owner of a QemuMutex Paolo Bonzini
@ 2011-02-26 15:40 ` Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 09/22] target-sh4: move intr_at_halt out of cpu_halted() Paolo Bonzini
` (15 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2011-02-26 15:40 UTC (permalink / raw)
To: qemu-devel; +Cc: jan.kiszka, aurelien
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
configure | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/configure b/configure
index 3036faf..4de26d2 100755
--- a/configure
+++ b/configure
@@ -2662,7 +2662,6 @@ if test "$vnc_png" != "no" ; then
fi
if test "$vnc_thread" != "no" ; then
echo "CONFIG_VNC_THREAD=y" >> $config_host_mak
- echo "CONFIG_THREAD=y" >> $config_host_mak
fi
if test "$fnmatch" = "yes" ; then
echo "CONFIG_FNMATCH=y" >> $config_host_mak
@@ -2758,7 +2757,6 @@ if test "$xen" = "yes" ; then
fi
if test "$io_thread" = "yes" ; then
echo "CONFIG_IOTHREAD=y" >> $config_host_mak
- echo "CONFIG_THREAD=y" >> $config_host_mak
fi
if test "$linux_aio" = "yes" ; then
echo "CONFIG_LINUX_AIO=y" >> $config_host_mak
--
1.7.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PATCH v2 upstream 09/22] target-sh4: move intr_at_halt out of cpu_halted()
2011-02-26 15:39 [Qemu-devel] [PATCH v2 uq/master 00/22] Win32 iothread support Paolo Bonzini
` (7 preceding siblings ...)
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 08/22] remove CONFIG_THREAD Paolo Bonzini
@ 2011-02-26 15:40 ` Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 10/22] inline cpu_halted into sole caller Paolo Bonzini
` (14 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2011-02-26 15:40 UTC (permalink / raw)
To: qemu-devel; +Cc: jan.kiszka, aurelien
From: Aurelien Jarno <aurelien@aurel32.net>
All targets except SH4 have the same cpu_halted() routine, and it has
only one caller. It is therefore a good candidate for inlining.
The difference is the handling of the intr_at_halt, which is necessary
to ignore SR.BL when sleeping. Move intr_at_halt handling out of it, by
setting this variable while executing the sleep instruction, and
clearing it when the CPU has been woken-up by an interrupt, whatever the
state of SR.BL. Also rename this variable in_sleep.
Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
target-sh4/cpu.h | 2 +-
target-sh4/exec.h | 1 -
target-sh4/helper.c | 4 ++--
target-sh4/op_helper.c | 1 +
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
index 789d188..74ff97a 100644
--- a/target-sh4/cpu.h
+++ b/target-sh4/cpu.h
@@ -184,7 +184,7 @@ typedef struct CPUSH4State {
uint32_t cvr; /* Cache Version Register */
void *intc_handle;
- int intr_at_halt; /* SR_BL ignored during sleep */
+ int in_sleep; /* SR_BL ignored during sleep */
memory_content *movcal_backup;
memory_content **movcal_backup_tail;
} CPUSH4State;
diff --git a/target-sh4/exec.h b/target-sh4/exec.h
index 2999c02..61bc121 100644
--- a/target-sh4/exec.h
+++ b/target-sh4/exec.h
@@ -37,7 +37,6 @@ static inline int cpu_halted(CPUState *env) {
return 0;
if (cpu_has_work(env)) {
env->halted = 0;
- env->intr_at_halt = 1;
return 0;
}
return EXCP_HALTED;
diff --git a/target-sh4/helper.c b/target-sh4/helper.c
index d2038bd..8f36d31 100644
--- a/target-sh4/helper.c
+++ b/target-sh4/helper.c
@@ -90,11 +90,11 @@ void do_interrupt(CPUState * env)
if (do_exp && env->exception_index != 0x1e0) {
env->exception_index = 0x000; /* masked exception -> reset */
}
- if (do_irq && !env->intr_at_halt) {
+ if (do_irq && !env->in_sleep) {
return; /* masked */
}
- env->intr_at_halt = 0;
}
+ env->in_sleep = 0;
if (do_irq) {
irq_vector = sh_intc_get_pending_vector(env->intc_handle,
diff --git a/target-sh4/op_helper.c b/target-sh4/op_helper.c
index 30f9842..b8f4ca2 100644
--- a/target-sh4/op_helper.c
+++ b/target-sh4/op_helper.c
@@ -119,6 +119,7 @@ void helper_debug(void)
void helper_sleep(uint32_t next_pc)
{
env->halted = 1;
+ env->in_sleep = 1;
env->exception_index = EXCP_HLT;
env->pc = next_pc;
cpu_loop_exit();
--
1.7.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PATCH v2 upstream 10/22] inline cpu_halted into sole caller
2011-02-26 15:39 [Qemu-devel] [PATCH v2 uq/master 00/22] Win32 iothread support Paolo Bonzini
` (8 preceding siblings ...)
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 09/22] target-sh4: move intr_at_halt out of cpu_halted() Paolo Bonzini
@ 2011-02-26 15:40 ` Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 11/22] always qemu_cpu_kick after unhalting a cpu Paolo Bonzini
` (13 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2011-02-26 15:40 UTC (permalink / raw)
To: qemu-devel; +Cc: jan.kiszka, aurelien
All implementations are now the same, and there is only one caller,
so inline the function there.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
cpu-exec.c | 9 +++++++--
target-alpha/exec.h | 11 -----------
target-arm/exec.h | 13 -------------
target-cris/exec.h | 11 -----------
target-i386/exec.h | 12 ------------
target-m68k/exec.h | 10 ----------
target-microblaze/exec.h | 11 -----------
target-mips/exec.h | 11 -----------
target-ppc/exec.h | 11 -----------
target-s390x/exec.h | 12 ------------
target-sh4/exec.h | 10 ----------
target-sparc/exec.h | 10 ----------
12 files changed, 7 insertions(+), 124 deletions(-)
diff --git a/cpu-exec.c b/cpu-exec.c
index b03b3a7..eed9282 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -208,8 +208,13 @@ int cpu_exec(CPUState *env1)
uint8_t *tc_ptr;
unsigned long next_tb;
- if (cpu_halted(env1) == EXCP_HALTED)
- return EXCP_HALTED;
+ if (env1->halted) {
+ if (!cpu_has_work(env1)) {
+ return EXCP_HALTED;
+ }
+
+ env1->halted = 0;
+ }
cpu_single_env = env1;
diff --git a/target-alpha/exec.h b/target-alpha/exec.h
index a8a38d2..6ae96d1 100644
--- a/target-alpha/exec.h
+++ b/target-alpha/exec.h
@@ -42,17 +42,6 @@ static inline int cpu_has_work(CPUState *env)
return (env->interrupt_request & CPU_INTERRUPT_HARD);
}
-static inline int cpu_halted(CPUState *env)
-{
- if (!env->halted)
- return 0;
- if (cpu_has_work(env)) {
- env->halted = 0;
- return 0;
- }
- return EXCP_HALTED;
-}
-
static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
{
env->pc = tb->pc;
diff --git a/target-arm/exec.h b/target-arm/exec.h
index e4c35a3..44e1b55 100644
--- a/target-arm/exec.h
+++ b/target-arm/exec.h
@@ -32,19 +32,6 @@ static inline int cpu_has_work(CPUState *env)
(CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB));
}
-static inline int cpu_halted(CPUState *env) {
- if (!env->halted)
- return 0;
- /* An interrupt wakes the CPU even if the I and F CPSR bits are
- set. We use EXITTB to silently wake CPU without causing an
- actual interrupt. */
- if (cpu_has_work(env)) {
- env->halted = 0;
- return 0;
- }
- return EXCP_HALTED;
-}
-
#if !defined(CONFIG_USER_ONLY)
#include "softmmu_exec.h"
#endif
diff --git a/target-cris/exec.h b/target-cris/exec.h
index 34c0132..2d5d297 100644
--- a/target-cris/exec.h
+++ b/target-cris/exec.h
@@ -33,17 +33,6 @@ static inline int cpu_has_work(CPUState *env)
return (env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI));
}
-static inline int cpu_halted(CPUState *env) {
- if (!env->halted)
- return 0;
-
- if (cpu_has_work(env)) {
- env->halted = 0;
- return 0;
- }
- return EXCP_HALTED;
-}
-
static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
{
env->pc = tb->pc;
diff --git a/target-i386/exec.h b/target-i386/exec.h
index fc8945b..3e7386e 100644
--- a/target-i386/exec.h
+++ b/target-i386/exec.h
@@ -304,18 +304,6 @@ static inline int cpu_has_work(CPUState *env)
return work;
}
-static inline int cpu_halted(CPUState *env) {
- /* handle exit of HALTED state */
- if (!env->halted)
- return 0;
- /* disable halt condition */
- if (cpu_has_work(env)) {
- env->halted = 0;
- return 0;
- }
- return EXCP_HALTED;
-}
-
/* load efer and update the corresponding hflags. XXX: do consistency
checks with cpuid bits ? */
static inline void cpu_load_efer(CPUState *env, uint64_t val)
diff --git a/target-m68k/exec.h b/target-m68k/exec.h
index f31e06e..91daa6b 100644
--- a/target-m68k/exec.h
+++ b/target-m68k/exec.h
@@ -33,16 +33,6 @@ static inline int cpu_has_work(CPUState *env)
return (env->interrupt_request & (CPU_INTERRUPT_HARD));
}
-static inline int cpu_halted(CPUState *env) {
- if (!env->halted)
- return 0;
- if (cpu_has_work(env)) {
- env->halted = 0;
- return 0;
- }
- return EXCP_HALTED;
-}
-
static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
{
env->pc = tb->pc;
diff --git a/target-microblaze/exec.h b/target-microblaze/exec.h
index ab19828..1efff30 100644
--- a/target-microblaze/exec.h
+++ b/target-microblaze/exec.h
@@ -32,17 +32,6 @@ static inline int cpu_has_work(CPUState *env)
return (env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI));
}
-static inline int cpu_halted(CPUState *env) {
- if (!env->halted)
- return 0;
-
- if (cpu_has_work(env)) {
- env->halted = 0;
- return 0;
- }
- return EXCP_HALTED;
-}
-
static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
{
env->sregs[SR_PC] = tb->pc;
diff --git a/target-mips/exec.h b/target-mips/exec.h
index 1273654..b3c5a13 100644
--- a/target-mips/exec.h
+++ b/target-mips/exec.h
@@ -36,17 +36,6 @@ static inline int cpu_has_work(CPUState *env)
return has_work;
}
-static inline int cpu_halted(CPUState *env)
-{
- if (!env->halted)
- return 0;
- if (cpu_has_work(env)) {
- env->halted = 0;
- return 0;
- }
- return EXCP_HALTED;
-}
-
static inline void compute_hflags(CPUState *env)
{
env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 |
diff --git a/target-ppc/exec.h b/target-ppc/exec.h
index 4688ef5..f87847a 100644
--- a/target-ppc/exec.h
+++ b/target-ppc/exec.h
@@ -38,17 +38,6 @@ static inline int cpu_has_work(CPUState *env)
}
-static inline int cpu_halted(CPUState *env)
-{
- if (!env->halted)
- return 0;
- if (cpu_has_work(env)) {
- env->halted = 0;
- return 0;
- }
- return EXCP_HALTED;
-}
-
static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
{
env->nip = tb->pc;
diff --git a/target-s390x/exec.h b/target-s390x/exec.h
index bf3f264..f7893f3 100644
--- a/target-s390x/exec.h
+++ b/target-s390x/exec.h
@@ -34,18 +34,6 @@ static inline int cpu_has_work(CPUState *env)
return env->interrupt_request & CPU_INTERRUPT_HARD; // guess
}
-static inline int cpu_halted(CPUState *env)
-{
- if (!env->halted) {
- return 0;
- }
- if (cpu_has_work(env)) {
- env->halted = 0;
- return 0;
- }
- return EXCP_HALTED;
-}
-
static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock* tb)
{
env->psw.addr = tb->pc;
diff --git a/target-sh4/exec.h b/target-sh4/exec.h
index 61bc121..9f1c1f6 100644
--- a/target-sh4/exec.h
+++ b/target-sh4/exec.h
@@ -32,16 +32,6 @@ static inline int cpu_has_work(CPUState *env)
return (env->interrupt_request & CPU_INTERRUPT_HARD);
}
-static inline int cpu_halted(CPUState *env) {
- if (!env->halted)
- return 0;
- if (cpu_has_work(env)) {
- env->halted = 0;
- return 0;
- }
- return EXCP_HALTED;
-}
-
#ifndef CONFIG_USER_ONLY
#include "softmmu_exec.h"
#endif
diff --git a/target-sparc/exec.h b/target-sparc/exec.h
index f811571..f5c221e 100644
--- a/target-sparc/exec.h
+++ b/target-sparc/exec.h
@@ -22,16 +22,6 @@ static inline int cpu_has_work(CPUState *env1)
}
-static inline int cpu_halted(CPUState *env1) {
- if (!env1->halted)
- return 0;
- if (cpu_has_work(env1)) {
- env1->halted = 0;
- return 0;
- }
- return EXCP_HALTED;
-}
-
static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
{
env->pc = tb->pc;
--
1.7.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PATCH v2 upstream 11/22] always qemu_cpu_kick after unhalting a cpu
2011-02-26 15:39 [Qemu-devel] [PATCH v2 uq/master 00/22] Win32 iothread support Paolo Bonzini
` (9 preceding siblings ...)
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 10/22] inline cpu_halted into sole caller Paolo Bonzini
@ 2011-02-26 15:40 ` Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 12/22] exit round-robin vcpu loop if cpu->stopped is true Paolo Bonzini
` (12 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2011-02-26 15:40 UTC (permalink / raw)
To: qemu-devel; +Cc: jan.kiszka, aurelien
This ensures env->halt_cond is broadcast, and the loop in
qemu_tcg_wait_io_event and qemu_kvm_wait_io_event is exited
naturally rather than through a timeout.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/ppc.c | 2 ++
hw/sun4m.c | 10 ++++++++--
hw/sun4u.c | 4 ++--
target-s390x/kvm.c | 1 +
4 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/hw/ppc.c b/hw/ppc.c
index 968aec1..de02d33 100644
--- a/hw/ppc.c
+++ b/hw/ppc.c
@@ -208,6 +208,7 @@ static void ppc970_set_irq (void *opaque, int pin, int level)
} else {
LOG_IRQ("%s: restart the CPU\n", __func__);
env->halted = 0;
+ qemu_cpu_kick(env);
}
break;
case PPC970_INPUT_HRESET:
@@ -300,6 +301,7 @@ static void ppc40x_set_irq (void *opaque, int pin, int level)
} else {
LOG_IRQ("%s: restart the CPU\n", __func__);
env->halted = 0;
+ qemu_cpu_kick(env);
}
break;
case PPC40x_INPUT_DEBUG:
diff --git a/hw/sun4m.c b/hw/sun4m.c
index 30e8a21..df3aa32 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -253,15 +253,21 @@ void cpu_check_irqs(CPUState *env)
}
}
+static void cpu_kick_irq(CPUState *env)
+{
+ env->halted = 0;
+ cpu_check_irqs(env);
+ qemu_cpu_kick(env);
+}
+
static void cpu_set_irq(void *opaque, int irq, int level)
{
CPUState *env = opaque;
if (level) {
trace_sun4m_cpu_set_irq_raise(irq);
- env->halted = 0;
env->pil_in |= 1 << irq;
- cpu_check_irqs(env);
+ cpu_kick_irq(env);
} else {
trace_sun4m_cpu_set_irq_lower(irq);
env->pil_in &= ~(1 << irq);
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 90b1ce2..d282324 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -298,6 +298,7 @@ static void cpu_kick_irq(CPUState *env)
{
env->halted = 0;
cpu_check_irqs(env);
+ qemu_cpu_kick(env);
}
static void cpu_set_irq(void *opaque, int irq, int level)
@@ -306,9 +307,8 @@ static void cpu_set_irq(void *opaque, int irq, int level)
if (level) {
CPUIRQ_DPRINTF("Raise CPU IRQ %d\n", irq);
- env->halted = 0;
env->pil_in |= 1 << irq;
- cpu_check_irqs(env);
+ cpu_kick_irq(env);
} else {
CPUIRQ_DPRINTF("Lower CPU IRQ %d\n", irq);
env->pil_in &= ~(1 << irq);
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index b349812..6e94274 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -194,6 +194,7 @@ static void kvm_s390_interrupt_internal(CPUState *env, int type, uint32_t parm,
env->halted = 0;
env->exception_index = -1;
+ qemu_cpu_kick(env);
kvmint.type = type;
kvmint.parm = parm;
--
1.7.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PATCH v2 upstream 12/22] exit round-robin vcpu loop if cpu->stopped is true
2011-02-26 15:39 [Qemu-devel] [PATCH v2 uq/master 00/22] Win32 iothread support Paolo Bonzini
` (10 preceding siblings ...)
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 11/22] always qemu_cpu_kick after unhalting a cpu Paolo Bonzini
@ 2011-02-26 15:40 ` Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 13/22] always signal pause_cond after stopping a VCPU Paolo Bonzini
` (11 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2011-02-26 15:40 UTC (permalink / raw)
To: qemu-devel; +Cc: jan.kiszka, aurelien
Sometimes vcpus are stopped directly without going through ->stop = 1.
Exit the VCPU execution loop in this case as well.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
cpus.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/cpus.c b/cpus.c
index c5743c4..785a104 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1098,7 +1098,7 @@ bool cpu_exec_all(void)
cpu_handle_debug_exception(env);
break;
}
- } else if (env->stop) {
+ } else if (env->stop || env->stopped) {
break;
}
}
--
1.7.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PATCH v2 upstream 13/22] always signal pause_cond after stopping a VCPU
2011-02-26 15:39 [Qemu-devel] [PATCH v2 uq/master 00/22] Win32 iothread support Paolo Bonzini
` (11 preceding siblings ...)
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 12/22] exit round-robin vcpu loop if cpu->stopped is true Paolo Bonzini
@ 2011-02-26 15:40 ` Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 14/22] do not use timedwait on qemu_halt_cond Paolo Bonzini
` (10 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2011-02-26 15:40 UTC (permalink / raw)
To: qemu-devel; +Cc: jan.kiszka, aurelien
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
cpus.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/cpus.c b/cpus.c
index 785a104..6cfb45b 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1012,8 +1012,10 @@ void qemu_notify_event(void)
void cpu_stop_current(void)
{
if (cpu_single_env) {
+ cpu_single_env->stop = 0;
cpu_single_env->stopped = 1;
cpu_exit(cpu_single_env);
+ qemu_cond_signal(&qemu_pause_cond);
}
}
--
1.7.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PATCH v2 upstream 14/22] do not use timedwait on qemu_halt_cond
2011-02-26 15:39 [Qemu-devel] [PATCH v2 uq/master 00/22] Win32 iothread support Paolo Bonzini
` (12 preceding siblings ...)
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 13/22] always signal pause_cond after stopping a VCPU Paolo Bonzini
@ 2011-02-26 15:40 ` Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 15/22] do not use timedwait on qemu_system_cond Paolo Bonzini
` (9 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2011-02-26 15:40 UTC (permalink / raw)
To: qemu-devel; +Cc: jan.kiszka, aurelien
The following conditions can cause cpu_has_work(env) to become true:
- env->queued_work_first: run_on_cpu is already kicking the VCPU
- env->stop = 1: pause_all_vcpus is already kicking the VCPU
- env->stopped = 0: resume_all_vcpus is already kicking the VCPU
- vm_running = 1: vm_start is calling resume_all_vcpus
- env->halted = 0: see previous patch
- qemu_cpu_has_work(env): when it becomes true, board code should set
env->halted = 0 too.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
cpus.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/cpus.c b/cpus.c
index 6cfb45b..4c3837f 100644
--- a/cpus.c
+++ b/cpus.c
@@ -771,7 +771,7 @@ static void qemu_tcg_wait_io_event(void)
CPUState *env;
while (all_cpu_threads_idle()) {
- qemu_cond_timedwait(tcg_halt_cond, &qemu_global_mutex, 1000);
+ qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex);
}
qemu_mutex_unlock(&qemu_global_mutex);
@@ -794,7 +794,7 @@ static void qemu_tcg_wait_io_event(void)
static void qemu_kvm_wait_io_event(CPUState *env)
{
while (cpu_thread_is_idle(env)) {
- qemu_cond_timedwait(env->halt_cond, &qemu_global_mutex, 1000);
+ qemu_cond_wait(env->halt_cond, &qemu_global_mutex);
}
qemu_kvm_eat_signals(env);
--
1.7.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PATCH v2 upstream 15/22] do not use timedwait on qemu_system_cond
2011-02-26 15:39 [Qemu-devel] [PATCH v2 uq/master 00/22] Win32 iothread support Paolo Bonzini
` (13 preceding siblings ...)
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 14/22] do not use timedwait on qemu_halt_cond Paolo Bonzini
@ 2011-02-26 15:40 ` Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 16/22] do not use timedwait on qemu_pause_cond Paolo Bonzini
` (8 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2011-02-26 15:40 UTC (permalink / raw)
To: qemu-devel; +Cc: jan.kiszka, aurelien
qemu_main_loop_start is the only place where qemu_system_ready is set
to 1.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
cpus.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/cpus.c b/cpus.c
index 4c3837f..e367b3b 100644
--- a/cpus.c
+++ b/cpus.c
@@ -823,7 +823,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
/* and wait for machine initialization */
while (!qemu_system_ready) {
- qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100);
+ qemu_cond_wait(&qemu_system_cond, &qemu_global_mutex);
}
while (1) {
@@ -855,7 +855,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
/* and wait for machine initialization */
while (!qemu_system_ready) {
- qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100);
+ qemu_cond_wait(&qemu_system_cond, &qemu_global_mutex);
}
while (1) {
--
1.7.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PATCH v2 upstream 16/22] do not use timedwait on qemu_pause_cond
2011-02-26 15:39 [Qemu-devel] [PATCH v2 uq/master 00/22] Win32 iothread support Paolo Bonzini
` (14 preceding siblings ...)
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 15/22] do not use timedwait on qemu_system_cond Paolo Bonzini
@ 2011-02-26 15:40 ` Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 17/22] do not use timedwait on qemu_cpu_cond Paolo Bonzini
` (7 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2011-02-26 15:40 UTC (permalink / raw)
To: qemu-devel; +Cc: jan.kiszka, aurelien
all_vcpus_paused can start returning true after penv->stopped changes
from 0 to 1. When this is done, qemu_pause_cond is always signaled.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
cpus.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/cpus.c b/cpus.c
index e367b3b..8f169ad 100644
--- a/cpus.c
+++ b/cpus.c
@@ -938,7 +938,7 @@ void pause_all_vcpus(void)
}
while (!all_vcpus_paused()) {
- qemu_cond_timedwait(&qemu_pause_cond, &qemu_global_mutex, 100);
+ qemu_cond_wait(&qemu_pause_cond, &qemu_global_mutex);
penv = first_cpu;
while (penv) {
qemu_cpu_kick(penv);
--
1.7.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PATCH v2 upstream 17/22] do not use timedwait on qemu_cpu_cond
2011-02-26 15:39 [Qemu-devel] [PATCH v2 uq/master 00/22] Win32 iothread support Paolo Bonzini
` (15 preceding siblings ...)
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 16/22] do not use timedwait on qemu_pause_cond Paolo Bonzini
@ 2011-02-26 15:40 ` Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 18/22] iothread stops the vcpu thread via IPI Paolo Bonzini
` (6 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2011-02-26 15:40 UTC (permalink / raw)
To: qemu-devel; +Cc: jan.kiszka, aurelien
Whenever env->created becomes true, qemu_cpu_cond is signaled by
{kvm,tcg}_cpu_thread_fn.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
cpus.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/cpus.c b/cpus.c
index 8f169ad..4305184 100644
--- a/cpus.c
+++ b/cpus.c
@@ -970,7 +970,7 @@ static void qemu_tcg_init_vcpu(void *_env)
qemu_cond_init(env->halt_cond);
qemu_thread_create(env->thread, qemu_tcg_cpu_thread_fn, env);
while (env->created == 0) {
- qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
+ qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex);
}
tcg_cpu_thread = env->thread;
tcg_halt_cond = env->halt_cond;
@@ -987,7 +987,7 @@ static void qemu_kvm_start_vcpu(CPUState *env)
qemu_cond_init(env->halt_cond);
qemu_thread_create(env->thread, qemu_kvm_cpu_thread_fn, env);
while (env->created == 0) {
- qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
+ qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex);
}
}
--
1.7.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PATCH v2 upstream 18/22] iothread stops the vcpu thread via IPI
2011-02-26 15:39 [Qemu-devel] [PATCH v2 uq/master 00/22] Win32 iothread support Paolo Bonzini
` (16 preceding siblings ...)
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 17/22] do not use timedwait on qemu_cpu_cond Paolo Bonzini
@ 2011-02-26 15:40 ` Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 19/22] move blocking of signals to qemu_signalfd_init Paolo Bonzini
` (5 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2011-02-26 15:40 UTC (permalink / raw)
To: qemu-devel; +Cc: jan.kiszka, aurelien
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
cpus.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/cpus.c b/cpus.c
index 4305184..32e9352 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1086,9 +1086,11 @@ bool cpu_exec_all(void)
qemu_clock_enable(vm_clock,
(env->singlestep_enabled & SSTEP_NOTIMER) == 0);
+#ifndef CONFIG_IOTHREAD
if (qemu_alarm_pending()) {
break;
}
+#endif
if (cpu_can_run(env)) {
if (kvm_enabled()) {
r = kvm_cpu_exec(env);
--
1.7.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PATCH v2 upstream 19/22] move blocking of signals to qemu_signalfd_init
2011-02-26 15:39 [Qemu-devel] [PATCH v2 uq/master 00/22] Win32 iothread support Paolo Bonzini
` (17 preceding siblings ...)
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 18/22] iothread stops the vcpu thread via IPI Paolo Bonzini
@ 2011-02-26 15:40 ` Paolo Bonzini
2011-02-27 9:41 ` [Qemu-devel] " Jan Kiszka
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 20/22] provide dummy signal init functions for win32 Paolo Bonzini
` (4 subsequent siblings)
23 siblings, 1 reply; 31+ messages in thread
From: Paolo Bonzini @ 2011-02-26 15:40 UTC (permalink / raw)
To: qemu-devel; +Cc: jan.kiszka, aurelien
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
cpus.c | 87 ++++++++++++++++++++++++++-------------------------------------
1 files changed, 36 insertions(+), 51 deletions(-)
diff --git a/cpus.c b/cpus.c
index 32e9352..8c440f1 100644
--- a/cpus.c
+++ b/cpus.c
@@ -346,11 +346,37 @@ static void sigfd_handler(void *opaque)
}
}
-static int qemu_signalfd_init(sigset_t mask)
+static int qemu_signalfd_init(void)
{
int sigfd;
+ sigset_t set;
- sigfd = qemu_signalfd(&mask);
+#ifdef CONFIG_IOTHREAD
+ /* SIGUSR2 used by posix-aio-compat.c */
+ sigemptyset(&set);
+ sigaddset(&set, SIGUSR2);
+ pthread_sigmask(SIG_UNBLOCK, &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);
+ if (kvm_enabled()) {
+ /*
+ * We need to process timer signals synchronously to avoid a race
+ * between exit_request check and KVM vcpu entry.
+ */
+ sigaddset(&set, SIGIO);
+ sigaddset(&set, SIGALRM);
+ }
+#endif
+
+ sigfd = qemu_signalfd(&set);
if (sigfd == -1) {
fprintf(stderr, "failed to create signalfd\n");
return -errno;
@@ -438,6 +464,12 @@ static void qemu_event_increment(void)
static void qemu_kvm_eat_signals(CPUState *env)
{
}
+
+static int qemu_signalfd_init(void)
+{
+ return 0;
+}
+
#endif /* _WIN32 */
#ifndef CONFIG_IOTHREAD
@@ -471,39 +503,14 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
#endif
}
-#ifndef _WIN32
-static sigset_t block_synchronous_signals(void)
-{
- sigset_t set;
-
- sigemptyset(&set);
- sigaddset(&set, SIGBUS);
- if (kvm_enabled()) {
- /*
- * We need to process timer signals synchronously to avoid a race
- * between exit_request check and KVM vcpu entry.
- */
- sigaddset(&set, SIGIO);
- sigaddset(&set, SIGALRM);
- }
-
- return set;
-}
-#endif
-
int qemu_init_main_loop(void)
{
-#ifndef _WIN32
- sigset_t blocked_signals;
int ret;
- blocked_signals = block_synchronous_signals();
-
- ret = qemu_signalfd_init(blocked_signals);
+ ret = qemu_signalfd_init();
if (ret) {
return ret;
}
-#endif
qemu_init_sigbus();
@@ -651,35 +658,13 @@ static void qemu_tcg_init_cpu_signals(void)
pthread_sigmask(SIG_UNBLOCK, &set, NULL);
}
-static sigset_t block_io_signals(void)
-{
- sigset_t set;
-
- /* SIGUSR2 used by posix-aio-compat.c */
- sigemptyset(&set);
- sigaddset(&set, SIGUSR2);
- pthread_sigmask(SIG_UNBLOCK, &set, NULL);
-
- sigemptyset(&set);
- sigaddset(&set, SIGIO);
- sigaddset(&set, SIGALRM);
- sigaddset(&set, SIG_IPI);
- sigaddset(&set, SIGBUS);
- pthread_sigmask(SIG_BLOCK, &set, NULL);
-
- return set;
-}
-
int qemu_init_main_loop(void)
{
int ret;
- sigset_t blocked_signals;
qemu_init_sigbus();
- blocked_signals = block_io_signals();
-
- ret = qemu_signalfd_init(blocked_signals);
+ ret = qemu_signalfd_init();
if (ret) {
return ret;
}
--
1.7.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PATCH v2 upstream 20/22] provide dummy signal init functions for win32
2011-02-26 15:39 [Qemu-devel] [PATCH v2 uq/master 00/22] Win32 iothread support Paolo Bonzini
` (18 preceding siblings ...)
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 19/22] move blocking of signals to qemu_signalfd_init Paolo Bonzini
@ 2011-02-26 15:40 ` Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 21/22] protect qemu_cpu_kick_self for Win32 Paolo Bonzini
` (3 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2011-02-26 15:40 UTC (permalink / raw)
To: qemu-devel; +Cc: jan.kiszka, aurelien
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
cpus.c | 143 ++++++++++++++++++++++++++++++++-------------------------------
1 files changed, 73 insertions(+), 70 deletions(-)
diff --git a/cpus.c b/cpus.c
index 8c440f1..3951111 100644
--- a/cpus.c
+++ b/cpus.c
@@ -196,6 +196,16 @@ static void cpu_handle_debug_exception(CPUState *env)
#endif
}
+#ifdef CONFIG_IOTHREAD
+static void cpu_signal(int sig)
+{
+ if (cpu_single_env) {
+ cpu_exit(cpu_single_env);
+ }
+ exit_request = 1;
+}
+#endif
+
#ifdef CONFIG_LINUX
static void sigbus_reraise(void)
{
@@ -390,6 +400,61 @@ static int qemu_signalfd_init(void)
return 0;
}
+static void qemu_kvm_init_cpu_signals(CPUState *env)
+{
+ int r;
+ sigset_t set;
+ struct sigaction sigact;
+
+ memset(&sigact, 0, sizeof(sigact));
+ sigact.sa_handler = dummy_signal;
+ sigaction(SIG_IPI, &sigact, NULL);
+
+#ifdef CONFIG_IOTHREAD
+ pthread_sigmask(SIG_BLOCK, NULL, &set);
+ sigdelset(&set, SIG_IPI);
+ sigdelset(&set, SIGBUS);
+ r = kvm_set_signal_mask(env, &set);
+ if (r) {
+ fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r));
+ exit(1);
+ }
+#else
+ sigemptyset(&set);
+ sigaddset(&set, SIG_IPI);
+ sigaddset(&set, SIGIO);
+ sigaddset(&set, SIGALRM);
+ pthread_sigmask(SIG_BLOCK, &set, NULL);
+
+ pthread_sigmask(SIG_BLOCK, NULL, &set);
+ sigdelset(&set, SIGIO);
+ sigdelset(&set, SIGALRM);
+#endif
+ sigdelset(&set, SIG_IPI);
+ sigdelset(&set, SIGBUS);
+ r = kvm_set_signal_mask(env, &set);
+ if (r) {
+ fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r));
+ exit(1);
+ }
+}
+
+static void qemu_tcg_init_cpu_signals(void)
+{
+#ifdef CONFIG_IOTHREAD
+ sigset_t set;
+ struct sigaction sigact;
+
+ memset(&sigact, 0, sizeof(sigact));
+ sigact.sa_handler = cpu_signal;
+ sigaction(SIG_IPI, &sigact, NULL);
+
+ sigemptyset(&set);
+ sigaddset(&set, SIG_IPI);
+ pthread_sigmask(SIG_UNBLOCK, &set, NULL);
+#endif
+}
+
static void qemu_kvm_eat_signals(CPUState *env)
{
struct timespec ts = { 0, 0 };
@@ -470,39 +535,17 @@ static int qemu_signalfd_init(void)
return 0;
}
-#endif /* _WIN32 */
-
-#ifndef CONFIG_IOTHREAD
static void qemu_kvm_init_cpu_signals(CPUState *env)
{
-#ifndef _WIN32
- int r;
- sigset_t set;
- struct sigaction sigact;
-
- memset(&sigact, 0, sizeof(sigact));
- sigact.sa_handler = dummy_signal;
- sigaction(SIG_IPI, &sigact, NULL);
-
- sigemptyset(&set);
- sigaddset(&set, SIG_IPI);
- sigaddset(&set, SIGIO);
- sigaddset(&set, SIGALRM);
- pthread_sigmask(SIG_BLOCK, &set, NULL);
+ abort();
+}
- pthread_sigmask(SIG_BLOCK, NULL, &set);
- sigdelset(&set, SIG_IPI);
- sigdelset(&set, SIGBUS);
- sigdelset(&set, SIGIO);
- sigdelset(&set, SIGALRM);
- r = kvm_set_signal_mask(env, &set);
- if (r) {
- fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r));
- exit(1);
- }
-#endif
+static void qemu_tcg_init_cpu_signals(void)
+{
}
+#endif /* _WIN32 */
+#ifndef CONFIG_IOTHREAD
int qemu_init_main_loop(void)
{
int ret;
@@ -536,6 +579,8 @@ void qemu_init_vcpu(void *_env)
exit(1);
}
qemu_kvm_init_cpu_signals(env);
+ } else {
+ qemu_tcg_init_cpu_signals();
}
}
@@ -616,48 +661,6 @@ static QemuCond qemu_system_cond;
static QemuCond qemu_pause_cond;
static QemuCond qemu_work_cond;
-static void cpu_signal(int sig)
-{
- if (cpu_single_env) {
- cpu_exit(cpu_single_env);
- }
- exit_request = 1;
-}
-
-static void qemu_kvm_init_cpu_signals(CPUState *env)
-{
- int r;
- sigset_t set;
- struct sigaction sigact;
-
- memset(&sigact, 0, sizeof(sigact));
- sigact.sa_handler = dummy_signal;
- sigaction(SIG_IPI, &sigact, NULL);
-
- pthread_sigmask(SIG_BLOCK, NULL, &set);
- sigdelset(&set, SIG_IPI);
- sigdelset(&set, SIGBUS);
- r = kvm_set_signal_mask(env, &set);
- if (r) {
- fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r));
- exit(1);
- }
-}
-
-static void qemu_tcg_init_cpu_signals(void)
-{
- sigset_t set;
- struct sigaction sigact;
-
- memset(&sigact, 0, sizeof(sigact));
- sigact.sa_handler = cpu_signal;
- sigaction(SIG_IPI, &sigact, NULL);
-
- sigemptyset(&set);
- sigaddset(&set, SIG_IPI);
- pthread_sigmask(SIG_UNBLOCK, &set, NULL);
-}
-
int qemu_init_main_loop(void)
{
int ret;
--
1.7.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PATCH v2 upstream 21/22] protect qemu_cpu_kick_self for Win32
2011-02-26 15:39 [Qemu-devel] [PATCH v2 uq/master 00/22] Win32 iothread support Paolo Bonzini
` (19 preceding siblings ...)
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 20/22] provide dummy signal init functions for win32 Paolo Bonzini
@ 2011-02-26 15:40 ` Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 22/22] add Win32 IPI service Paolo Bonzini
` (2 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2011-02-26 15:40 UTC (permalink / raw)
To: qemu-devel; +Cc: jan.kiszka, aurelien
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
cpus.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/cpus.c b/cpus.c
index 3951111..34ef862 100644
--- a/cpus.c
+++ b/cpus.c
@@ -867,12 +867,16 @@ void qemu_cpu_kick(void *_env)
void qemu_cpu_kick_self(void)
{
+#ifndef _WIN32
assert(cpu_single_env);
if (!cpu_single_env->thread_kicked) {
qemu_thread_signal(cpu_single_env->thread, SIG_IPI);
cpu_single_env->thread_kicked = true;
}
+#else
+ abort();
+#endif
}
int qemu_cpu_is_self(void *_env)
--
1.7.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PATCH v2 upstream 22/22] add Win32 IPI service
2011-02-26 15:39 [Qemu-devel] [PATCH v2 uq/master 00/22] Win32 iothread support Paolo Bonzini
` (20 preceding siblings ...)
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 21/22] protect qemu_cpu_kick_self for Win32 Paolo Bonzini
@ 2011-02-26 15:40 ` Paolo Bonzini
2011-02-26 16:49 ` [Qemu-devel] [PATCH v2 uq/master 00/22] Win32 iothread support Blue Swirl
2011-02-27 9:47 ` [Qemu-devel] " Jan Kiszka
23 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2011-02-26 15:40 UTC (permalink / raw)
To: qemu-devel; +Cc: jan.kiszka, aurelien
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
cpus.c | 25 ++++++++++++++++++++++---
qemu-thread-posix.c | 9 ---------
qemu-thread-posix.h | 1 -
3 files changed, 22 insertions(+), 13 deletions(-)
diff --git a/cpus.c b/cpus.c
index 34ef862..a2de3c2 100644
--- a/cpus.c
+++ b/cpus.c
@@ -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);
diff --git a/qemu-thread-posix.c b/qemu-thread-posix.c
index a4c6e25..9cceda7 100644
--- a/qemu-thread-posix.c
+++ b/qemu-thread-posix.c
@@ -186,15 +186,6 @@ void qemu_thread_create(QemuThread *thread,
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
}
-void qemu_thread_signal(QemuThread *thread, int sig)
-{
- int err;
-
- err = pthread_kill(thread->thread, sig);
- if (err)
- error_exit(err, __func__);
-}
-
void qemu_thread_get_self(QemuThread *thread)
{
thread->thread = pthread_self();
diff --git a/qemu-thread-posix.h b/qemu-thread-posix.h
index 11978db..35e0a8b 100644
--- a/qemu-thread-posix.h
+++ b/qemu-thread-posix.h
@@ -15,5 +15,4 @@ struct QemuThread {
pthread_t thread;
};
-void qemu_thread_signal(QemuThread *thread, int sig);
#endif
--
1.7.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] [PATCH v2 upstream 05/22] add win32 qemu-thread implementation
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 05/22] add win32 qemu-thread implementation Paolo Bonzini
@ 2011-02-26 16:47 ` Blue Swirl
2011-02-26 17:42 ` [Qemu-devel] " Paolo Bonzini
0 siblings, 1 reply; 31+ messages in thread
From: Blue Swirl @ 2011-02-26 16:47 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: jan.kiszka, qemu-devel, aurelien
On Sat, Feb 26, 2011 at 5:40 PM, Paolo Bonzini <pbonzini@redhat.com> wrote:
> For now, qemu_cond_timedwait and qemu_mutex_timedlock are left as
> POSIX-only functions. They can be removed later, once the patches
> that remove their uses are in.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> Makefile.objs | 4 +-
> qemu-thread.c => qemu-thread-posix.c | 0
> qemu-thread-posix.h | 18 +++
> qemu-thread-win32.c | 260 ++++++++++++++++++++++++++++++++++
> qemu-thread-win32.h | 21 +++
> qemu-thread.h | 27 ++--
> 6 files changed, 313 insertions(+), 17 deletions(-)
> rename qemu-thread.c => qemu-thread-posix.c (100%)
> create mode 100644 qemu-thread-posix.h
> create mode 100644 qemu-thread-win32.c
> create mode 100644 qemu-thread-win32.h
>
> diff --git a/Makefile.objs b/Makefile.objs
> index 9e98a66..a52f42f 100644
> --- a/Makefile.objs
> +++ b/Makefile.objs
> @@ -142,8 +142,8 @@ endif
> common-obj-y += $(addprefix ui/, $(ui-obj-y))
>
> common-obj-y += iov.o acl.o
> -common-obj-$(CONFIG_THREAD) += qemu-thread.o
> -common-obj-$(CONFIG_POSIX) += compatfd.o
> +common-obj-$(CONFIG_POSIX) += qemu-thread-posix.o compatfd.o
> +common-obj-$(CONFIG_WIN32) += qemu-thread-win32.o
> common-obj-y += notify.o event_notifier.o
> common-obj-y += qemu-timer.o qemu-timer-common.o
>
> diff --git a/qemu-thread.c b/qemu-thread-posix.c
> similarity index 100%
> rename from qemu-thread.c
> rename to qemu-thread-posix.c
> diff --git a/qemu-thread-posix.h b/qemu-thread-posix.h
> new file mode 100644
> index 0000000..7af371c
> --- /dev/null
> +++ b/qemu-thread-posix.h
> @@ -0,0 +1,18 @@
> +#ifndef __QEMU_THREAD_POSIX_H
> +#define __QEMU_THREAD_POSIX_H 1
> +#include "pthread.h"
> +
> +struct QemuMutex {
> + pthread_mutex_t lock;
> +};
> +
> +struct QemuCond {
> + pthread_cond_t cond;
> +};
> +
> +struct QemuThread {
> + pthread_t thread;
> +};
> +
> +void qemu_thread_signal(QemuThread *thread, int sig);
> +#endif
> diff --git a/qemu-thread-win32.c b/qemu-thread-win32.c
> new file mode 100644
> index 0000000..89422ce
> --- /dev/null
> +++ b/qemu-thread-win32.c
> @@ -0,0 +1,260 @@
> +/*
> + * Win32 implementation for mutex/cond/thread functions
> + *
> + * Copyright Red Hat, Inc. 2010
> + *
> + * Author:
> + * Paolo Bonzini <pbonzini@redhat.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + *
> + */
> +#include "qemu-common.h"
> +#include "qemu-thread.h"
> +#include <process.h>
> +#include <assert.h>
> +#include <limits.h>
> +
> +static void error_exit(int err, const char *msg)
> +{
> + char *pstr;
> +
> + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
> + NULL, err, 0, (LPTSTR)&pstr, 2, NULL);
> + fprintf(stderr, "qemu: %s: %s\n", msg, pstr);
> + LocalFree(pstr);
> + exit(1);
> +}
> +
> +void qemu_mutex_init(QemuMutex *mutex)
> +{
> + mutex->owner = 0;
> + InitializeCriticalSection(&mutex->lock);
> +}
> +
> +void qemu_mutex_lock(QemuMutex *mutex)
> +{
> + EnterCriticalSection(&mutex->lock);
> +
> + /* Win32 CRITICAL_SECTIONs are recursive. Assert that we're not
> + * using them as such.
> + */
> + assert(mutex->owner == 0);
> + mutex->owner = GetCurrentThreadId();
> +}
> +
> +int qemu_mutex_trylock(QemuMutex *mutex)
> +{
> + int owned;
> +
> + owned = TryEnterCriticalSection(&mutex->lock);
> + if (owned) {
> + assert(mutex->owner == 0);
> + mutex->owner = GetCurrentThreadId();
> + }
> + return !owned;
> +}
> +
> +void qemu_mutex_unlock(QemuMutex *mutex)
> +{
> + assert(mutex->owner == GetCurrentThreadId());
> + mutex->owner = 0;
> + LeaveCriticalSection(&mutex->lock);
> +}
> +
> +void qemu_cond_init(QemuCond *cond)
> +{
> + memset(cond, 0, sizeof(*cond));
> +
> + cond->sema = CreateSemaphore(NULL, 0, LONG_MAX, NULL);
> + if (!cond->sema) {
> + error_exit(GetLastError(), __func__);
> + }
> + cond->continue_event = CreateEvent(NULL, /* security */
> + FALSE, /* auto-reset */
> + FALSE, /* not signaled */
> + NULL); /* name */
> + if (!cond->continue_event) {
> + error_exit(GetLastError(), __func__);
> + }
> +}
> +
> +void qemu_cond_signal(QemuCond *cond)
> +{
> + DWORD result;
> +
> + /*
> + * Signal only when there are waiters. cond->waiters is
> + * incremented by pthread_cond_wait under the external lock,
> + * so we are safe about that.
> + */
> + if (cond->waiters == 0) {
> + return;
> + }
> +
> + /*
> + * Waiting threads decrement it outside the external lock, but
> + * only if another thread is executing pthread_cond_broadcast and
> + * has the mutex. So, it also cannot be decremented concurrently
> + * with this particular access.
> + */
> + cond->target = cond->waiters - 1;
> + result = SignalObjectAndWait(cond->sema, cond->continue_event,
> + INFINITE, FALSE);
> + if (result == WAIT_ABANDONED || result == WAIT_FAILED) {
> + error_exit(GetLastError(), __func__);
> + }
> +}
> +
> +void qemu_cond_broadcast(QemuCond *cond)
> +{
> + BOOLEAN result;
> + /*
> + * As in pthread_cond_signal, access to cond->waiters and
> + * cond->target is locked via the external mutex.
> + */
> + if (cond->waiters == 0) {
> + return;
> + }
> +
> + cond->target = 0;
> + result = ReleaseSemaphore(cond->sema, cond->waiters, NULL);
> + if (!result) {
> + error_exit(GetLastError(), __func__);
> + }
> +
> + /*
> + * At this point all waiters continue. Each one takes its
> + * slice of the semaphore. Now it's our turn to wait: Since
> + * the external mutex is held, no thread can leave cond_wait,
> + * yet. For this reason, we can be sure that no thread gets
> + * a chance to eat *more* than one slice. OTOH, it means
> + * that the last waiter must send us a wake-up.
> + */
> + WaitForSingleObject(cond->continue_event, INFINITE);
> +}
> +
> +void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex)
> +{
> + /*
> + * This access is protected under the mutex.
> + */
> + cond->waiters++;
> +
> + /*
> + * Unlock external mutex and wait for signal.
> + * NOTE: we've held mutex locked long enough to increment
> + * waiters count above, so there's no problem with
> + * leaving mutex unlocked before we wait on semaphore.
> + */
> + qemu_mutex_unlock(mutex);
> + WaitForSingleObject(cond->sema, INFINITE);
> +
> + /* Now waiters must rendez-vous with the signaling thread and
> + * let it continue. For cond_broadcast this has heavy contention
> + * and triggers thundering herd. So goes life.
> + *
> + * Decrease waiters count. The mutex is not taken, so we have
> + * to do this atomically.
> + *
> + * All waiters contend for the mutex at the end of this function
> + * until the signaling thread relinquishes it. To ensure
> + * each waiter consumes exactly one slice of the semaphore,
> + * the signaling thread stops until it is told by the last
> + * waiter that it can go on.
> + */
> + if (InterlockedDecrement(&cond->waiters) == cond->target) {
> + SetEvent(cond->continue_event);
> + }
> +
> + qemu_mutex_lock(mutex);
> +}
> +
> +struct qemu_thread_data {
QemuThreadData?
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] [PATCH v2 uq/master 00/22] Win32 iothread support
2011-02-26 15:39 [Qemu-devel] [PATCH v2 uq/master 00/22] Win32 iothread support Paolo Bonzini
` (21 preceding siblings ...)
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 22/22] add Win32 IPI service Paolo Bonzini
@ 2011-02-26 16:49 ` Blue Swirl
2011-02-27 9:47 ` [Qemu-devel] " Jan Kiszka
23 siblings, 0 replies; 31+ messages in thread
From: Blue Swirl @ 2011-02-26 16:49 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: jan.kiszka, qemu-devel, aurelien
On Sat, Feb 26, 2011 at 5:39 PM, Paolo Bonzini <pbonzini@redhat.com> wrote:
> After gathering the comments about the two series I sent separately,
> here is the full series for Win32 iothread support, ready to be
> applied to uq/master.
>
> Patches 1 to 5 are generic Win32 improvements, including the qemu-thread
> implementation. Because of complex dependencies, I think it's better
> if this part is also routed through uq/master.
>
> Patches 6 to 8 are generic threading improvements, including using
> PTHREAD_MUTEX_ERRORCHECK as suggested by Jan.
>
> Patches 9 to 17 eliminate polling, replacing condition variable
> timedwait with wait.
>
> Patch 18 removes a redundant condition from the TCG cpu_exec_all
> function.
>
> Patches 19 to 21 add all necessary stubs to make iothread compile
> with Win32, except the IPI calls. These are provided by patch 22.
>
> Tested on Wine and Linux, not on "real" Windows. The series introduces
> a dependency on Windows 2K or newer. I don't think either 95/98/ME
> or Windows NT 3.x are reasonable host systems for QEMU, anyway.
>
> I incorporated all suggestions from Jan, including his renaming patch
> for qemu_*_is_self, and included Aurelien's sh4 tweak to cpu_halted.
All look OK except for a minor structure naming nitpick.
^ permalink raw reply [flat|nested] 31+ messages in thread
* [Qemu-devel] Re: [PATCH v2 upstream 05/22] add win32 qemu-thread implementation
2011-02-26 16:47 ` Blue Swirl
@ 2011-02-26 17:42 ` Paolo Bonzini
0 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2011-02-26 17:42 UTC (permalink / raw)
To: Blue Swirl; +Cc: jan.kiszka, qemu-devel, aurelien
On 02/26/2011 05:47 PM, Blue Swirl wrote:
> On Sat, Feb 26, 2011 at 5:40 PM, Paolo Bonzini<pbonzini@redhat.com> wrote:
>> For now, qemu_cond_timedwait and qemu_mutex_timedlock are left as
>> POSIX-only functions. They can be removed later, once the patches
>> that remove their uses are in.
>>
>> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
>> ---
>> Makefile.objs | 4 +-
>> qemu-thread.c => qemu-thread-posix.c | 0
>> qemu-thread-posix.h | 18 +++
>> qemu-thread-win32.c | 260 ++++++++++++++++++++++++++++++++++
>> qemu-thread-win32.h | 21 +++
>> qemu-thread.h | 27 ++--
>> 6 files changed, 313 insertions(+), 17 deletions(-)
>> rename qemu-thread.c => qemu-thread-posix.c (100%)
>> create mode 100644 qemu-thread-posix.h
>> create mode 100644 qemu-thread-win32.c
>> create mode 100644 qemu-thread-win32.h
>>
>> diff --git a/Makefile.objs b/Makefile.objs
>> index 9e98a66..a52f42f 100644
>> --- a/Makefile.objs
>> +++ b/Makefile.objs
>> @@ -142,8 +142,8 @@ endif
>> common-obj-y += $(addprefix ui/, $(ui-obj-y))
>>
>> common-obj-y += iov.o acl.o
>> -common-obj-$(CONFIG_THREAD) += qemu-thread.o
>> -common-obj-$(CONFIG_POSIX) += compatfd.o
>> +common-obj-$(CONFIG_POSIX) += qemu-thread-posix.o compatfd.o
>> +common-obj-$(CONFIG_WIN32) += qemu-thread-win32.o
>> common-obj-y += notify.o event_notifier.o
>> common-obj-y += qemu-timer.o qemu-timer-common.o
>>
>> diff --git a/qemu-thread.c b/qemu-thread-posix.c
>> similarity index 100%
>> rename from qemu-thread.c
>> rename to qemu-thread-posix.c
>> diff --git a/qemu-thread-posix.h b/qemu-thread-posix.h
>> new file mode 100644
>> index 0000000..7af371c
>> --- /dev/null
>> +++ b/qemu-thread-posix.h
>> @@ -0,0 +1,18 @@
>> +#ifndef __QEMU_THREAD_POSIX_H
>> +#define __QEMU_THREAD_POSIX_H 1
>> +#include "pthread.h"
>> +
>> +struct QemuMutex {
>> + pthread_mutex_t lock;
>> +};
>> +
>> +struct QemuCond {
>> + pthread_cond_t cond;
>> +};
>> +
>> +struct QemuThread {
>> + pthread_t thread;
>> +};
>> +
>> +void qemu_thread_signal(QemuThread *thread, int sig);
>> +#endif
>> diff --git a/qemu-thread-win32.c b/qemu-thread-win32.c
>> new file mode 100644
>> index 0000000..89422ce
>> --- /dev/null
>> +++ b/qemu-thread-win32.c
>> @@ -0,0 +1,260 @@
>> +/*
>> + * Win32 implementation for mutex/cond/thread functions
>> + *
>> + * Copyright Red Hat, Inc. 2010
>> + *
>> + * Author:
>> + * Paolo Bonzini<pbonzini@redhat.com>
>> + *
>> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
>> + * See the COPYING file in the top-level directory.
>> + *
>> + */
>> +#include "qemu-common.h"
>> +#include "qemu-thread.h"
>> +#include<process.h>
>> +#include<assert.h>
>> +#include<limits.h>
>> +
>> +static void error_exit(int err, const char *msg)
>> +{
>> + char *pstr;
>> +
>> + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
>> + NULL, err, 0, (LPTSTR)&pstr, 2, NULL);
>> + fprintf(stderr, "qemu: %s: %s\n", msg, pstr);
>> + LocalFree(pstr);
>> + exit(1);
>> +}
>> +
>> +void qemu_mutex_init(QemuMutex *mutex)
>> +{
>> + mutex->owner = 0;
>> + InitializeCriticalSection(&mutex->lock);
>> +}
>> +
>> +void qemu_mutex_lock(QemuMutex *mutex)
>> +{
>> + EnterCriticalSection(&mutex->lock);
>> +
>> + /* Win32 CRITICAL_SECTIONs are recursive. Assert that we're not
>> + * using them as such.
>> + */
>> + assert(mutex->owner == 0);
>> + mutex->owner = GetCurrentThreadId();
>> +}
>> +
>> +int qemu_mutex_trylock(QemuMutex *mutex)
>> +{
>> + int owned;
>> +
>> + owned = TryEnterCriticalSection(&mutex->lock);
>> + if (owned) {
>> + assert(mutex->owner == 0);
>> + mutex->owner = GetCurrentThreadId();
>> + }
>> + return !owned;
>> +}
>> +
>> +void qemu_mutex_unlock(QemuMutex *mutex)
>> +{
>> + assert(mutex->owner == GetCurrentThreadId());
>> + mutex->owner = 0;
>> + LeaveCriticalSection(&mutex->lock);
>> +}
>> +
>> +void qemu_cond_init(QemuCond *cond)
>> +{
>> + memset(cond, 0, sizeof(*cond));
>> +
>> + cond->sema = CreateSemaphore(NULL, 0, LONG_MAX, NULL);
>> + if (!cond->sema) {
>> + error_exit(GetLastError(), __func__);
>> + }
>> + cond->continue_event = CreateEvent(NULL, /* security */
>> + FALSE, /* auto-reset */
>> + FALSE, /* not signaled */
>> + NULL); /* name */
>> + if (!cond->continue_event) {
>> + error_exit(GetLastError(), __func__);
>> + }
>> +}
>> +
>> +void qemu_cond_signal(QemuCond *cond)
>> +{
>> + DWORD result;
>> +
>> + /*
>> + * Signal only when there are waiters. cond->waiters is
>> + * incremented by pthread_cond_wait under the external lock,
>> + * so we are safe about that.
>> + */
>> + if (cond->waiters == 0) {
>> + return;
>> + }
>> +
>> + /*
>> + * Waiting threads decrement it outside the external lock, but
>> + * only if another thread is executing pthread_cond_broadcast and
>> + * has the mutex. So, it also cannot be decremented concurrently
>> + * with this particular access.
>> + */
>> + cond->target = cond->waiters - 1;
>> + result = SignalObjectAndWait(cond->sema, cond->continue_event,
>> + INFINITE, FALSE);
>> + if (result == WAIT_ABANDONED || result == WAIT_FAILED) {
>> + error_exit(GetLastError(), __func__);
>> + }
>> +}
>> +
>> +void qemu_cond_broadcast(QemuCond *cond)
>> +{
>> + BOOLEAN result;
>> + /*
>> + * As in pthread_cond_signal, access to cond->waiters and
>> + * cond->target is locked via the external mutex.
>> + */
>> + if (cond->waiters == 0) {
>> + return;
>> + }
>> +
>> + cond->target = 0;
>> + result = ReleaseSemaphore(cond->sema, cond->waiters, NULL);
>> + if (!result) {
>> + error_exit(GetLastError(), __func__);
>> + }
>> +
>> + /*
>> + * At this point all waiters continue. Each one takes its
>> + * slice of the semaphore. Now it's our turn to wait: Since
>> + * the external mutex is held, no thread can leave cond_wait,
>> + * yet. For this reason, we can be sure that no thread gets
>> + * a chance to eat *more* than one slice. OTOH, it means
>> + * that the last waiter must send us a wake-up.
>> + */
>> + WaitForSingleObject(cond->continue_event, INFINITE);
>> +}
>> +
>> +void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex)
>> +{
>> + /*
>> + * This access is protected under the mutex.
>> + */
>> + cond->waiters++;
>> +
>> + /*
>> + * Unlock external mutex and wait for signal.
>> + * NOTE: we've held mutex locked long enough to increment
>> + * waiters count above, so there's no problem with
>> + * leaving mutex unlocked before we wait on semaphore.
>> + */
>> + qemu_mutex_unlock(mutex);
>> + WaitForSingleObject(cond->sema, INFINITE);
>> +
>> + /* Now waiters must rendez-vous with the signaling thread and
>> + * let it continue. For cond_broadcast this has heavy contention
>> + * and triggers thundering herd. So goes life.
>> + *
>> + * Decrease waiters count. The mutex is not taken, so we have
>> + * to do this atomically.
>> + *
>> + * All waiters contend for the mutex at the end of this function
>> + * until the signaling thread relinquishes it. To ensure
>> + * each waiter consumes exactly one slice of the semaphore,
>> + * the signaling thread stops until it is told by the last
>> + * waiter that it can go on.
>> + */
>> + if (InterlockedDecrement(&cond->waiters) == cond->target) {
>> + SetEvent(cond->continue_event);
>> + }
>> +
>> + qemu_mutex_lock(mutex);
>> +}
>> +
>> +struct qemu_thread_data {
>
> QemuThreadData?
Ok, will resubmit asap. Can you add this convention to checkpatch?
Paolo
^ permalink raw reply [flat|nested] 31+ messages in thread
* [Qemu-devel] Re: [PATCH v2 upstream 07/22] add assertions on the owner of a QemuMutex
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 07/22] add assertions on the owner of a QemuMutex Paolo Bonzini
@ 2011-02-27 9:33 ` Jan Kiszka
2011-02-27 15:06 ` Paolo Bonzini
0 siblings, 1 reply; 31+ messages in thread
From: Jan Kiszka @ 2011-02-27 9:33 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel, aurelien
[-- Attachment #1: Type: text/plain, Size: 3227 bytes --]
On 2011-02-26 16:40, Paolo Bonzini wrote:
> These are already present in the Win32 implementation, add them to
> the pthread wrappers as well. Use PTHREAD_MUTEX_ERRORCHECK for mutex
> operations, and track the owner separately for cond_signal/broadcast.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> qemu-thread-posix.c | 23 +++++++++++++++++++++--
> qemu-thread-posix.h | 1 +
> 2 files changed, 22 insertions(+), 2 deletions(-)
>
> diff --git a/qemu-thread-posix.c b/qemu-thread-posix.c
> index e307773..a4c6e25 100644
> --- a/qemu-thread-posix.c
> +++ b/qemu-thread-posix.c
> @@ -16,9 +16,12 @@
> #include <time.h>
> #include <signal.h>
> #include <stdint.h>
> +#include <assert.h>
> #include <string.h>
> #include "qemu-thread.h"
>
> +static pthread_t pthread_null;
> +
> static void error_exit(int err, const char *msg)
> {
> fprintf(stderr, "qemu: %s: %s\n", msg, strerror(err));
> @@ -28,8 +31,13 @@ static void error_exit(int err, const char *msg)
> void qemu_mutex_init(QemuMutex *mutex)
> {
> int err;
> + pthread_mutexattr_t mutexattr;
>
> - err = pthread_mutex_init(&mutex->lock, NULL);
> + mutex->owner = pthread_null;
> + pthread_mutexattr_init(&mutexattr);
> + pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_ERRORCHECK);
> + err = pthread_mutex_init(&mutex->lock, &mutexattr);
> + pthread_mutexattr_destroy(&mutexattr);
> if (err)
> error_exit(err, __func__);
> }
> @@ -48,13 +56,20 @@ void qemu_mutex_lock(QemuMutex *mutex)
> int err;
>
> err = pthread_mutex_lock(&mutex->lock);
> + mutex->owner = pthread_self();
> if (err)
> error_exit(err, __func__);
> }
>
> int qemu_mutex_trylock(QemuMutex *mutex)
> {
> - return pthread_mutex_trylock(&mutex->lock);
> + int err;
> + err = pthread_mutex_trylock(&mutex->lock);
> + if (err == 0) {
> + mutex->owner = pthread_self();
> + }
> +
> + return !!err;
> }
>
> static void timespec_add_ms(struct timespec *ts, uint64_t msecs)
> @@ -85,6 +100,7 @@ void qemu_mutex_unlock(QemuMutex *mutex)
> {
> int err;
>
> + mutex->owner = pthread_null;
> err = pthread_mutex_unlock(&mutex->lock);
> if (err)
> error_exit(err, __func__);
> @@ -130,7 +146,10 @@ void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex)
> {
> int err;
>
> + assert(pthread_equal(mutex->owner, pthread_self()));
> + mutex->owner = pthread_null;
> err = pthread_cond_wait(&cond->cond, &mutex->lock);
Though POSIX is not 100% explicit on this, every sane pthread_cond_wait
implementation will apply the same error checking as on
pthread_mutex_unlock when the given mutex is of
PTHREAD_MUTEX_ERRORCHECK. So, this assert is actually redundant as well.
Now that we are left without any assertions, I start wondering about one
of the original missions: enforce qemu_cond_signal/broadcast to be
called under a mutex. What about extending those services with a mutex
argument and applying the assert there? Could become a static-inline
wrapper so that the argument is optimized away if assert() is inactive.
Jan
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]
^ permalink raw reply [flat|nested] 31+ messages in thread
* [Qemu-devel] Re: [PATCH v2 upstream 19/22] move blocking of signals to qemu_signalfd_init
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 19/22] move blocking of signals to qemu_signalfd_init Paolo Bonzini
@ 2011-02-27 9:41 ` Jan Kiszka
2011-02-27 15:07 ` Paolo Bonzini
0 siblings, 1 reply; 31+ messages in thread
From: Jan Kiszka @ 2011-02-27 9:41 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel, Aurelien Jarno
[-- Attachment #1: Type: text/plain, Size: 3892 bytes --]
On 2011-02-26 16:40, Paolo Bonzini wrote:
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> cpus.c | 87 ++++++++++++++++++++++++++-------------------------------------
> 1 files changed, 36 insertions(+), 51 deletions(-)
>
> diff --git a/cpus.c b/cpus.c
> index 32e9352..8c440f1 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -346,11 +346,37 @@ static void sigfd_handler(void *opaque)
> }
> }
>
> -static int qemu_signalfd_init(sigset_t mask)
> +static int qemu_signalfd_init(void)
> {
> int sigfd;
> + sigset_t set;
>
> - sigfd = qemu_signalfd(&mask);
> +#ifdef CONFIG_IOTHREAD
> + /* SIGUSR2 used by posix-aio-compat.c */
> + sigemptyset(&set);
> + sigaddset(&set, SIGUSR2);
> + pthread_sigmask(SIG_UNBLOCK, &set, NULL);
Didn't you want to rename the function for the sake of non-signalfd
blocks like above?
> +
> + sigemptyset(&set);
> + sigaddset(&set, SIGIO);
> + sigaddset(&set, SIGALRM);
> + sigaddset(&set, SIG_IPI);
> + sigaddset(&set, SIGBUS);
> + pthread_sigmask(SIG_BLOCK, &set, NULL);
> +#else
> + sigemptyset(&set);
This line is shared and can be moved out of the #ifdef.
> + sigaddset(&set, SIGBUS);
> + if (kvm_enabled()) {
> + /*
> + * We need to process timer signals synchronously to avoid a race
> + * between exit_request check and KVM vcpu entry.
> + */
> + sigaddset(&set, SIGIO);
> + sigaddset(&set, SIGALRM);
> + }
> +#endif
> +
> + sigfd = qemu_signalfd(&set);
> if (sigfd == -1) {
> fprintf(stderr, "failed to create signalfd\n");
> return -errno;
> @@ -438,6 +464,12 @@ static void qemu_event_increment(void)
> static void qemu_kvm_eat_signals(CPUState *env)
> {
> }
> +
> +static int qemu_signalfd_init(void)
> +{
> + return 0;
> +}
> +
> #endif /* _WIN32 */
>
> #ifndef CONFIG_IOTHREAD
> @@ -471,39 +503,14 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
> #endif
> }
>
> -#ifndef _WIN32
> -static sigset_t block_synchronous_signals(void)
> -{
> - sigset_t set;
> -
> - sigemptyset(&set);
> - sigaddset(&set, SIGBUS);
> - if (kvm_enabled()) {
> - /*
> - * We need to process timer signals synchronously to avoid a race
> - * between exit_request check and KVM vcpu entry.
> - */
> - sigaddset(&set, SIGIO);
> - sigaddset(&set, SIGALRM);
> - }
> -
> - return set;
> -}
> -#endif
> -
> int qemu_init_main_loop(void)
> {
> -#ifndef _WIN32
> - sigset_t blocked_signals;
> int ret;
>
> - blocked_signals = block_synchronous_signals();
> -
> - ret = qemu_signalfd_init(blocked_signals);
> + ret = qemu_signalfd_init();
> if (ret) {
> return ret;
> }
> -#endif
>
> qemu_init_sigbus();
>
> @@ -651,35 +658,13 @@ static void qemu_tcg_init_cpu_signals(void)
> pthread_sigmask(SIG_UNBLOCK, &set, NULL);
> }
>
> -static sigset_t block_io_signals(void)
> -{
> - sigset_t set;
> -
> - /* SIGUSR2 used by posix-aio-compat.c */
> - sigemptyset(&set);
> - sigaddset(&set, SIGUSR2);
> - pthread_sigmask(SIG_UNBLOCK, &set, NULL);
> -
> - sigemptyset(&set);
> - sigaddset(&set, SIGIO);
> - sigaddset(&set, SIGALRM);
> - sigaddset(&set, SIG_IPI);
> - sigaddset(&set, SIGBUS);
> - pthread_sigmask(SIG_BLOCK, &set, NULL);
> -
> - return set;
> -}
> -
> int qemu_init_main_loop(void)
> {
> int ret;
> - sigset_t blocked_signals;
>
> qemu_init_sigbus();
>
> - blocked_signals = block_io_signals();
> -
> - ret = qemu_signalfd_init(blocked_signals);
> + ret = qemu_signalfd_init();
> if (ret) {
> return ret;
> }
Beside the minor nits, this looks good.
Jan
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]
^ permalink raw reply [flat|nested] 31+ messages in thread
* [Qemu-devel] Re: [PATCH v2 uq/master 00/22] Win32 iothread support
2011-02-26 15:39 [Qemu-devel] [PATCH v2 uq/master 00/22] Win32 iothread support Paolo Bonzini
` (22 preceding siblings ...)
2011-02-26 16:49 ` [Qemu-devel] [PATCH v2 uq/master 00/22] Win32 iothread support Blue Swirl
@ 2011-02-27 9:47 ` Jan Kiszka
23 siblings, 0 replies; 31+ messages in thread
From: Jan Kiszka @ 2011-02-27 9:47 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel, aurelien
[-- Attachment #1: Type: text/plain, Size: 1449 bytes --]
On 2011-02-26 16:39, Paolo Bonzini wrote:
> After gathering the comments about the two series I sent separately,
> here is the full series for Win32 iothread support, ready to be
> applied to uq/master.
>
> Patches 1 to 5 are generic Win32 improvements, including the qemu-thread
> implementation. Because of complex dependencies, I think it's better
> if this part is also routed through uq/master.
Agreed. This also ensures that the non-Win32 parts receive autotest
blessing before being applied.
>
> Patches 6 to 8 are generic threading improvements, including using
> PTHREAD_MUTEX_ERRORCHECK as suggested by Jan.
>
> Patches 9 to 17 eliminate polling, replacing condition variable
> timedwait with wait.
>
> Patch 18 removes a redundant condition from the TCG cpu_exec_all
> function.
>
> Patches 19 to 21 add all necessary stubs to make iothread compile
> with Win32, except the IPI calls. These are provided by patch 22.
>
> Tested on Wine and Linux, not on "real" Windows. The series introduces
> a dependency on Windows 2K or newer. I don't think either 95/98/ME
> or Windows NT 3.x are reasonable host systems for QEMU, anyway.
>
> I incorporated all suggestions from Jan, including his renaming patch
> for qemu_*_is_self, and included Aurelien's sh4 tweak to cpu_halted.
>
#ifndef _WIN32
Except for the minor remarks, looks very good to me.
#else
Can't asses.
#endif
Jan
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]
^ permalink raw reply [flat|nested] 31+ messages in thread
* [Qemu-devel] Re: [PATCH v2 upstream 07/22] add assertions on the owner of a QemuMutex
2011-02-27 9:33 ` [Qemu-devel] " Jan Kiszka
@ 2011-02-27 15:06 ` Paolo Bonzini
0 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2011-02-27 15:06 UTC (permalink / raw)
To: Jan Kiszka; +Cc: qemu-devel, aurelien
On 02/27/2011 10:33 AM, Jan Kiszka wrote:
> Now that we are left without any assertions, I start wondering about one
> of the original missions: enforce qemu_cond_signal/broadcast to be
> called under a mutex. What about extending those services with a mutex
> argument and applying the assert there?
That is one of the patches in my queue that I haven't submitted yet. :)
Paolo
^ permalink raw reply [flat|nested] 31+ messages in thread
* [Qemu-devel] Re: [PATCH v2 upstream 19/22] move blocking of signals to qemu_signalfd_init
2011-02-27 9:41 ` [Qemu-devel] " Jan Kiszka
@ 2011-02-27 15:07 ` Paolo Bonzini
0 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2011-02-27 15:07 UTC (permalink / raw)
To: Jan Kiszka; +Cc: qemu-devel, Aurelien Jarno
On 02/27/2011 10:41 AM, Jan Kiszka wrote:
>> > +#ifdef CONFIG_IOTHREAD
>> > + /* SIGUSR2 used by posix-aio-compat.c */
>> > + sigemptyset(&set);
>> > + sigaddset(&set, SIGUSR2);
>> > + pthread_sigmask(SIG_UNBLOCK,&set, NULL);
>
> Didn't you want to rename the function for the sake of non-signalfd
> blocks like above?
Right.
>> > +
>> > + sigemptyset(&set);
>> > + sigaddset(&set, SIGIO);
>> > + sigaddset(&set, SIGALRM);
>> > + sigaddset(&set, SIG_IPI);
>> > + sigaddset(&set, SIGBUS);
>> > + pthread_sigmask(SIG_BLOCK,&set, NULL);
>> > +#else
>> > + sigemptyset(&set);
>
> This line is shared and can be moved out of the #ifdef.
It's shared but for different purposes (UNBLOCK for iothread,
BLOCK/signalfd for !iothread), so I decided not to hoist it out.
Paolo
^ permalink raw reply [flat|nested] 31+ messages in thread
end of thread, other threads:[~2011-02-27 15:08 UTC | newest]
Thread overview: 31+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-02-26 15:39 [Qemu-devel] [PATCH v2 uq/master 00/22] Win32 iothread support Paolo Bonzini
2011-02-26 15:39 ` [Qemu-devel] [PATCH v2 upstream 01/22] unlock iothread during WaitForMultipleObjects Paolo Bonzini
2011-02-26 15:39 ` [Qemu-devel] [PATCH v2 upstream 02/22] implement win32 dynticks timer Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 03/22] use win32 timer queues Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 04/22] Refactor thread retrieval and check Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 05/22] add win32 qemu-thread implementation Paolo Bonzini
2011-02-26 16:47 ` Blue Swirl
2011-02-26 17:42 ` [Qemu-devel] " Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 06/22] include qemu-thread.h early Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 07/22] add assertions on the owner of a QemuMutex Paolo Bonzini
2011-02-27 9:33 ` [Qemu-devel] " Jan Kiszka
2011-02-27 15:06 ` Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 08/22] remove CONFIG_THREAD Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 09/22] target-sh4: move intr_at_halt out of cpu_halted() Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 10/22] inline cpu_halted into sole caller Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 11/22] always qemu_cpu_kick after unhalting a cpu Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 12/22] exit round-robin vcpu loop if cpu->stopped is true Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 13/22] always signal pause_cond after stopping a VCPU Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 14/22] do not use timedwait on qemu_halt_cond Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 15/22] do not use timedwait on qemu_system_cond Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 16/22] do not use timedwait on qemu_pause_cond Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 17/22] do not use timedwait on qemu_cpu_cond Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 18/22] iothread stops the vcpu thread via IPI Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 19/22] move blocking of signals to qemu_signalfd_init Paolo Bonzini
2011-02-27 9:41 ` [Qemu-devel] " Jan Kiszka
2011-02-27 15:07 ` Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 20/22] provide dummy signal init functions for win32 Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 21/22] protect qemu_cpu_kick_self for Win32 Paolo Bonzini
2011-02-26 15:40 ` [Qemu-devel] [PATCH v2 upstream 22/22] add Win32 IPI service Paolo Bonzini
2011-02-26 16:49 ` [Qemu-devel] [PATCH v2 uq/master 00/22] Win32 iothread support Blue Swirl
2011-02-27 9:47 ` [Qemu-devel] " Jan Kiszka
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).