[PATCH v3 uq/master 05/22] add win32 qemu-thread implementation

2011-02-28 Thread Paolo Bonzini
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 

Re: [PATCH v3 uq/master 05/22] add win32 qemu-thread implementation

2011-02-28 Thread Stefan Hajnoczi
On Mon, Feb 28, 2011 at 9:10 AM, Paolo Bonzini pbonz...@redhat.com wrote:
 +static unsigned __stdcall win32_start_routine(void *arg)
 +{
 +    struct QemuThreadData data = *(struct QemuThreadData *) arg;
 +    QemuThread *thread = data.thread;
 +
 +    free(arg);

qemu_free(arg);

Stefan
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html