summary refs log tree commit diff stats
path: root/include/qemu/coroutine.h
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2017-02-13 19:12:39 +0100
committerStefan Hajnoczi <stefanha@redhat.com>2017-02-21 11:39:40 +0000
commitfed20a70e39bb9385020bdc4e8839d95326df8e2 (patch)
tree07af96e10e918b1393a1ea94205f8802f4a0d1df /include/qemu/coroutine.h
parent91bcea4899017891983b9149bd50cb283e78dfc0 (diff)
downloadfocaccia-qemu-fed20a70e39bb9385020bdc4e8839d95326df8e2.tar.gz
focaccia-qemu-fed20a70e39bb9385020bdc4e8839d95326df8e2.zip
coroutine-lock: make CoMutex thread-safe
This uses the lock-free mutex described in the paper '"Blocking without
Locking", or LFTHREADS: A lock-free thread library' by Gidenstam and
Papatriantafilou.  The same technique is used in OSv, and in fact
the code is essentially a conversion to C of OSv's code.

[Added missing coroutine_fn in tests/test-aio-multithread.c.
--Stefan]

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Message-id: 20170213181244.16297-2-pbonzini@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'include/qemu/coroutine.h')
-rw-r--r--include/qemu/coroutine.h17
1 files changed, 15 insertions, 2 deletions
diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h
index 12584ed1b7..fce228f68a 100644
--- a/include/qemu/coroutine.h
+++ b/include/qemu/coroutine.h
@@ -160,10 +160,23 @@ bool qemu_co_queue_empty(CoQueue *queue);
 /**
  * Provides a mutex that can be used to synchronise coroutines
  */
+struct CoWaitRecord;
 typedef struct CoMutex {
-    bool locked;
+    /* Count of pending lockers; 0 for a free mutex, 1 for an
+     * uncontended mutex.
+     */
+    unsigned locked;
+
+    /* A queue of waiters.  Elements are added atomically in front of
+     * from_push.  to_pop is only populated, and popped from, by whoever
+     * is in charge of the next wakeup.  This can be an unlocker or,
+     * through the handoff protocol, a locker that is about to go to sleep.
+     */
+    QSLIST_HEAD(, CoWaitRecord) from_push, to_pop;
+
+    unsigned handoff, sequence;
+
     Coroutine *holder;
-    CoQueue queue;
 } CoMutex;
 
 /**