summary refs log tree commit diff stats
path: root/include/qemu/futex.h
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2017-01-12 19:07:54 +0100
committerStefan Hajnoczi <stefanha@redhat.com>2017-01-16 13:25:18 +0000
commitfbcc3e5004f01653b2885965c59cade25e286c18 (patch)
treeccdd40452c6ddce192c33a68832726fde7ee51f9 /include/qemu/futex.h
parentd7c99a1282ca2de1c344b8aa91be5364e9c6aa8f (diff)
downloadfocaccia-qemu-fbcc3e5004f01653b2885965c59cade25e286c18.tar.gz
focaccia-qemu-fbcc3e5004f01653b2885965c59cade25e286c18.zip
qemu-thread: optimize QemuLockCnt with futexes on Linux
This is complex, but I think it is reasonably documented in the source.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 20170112180800.21085-5-pbonzini@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'include/qemu/futex.h')
-rw-r--r--include/qemu/futex.h36
1 files changed, 36 insertions, 0 deletions
diff --git a/include/qemu/futex.h b/include/qemu/futex.h
new file mode 100644
index 0000000000..bb7dc9e296
--- /dev/null
+++ b/include/qemu/futex.h
@@ -0,0 +1,36 @@
+/*
+ * Wrappers around Linux futex syscall
+ *
+ * Copyright Red Hat, Inc. 2017
+ *
+ * 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 <sys/syscall.h>
+#include <linux/futex.h>
+
+#define qemu_futex(...)              syscall(__NR_futex, __VA_ARGS__)
+
+static inline void qemu_futex_wake(void *f, int n)
+{
+    qemu_futex(f, FUTEX_WAKE, n, NULL, NULL, 0);
+}
+
+static inline void qemu_futex_wait(void *f, unsigned val)
+{
+    while (qemu_futex(f, FUTEX_WAIT, (int) val, NULL, NULL, 0)) {
+        switch (errno) {
+        case EWOULDBLOCK:
+            return;
+        case EINTR:
+            break; /* get out of switch and retry */
+        default:
+            abort();
+        }
+    }
+}