fiber.test.cc revision 13465:dee578a46d87
111986Sandreas.sandberg@arm.com/*
211986Sandreas.sandberg@arm.com * Copyright 2018 Google, Inc.
311986Sandreas.sandberg@arm.com *
411986Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without
511986Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are
611986Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright
711986Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer;
811986Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright
911986Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the
1011986Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution;
1111986Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its
1211986Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from
1312037Sandreas.sandberg@arm.com * this software without specific prior written permission.
1411986Sandreas.sandberg@arm.com *
1511986Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1611986Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1711986Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1811986Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1911986Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2011986Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2111986Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2211986Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2311986Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2411986Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2511986Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2611986Sandreas.sandberg@arm.com *
2711986Sandreas.sandberg@arm.com * Authors: Gabe Black
2811986Sandreas.sandberg@arm.com */
2911986Sandreas.sandberg@arm.com
3011986Sandreas.sandberg@arm.com#include <gtest/gtest.h>
3111986Sandreas.sandberg@arm.com
3211986Sandreas.sandberg@arm.com#include <initializer_list>
3311986Sandreas.sandberg@arm.com#include <iostream>
3411986Sandreas.sandberg@arm.com#include <vector>
3511986Sandreas.sandberg@arm.com
3611986Sandreas.sandberg@arm.com#include "base/fiber.hh"
3711986Sandreas.sandberg@arm.com
3811986Sandreas.sandberg@arm.comclass TestFiber : public Fiber
3911986Sandreas.sandberg@arm.com{
4011986Sandreas.sandberg@arm.com  public:
4111986Sandreas.sandberg@arm.com    const char *name;
4211986Sandreas.sandberg@arm.com    std::vector<Fiber *> next;
4311986Sandreas.sandberg@arm.com
4411986Sandreas.sandberg@arm.com    TestFiber(const char *name, std::initializer_list<Fiber *> l);
4511986Sandreas.sandberg@arm.com
4611986Sandreas.sandberg@arm.com    void checkExpected();
4711986Sandreas.sandberg@arm.com    void main();
4811986Sandreas.sandberg@arm.com};
4911986Sandreas.sandberg@arm.com
5011986Sandreas.sandberg@arm.comextern TestFiber a;
5111986Sandreas.sandberg@arm.comextern TestFiber b;
5211986Sandreas.sandberg@arm.comextern TestFiber c;
5311986Sandreas.sandberg@arm.com
5411986Sandreas.sandberg@arm.comTestFiber a("A", { &b, &a, Fiber::primaryFiber(), &b, &c });
5511986Sandreas.sandberg@arm.comTestFiber b("B", { &a, &c });
5611986Sandreas.sandberg@arm.comTestFiber c("C", { &a, Fiber::primaryFiber(), Fiber::primaryFiber() });
5712391Sjason@lowepower.com
5812391Sjason@lowepower.comstd::vector<TestFiber *>::iterator expectedIt;
5912391Sjason@lowepower.comstd::vector<TestFiber *> expected({
6012037Sandreas.sandberg@arm.com    &a, &b, &a, &a, /* main Fiber, */
6112391Sjason@lowepower.com    &a, &b, &c, &a, &c,
6211986Sandreas.sandberg@arm.com    /* main Fiber, */ &c, &c
6311986Sandreas.sandberg@arm.com});
6411986Sandreas.sandberg@arm.com
6511986Sandreas.sandberg@arm.comTestFiber::TestFiber(
6611986Sandreas.sandberg@arm.com        const char *name, std::initializer_list<Fiber *> l) :
6712391Sjason@lowepower.com    name(name), next(l)
6812391Sjason@lowepower.com{}
6912391Sjason@lowepower.com
7012391Sjason@lowepower.comvoid
7112391Sjason@lowepower.comTestFiber::checkExpected()
7212391Sjason@lowepower.com{
7312391Sjason@lowepower.com    ASSERT_NE(expectedIt, expected.end());
7412391Sjason@lowepower.com    TestFiber *e = *expectedIt++;
7512391Sjason@lowepower.com    EXPECT_EQ(e, this) << "Expected " << e->name << ", got " << name;
7612391Sjason@lowepower.com}
7712391Sjason@lowepower.com
7812391Sjason@lowepower.comvoid
7912391Sjason@lowepower.comTestFiber::main()
8012391Sjason@lowepower.com{
8112391Sjason@lowepower.com    checkExpected();
8212391Sjason@lowepower.com    for (auto &n : next) {
8312391Sjason@lowepower.com        n->run();
8412391Sjason@lowepower.com        checkExpected();
8512391Sjason@lowepower.com    }
8612391Sjason@lowepower.com}
8712391Sjason@lowepower.com
8812391Sjason@lowepower.comTEST(Fiber, Switching)
8912391Sjason@lowepower.com{
9012391Sjason@lowepower.com    expectedIt = expected.begin();
9112391Sjason@lowepower.com
9212391Sjason@lowepower.com    a.run();
9312037Sandreas.sandberg@arm.com    EXPECT_EQ(expectedIt - expected.begin(), 4);
9412037Sandreas.sandberg@arm.com
9512037Sandreas.sandberg@arm.com    a.run();
9612037Sandreas.sandberg@arm.com    EXPECT_EQ(expectedIt - expected.begin(), 9);
9712391Sjason@lowepower.com
9812391Sjason@lowepower.com    c.run();
9912391Sjason@lowepower.com    EXPECT_EQ(expectedIt - expected.begin(), 10);
10012391Sjason@lowepower.com
10112391Sjason@lowepower.com    EXPECT_FALSE(a.finished());
10212391Sjason@lowepower.com    EXPECT_FALSE(b.finished());
10312037Sandreas.sandberg@arm.com    EXPECT_FALSE(c.finished());
10412037Sandreas.sandberg@arm.com
10512037Sandreas.sandberg@arm.com    c.run();
10612037Sandreas.sandberg@arm.com    EXPECT_EQ(expected.end(), expectedIt) <<
10712391Sjason@lowepower.com        "Didn't exactly use up the expected Fiber sequence";
108
109    EXPECT_TRUE(c.finished());
110}
111
112int currentIndex = 0;
113
114class LinkedFiber : public Fiber
115{
116  public:
117    const int index;
118    LinkedFiber(Fiber *link, int index) : Fiber(link), index(index) {}
119
120    void
121    main()
122    {
123        EXPECT_EQ(currentIndex, index);
124        currentIndex++;
125    }
126};
127
128TEST(Fiber, Linked)
129{
130    currentIndex = 0;
131
132    LinkedFiber lf3(Fiber::primaryFiber(), 3);
133    LinkedFiber lf2(&lf3, 2);
134    LinkedFiber lf1(&lf2, 1);
135    LinkedFiber lf0(&lf1, 0);
136
137    lf0.run();
138
139    EXPECT_EQ(currentIndex, 4);
140}
141