diff options
author | Michiel W. van Tol <Michiel.VanTol@arm.com> | 2018-08-31 12:50:20 +0100 |
---|---|---|
committer | Giacomo Travaglini <giacomo.travaglini@arm.com> | 2019-06-28 08:25:20 +0000 |
commit | 08e7849f2710e6b62aa07db86e356edb15a99f9c (patch) | |
tree | 0c8a11a85ad57db68198072b89519e403a1168c9 | |
parent | cb2be9940a055bf73647e9eef3779992d5af36b7 (diff) | |
download | gem5-08e7849f2710e6b62aa07db86e356edb15a99f9c.tar.xz |
base: Add argument to Coroutine class to not run on creation
In some cases, the point where you create a Coroutine is not the same as
where you want to start running it (and want it to switch back to). This
leads to the unnecessary overhead of switching in and out of the
Coroutine. This change adds an optional boolean argument to the
constructor for the Coroutine class to allow for overriding the default
behavior of running the Coroutine upon creation, which in specific cases
can be used to avoid the unnecessary overhead and improve simulator
performance.
Change-Id: I044698f85e81ee4144208aee30d133bcb462d35d
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/18588
Reviewed-by: Anthony Gutierrez <anthony.gutierrez@amd.com>
Maintainer: Anthony Gutierrez <anthony.gutierrez@amd.com>
Tested-by: kokoro <noreply+kokoro@google.com>
-rw-r--r-- | src/base/coroutine.hh | 13 | ||||
-rw-r--r-- | src/base/coroutine.test.cc | 19 |
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. */ |