gem5 v24.0.0.0
Loading...
Searching...
No Matches
coroutine.test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#include <gtest/gtest.h>
39
40#include "base/coroutine.hh"
41
42using namespace gem5;
43
49TEST(Coroutine, Unstarted)
50{
51 auto yielding_task =
53 {
54 yield();
55 };
56
57 const bool start_upon_creation = false;
58 Coroutine<void, void> coro(yielding_task, start_upon_creation);
59
60 ASSERT_FALSE(coro.started());
61}
62
67TEST(Coroutine, Unfinished)
68{
69 auto yielding_task =
71 {
72 yield();
73 };
74
75 Coroutine<void, void> coro(yielding_task);
76 ASSERT_TRUE(coro);
77}
78
85TEST(Coroutine, Passing)
86{
87 const std::vector<int> input{ 1, 2, 3 };
88 const std::vector<int> expected_values = input;
89
90 auto passing_task =
91 [&expected_values] (Coroutine<int, void>::CallerType& yield)
92 {
93 int argument;
94
95 for (const auto expected : expected_values) {
96 argument = yield.get();
97 ASSERT_EQ(argument, expected);
98 }
99 };
100
101 Coroutine<int, void> coro(passing_task);
102 ASSERT_TRUE(coro);
103
104 for (const auto val : input) {
105 coro(val);
106 }
107}
108
115TEST(Coroutine, Returning)
116{
117 const std::vector<int> output{ 1, 2, 3 };
118 const std::vector<int> expected_values = output;
119
120 auto returning_task =
122 {
123 for (const auto ret : output) {
124 yield(ret);
125 }
126 };
127
128 Coroutine<void, int> coro(returning_task);
129 ASSERT_TRUE(coro);
130
131 for (const auto expected : expected_values) {
132 int returned = coro.get();
133 ASSERT_EQ(returned, expected);
134 }
135}
136
144TEST(Coroutine, Fibonacci)
145{
146 const std::vector<int> expected_values{
147 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233 };
148
149 const int steps = expected_values.size();
150
151 auto fibonacci_task =
152 [steps] (Coroutine<void, int>::CallerType& yield)
153 {
154 int prev = 0;
155 int current = 1;
156
157 for (auto iter = 0; iter < steps; iter++) {
158 int sum = prev + current;
159 yield(sum);
160
161 prev = current;
162 current = sum;
163 }
164 };
165
166 Coroutine<void, int> coro(fibonacci_task);
167 ASSERT_TRUE(coro);
168
169 for (const auto expected : expected_values) {
170 ASSERT_TRUE(coro);
171 int returned = coro.get();
172 ASSERT_EQ(returned, expected);
173 }
174}
175
185TEST(Coroutine, Cooperative)
186{
187 const std::string caller_str("HloWrd");
188 const std::string coro_str("el ol!");
189 const std::string expected("Hello World!");
190
191 auto cooperative_task =
193 {
194 for (auto& appended_c : coro_str) {
195 auto old_str = yield.get();
196 yield(old_str + appended_c);
197 }
198 };
199
200 Coroutine<std::string, std::string> coro(cooperative_task);
201
202 std::string result;
203 for (auto& c : caller_str) {
204 ASSERT_TRUE(coro);
205 result += c;
206 result = coro(result).get();
207 }
208
209 ASSERT_EQ(result, expected);
210}
211
219{
220 const std::string wrong("Inner");
221 const std::string expected("Inner + Outer");
222
223 auto inner_task =
225 {
226 std::string inner_string("Inner");
227 yield(inner_string);
228 };
229
230 auto outer_task =
231 [&inner_task] (Coroutine<void, std::string>::CallerType& yield)
232 {
233 Coroutine<void, std::string> coro(inner_task);
234 std::string inner_string = coro.get();
235
236 std::string outer_string("Outer");
237 yield(inner_string + " + " + outer_string);
238 };
239
240
241 Coroutine<void, std::string> coro(outer_task);
242 ASSERT_TRUE(coro);
243
244 std::string result = coro.get();
245
246 ASSERT_NE(result, wrong);
247 ASSERT_EQ(result, expected);
248}
249
259TEST(Coroutine, TwoCallers)
260{
261 bool valid_return = false;
262
263 Coroutine<void, void> callee{[]
265 {
266 yield();
267 yield();
268 }};
269
270 Coroutine<void, void> other_caller{[&callee, &valid_return]
272 {
273 callee();
274 valid_return = true;
275 yield();
276 }};
277
278 ASSERT_TRUE(valid_return);
279}
CallerType: A reference to an object of this class will be passed to the coroutine task.
Definition coroutine.hh:85
This template defines a Coroutine wrapper type with a Boost-like interface.
Definition coroutine.hh:64
STL vector class.
Definition stl.hh:37
TEST(Coroutine, Unstarted)
This test is checking if the Coroutine, once it's created it doesn't start since the second argument ...
std::vector< SwitchingFiber * > expected({ &a, &b, &a, &a, &a, &b, &c, &a, &c, &c, &c })
std::enable_if_t<!std::is_same_v< T, void >, T > get()
get() is the way we can extrapolate return values (yielded) from the coroutine.
Definition coroutine.hh:249
bool started() const
Returns whether the "main" function of this fiber has started.
Definition fiber.hh:116
Bitfield< 29 > c
Definition misc_types.hh:53
Bitfield< 18 > sum
Definition misc.hh:1198
Bitfield< 63 > val
Definition misc.hh:804
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
static void output(const char *filename)
Definition debug.cc:60

Generated on Tue Jun 18 2024 16:24:00 for gem5 by doxygen 1.11.0