[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v4 06/10] coroutine: add co_aio_sleep_ns() to allow
From: |
MORITA Kazutaka |
Subject: |
[Qemu-devel] [PATCH v4 06/10] coroutine: add co_aio_sleep_ns() to allow sleep in block drivers |
Date: |
Fri, 26 Jul 2013 15:10:48 +0900 |
This helper function behaves similarly to co_sleep_ns(), but the
sleeping coroutine will be resumed when using qemu_aio_wait().
Signed-off-by: MORITA Kazutaka <address@hidden>
---
include/block/coroutine.h | 8 ++++++++
qemu-coroutine-sleep.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 55 insertions(+)
diff --git a/include/block/coroutine.h b/include/block/coroutine.h
index 377805a..23ea6e9 100644
--- a/include/block/coroutine.h
+++ b/include/block/coroutine.h
@@ -210,6 +210,14 @@ void qemu_co_rwlock_unlock(CoRwlock *lock);
void coroutine_fn co_sleep_ns(QEMUClock *clock, int64_t ns);
/**
+ * Yield the coroutine for a given duration
+ *
+ * Behaves similarly to co_sleep_ns(), but the sleeping coroutine will be
+ * resumed when using qemu_aio_wait().
+ */
+void coroutine_fn co_aio_sleep_ns(int64_t ns);
+
+/**
* Yield until a file descriptor becomes readable
*
* Note that this function clobbers the handlers for the file descriptor.
diff --git a/qemu-coroutine-sleep.c b/qemu-coroutine-sleep.c
index 169ce5c..3955347 100644
--- a/qemu-coroutine-sleep.c
+++ b/qemu-coroutine-sleep.c
@@ -13,6 +13,7 @@
#include "block/coroutine.h"
#include "qemu/timer.h"
+#include "qemu/thread.h"
typedef struct CoSleepCB {
QEMUTimer *ts;
@@ -37,3 +38,49 @@ void coroutine_fn co_sleep_ns(QEMUClock *clock, int64_t ns)
qemu_del_timer(sleep_cb.ts);
qemu_free_timer(sleep_cb.ts);
}
+
+typedef struct CoAioSleepCB {
+ QEMUBH *bh;
+ int64_t ns;
+ Coroutine *co;
+} CoAioSleepCB;
+
+static void co_aio_sleep_cb(void *opaque)
+{
+ CoAioSleepCB *aio_sleep_cb = opaque;
+
+ qemu_coroutine_enter(aio_sleep_cb->co, NULL);
+}
+
+static void *sleep_thread(void *opaque)
+{
+ CoAioSleepCB *aio_sleep_cb = opaque;
+ struct timespec req = {
+ .tv_sec = aio_sleep_cb->ns / 1000000000,
+ .tv_nsec = aio_sleep_cb->ns % 1000000000,
+ };
+ struct timespec rem;
+
+ while (nanosleep(&req, &rem) < 0 && errno == EINTR) {
+ req = rem;
+ }
+
+ qemu_bh_schedule(aio_sleep_cb->bh);
+
+ return NULL;
+}
+
+void coroutine_fn co_aio_sleep_ns(int64_t ns)
+{
+ CoAioSleepCB aio_sleep_cb = {
+ .ns = ns,
+ .co = qemu_coroutine_self(),
+ };
+ QemuThread thread;
+
+ aio_sleep_cb.bh = qemu_bh_new(co_aio_sleep_cb, &aio_sleep_cb);
+ qemu_thread_create(&thread, sleep_thread, &aio_sleep_cb,
+ QEMU_THREAD_DETACHED);
+ qemu_coroutine_yield();
+ qemu_bh_delete(aio_sleep_cb.bh);
+}
--
1.8.1.3.566.gaa39828
- [Qemu-devel] [PATCH v4 00/10] sheepdog: reconnect server after connection failure, MORITA Kazutaka, 2013/07/26
- [Qemu-devel] [PATCH v4 06/10] coroutine: add co_aio_sleep_ns() to allow sleep in block drivers,
MORITA Kazutaka <=
- [Qemu-devel] [PATCH v4 02/10] iov: handle EOF in iov_send_recv, MORITA Kazutaka, 2013/07/26
- [Qemu-devel] [PATCH v4 10/10] sheepdog: check simultaneous create in resend_aioreq, MORITA Kazutaka, 2013/07/26
- [Qemu-devel] [PATCH v4 01/10] ignore SIGPIPE in qemu-img and qemu-io, MORITA Kazutaka, 2013/07/26
- [Qemu-devel] [PATCH v4 03/10] sheepdog: check return values of qemu_co_recv/send correctly, MORITA Kazutaka, 2013/07/26
- [Qemu-devel] [PATCH v4 05/10] sheepdog: reload inode outside of resend_aioreq, MORITA Kazutaka, 2013/07/26
- [Qemu-devel] [PATCH v4 09/10] sheepdog: cancel aio requests if possible, MORITA Kazutaka, 2013/07/26
- [Qemu-devel] [PATCH v4 08/10] sheepdog: make add_aio_request and send_aioreq void functions, MORITA Kazutaka, 2013/07/26