From 14ea9b28fa060b27553d93a0700853f8842d8cc3 Mon Sep 17 00:00:00 2001
From: Jeffrey Cody <jcody@redhat.com>
Date: Wed, 21 Mar 2012 21:55:02 +0100
Subject: [PATCH 35/55] coroutine: add co_sleep_ns() coroutine sleep function

RH-Author: Jeffrey Cody <jcody@redhat.com>
Message-id: <4b25eb864994581d80d8f26311fafc03258545a5.1332362400.git.jcody@redhat.com>
Patchwork-id: 38885
O-Subject: [RHEL6.3 qemu-kvm PATCH v8 35/54] coroutine: add co_sleep_ns() coroutine sleep function
Bugzilla: 582475
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Marcelo Tosatti <mtosatti@redhat.com>
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>

From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>

Note: the function is called co_sleep() and its granularity is dependent
on the given clock because qemu-timer refactoring has not been
backported.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>

(cherry picked from commit 7e6246670add62116729bd93811e41eb60f66b77)

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Jeff Cody <jcody@redhat.com>
---
 Makefile.objs          |    1 +
 qemu-coroutine-sleep.c |   38 ++++++++++++++++++++++++++++++++++++++
 qemu-coroutine.h       |   14 ++++++++++++++
 qemu-timer.h           |    1 +
 4 files changed, 54 insertions(+), 0 deletions(-)
 create mode 100644 qemu-coroutine-sleep.c

Signed-off-by: Michal Novotny <minovotn@redhat.com>
---
 Makefile.objs          |    1 +
 qemu-coroutine-sleep.c |   38 ++++++++++++++++++++++++++++++++++++++
 qemu-coroutine.h       |   14 ++++++++++++++
 qemu-timer.h           |    1 +
 4 files changed, 54 insertions(+), 0 deletions(-)
 create mode 100644 qemu-coroutine-sleep.c

diff --git a/Makefile.objs b/Makefile.objs
index 7086535..716b346 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -7,6 +7,7 @@ qobject-obj-y += qerror.o error.o
 #######################################################################
 # coroutines
 coroutine-obj-y = qemu-coroutine.o qemu-coroutine-lock.o
+coroutine-obj-y += qemu-coroutine-sleep.o
 coroutine-obj-$(CONFIG_POSIX) += coroutine-ucontext.o
 coroutine-obj-$(CONFIG_WIN32) += coroutine-win32.o
 
diff --git a/qemu-coroutine-sleep.c b/qemu-coroutine-sleep.c
new file mode 100644
index 0000000..ed115a1
--- /dev/null
+++ b/qemu-coroutine-sleep.c
@@ -0,0 +1,38 @@
+/*
+ * QEMU coroutine sleep
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Stefan Hajnoczi    <stefanha@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#include "qemu-coroutine.h"
+#include "qemu-timer.h"
+
+typedef struct CoSleepCB {
+    QEMUTimer *ts;
+    Coroutine *co;
+} CoSleepCB;
+
+static void co_sleep_cb(void *opaque)
+{
+    CoSleepCB *sleep_cb = opaque;
+
+    qemu_free_timer(sleep_cb->ts);
+    qemu_coroutine_enter(sleep_cb->co, NULL);
+}
+
+void coroutine_fn co_sleep(QEMUClock *clock, int64_t n)
+{
+    CoSleepCB sleep_cb = {
+        .co = qemu_coroutine_self(),
+    };
+    sleep_cb.ts = qemu_new_timer(clock, co_sleep_cb, &sleep_cb);
+    qemu_mod_timer(sleep_cb.ts, qemu_get_clock(clock) + n);
+    qemu_coroutine_yield();
+}
diff --git a/qemu-coroutine.h b/qemu-coroutine.h
index b4fa51e..0d4068a 100644
--- a/qemu-coroutine.h
+++ b/qemu-coroutine.h
@@ -17,6 +17,7 @@
 
 #include <stdbool.h>
 #include "qemu-queue.h"
+#include "qemu-timer.h"
 
 /**
  * Coroutines are a mechanism for stack switching and can be used for
@@ -161,4 +162,17 @@ void coroutine_fn qemu_co_mutex_lock(CoMutex *mutex);
  */
 void coroutine_fn qemu_co_mutex_unlock(CoMutex *mutex);
 
+/**
+ * Yield the coroutine for a given duration
+ *
+ * Note this function uses timers and hence only works when a main loop is in
+ * use.  See main-loop.h and do not use from qemu-tool programs.
+ *
+ * RHEL does not have nanosecond qemu-timer.h functions like upstream.  Instead
+ * it uses per-clock time units as was previously the case upstream.  Therefore
+ * the unit of the n argument depends on the clock and the function name does
+ * not include "_ns".
+ */
+void coroutine_fn co_sleep(QEMUClock *clock, int64_t n);
+
 #endif /* QEMU_COROUTINE_H */
diff --git a/qemu-timer.h b/qemu-timer.h
index 5e5942e..bac11db 100644
--- a/qemu-timer.h
+++ b/qemu-timer.h
@@ -1,6 +1,7 @@
 #ifndef QEMU_TIMER_H
 #define QEMU_TIMER_H
 
+#include "qemu-common.h"
 #include "notify.h"
 
 /* timers */
-- 
1.7.7.6

