summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/base/coroutine.hh13
-rw-r--r--src/base/coroutine.test.cc19
2 files changed, 29 insertions, 3 deletions
diff --git a/src/base/coroutine.hh b/src/base/coroutine.hh
index d28889296..35c3ab943 100644
--- a/src/base/coroutine.hh
+++ b/src/base/coroutine.hh
@@ -161,14 +161,21 @@ class Coroutine : public Fiber
* it needs to run. The first argument of the function should be a
* reference to the Coroutine<Arg,Ret>::caller_type which the
* routine will use as a way for yielding to the caller.
+ * The optional second boolean argument controls if the Coroutine
+ * should be run on creation, which mimics Boost's Coroutine
+ * semantics by default. This can be disabled as an optimization to
+ * avoid unnecessary context switches on Coroutine creation.
*
* @param f task run by the coroutine
+ * @param run_coroutine set to false to disable running the coroutine
+ * immediately after it is created
*/
- Coroutine(std::function<void(CallerType&)> f)
+ Coroutine(std::function<void(CallerType&)> f, bool run_coroutine = true)
: Fiber(), task(f), caller(*this)
{
- // Create and Run the Coroutine
- this->call();
+ // When desired, run the Coroutine after it is created
+ if (run_coroutine)
+ this->call();
}
virtual ~Coroutine() {}
diff --git a/src/base/coroutine.test.cc b/src/base/coroutine.test.cc
index 655bc254a..586686972 100644
--- a/src/base/coroutine.test.cc
+++ b/src/base/coroutine.test.cc
@@ -44,6 +44,25 @@
using namespace m5;
/**
+ * This test is checking if the Coroutine, once it's created
+ * it doesn't start since the second argument of the constructor
+ * (run_coroutine) is set to false
+ */
+TEST(Coroutine, Unstarted)
+{
+ auto yielding_task =
+ [] (Coroutine<void, void>::CallerType& yield)
+ {
+ yield();
+ };
+
+ const bool start_upon_creation = false;
+ Coroutine<void, void> coro(yielding_task, start_upon_creation);
+
+ ASSERT_FALSE(coro.started());
+}
+
+/**
* This test is checking if the Coroutine, once it yields
* back to the caller, it is still marked as not finished.
*/