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 pbonz...@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 000..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 000..2edcb1a
--- /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 pbonz...@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