113465Sgabeblack@google.com/*
214042Sgiacomo.travaglini@arm.com * Copyright (c) 2019 ARM Limited
314042Sgiacomo.travaglini@arm.com * All rights reserved
414042Sgiacomo.travaglini@arm.com *
514042Sgiacomo.travaglini@arm.com * The license below extends only to copyright in the software and shall
614042Sgiacomo.travaglini@arm.com * not be construed as granting a license to any other intellectual
714042Sgiacomo.travaglini@arm.com * property including but not limited to intellectual property relating
814042Sgiacomo.travaglini@arm.com * to a hardware implementation of the functionality of the software
914042Sgiacomo.travaglini@arm.com * licensed hereunder.  You may use the software subject to the license
1014042Sgiacomo.travaglini@arm.com * terms below provided that you ensure that this notice is replicated
1114042Sgiacomo.travaglini@arm.com * unmodified and in its entirety in all distributions of the software,
1214042Sgiacomo.travaglini@arm.com * modified or unmodified, in source code or in binary form.
1314042Sgiacomo.travaglini@arm.com *
1413465Sgabeblack@google.com * Copyright 2018 Google, Inc.
1513465Sgabeblack@google.com *
1613465Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
1713465Sgabeblack@google.com * modification, are permitted provided that the following conditions are
1813465Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
1913465Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
2013465Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
2113465Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
2213465Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
2313465Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
2413465Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
2513465Sgabeblack@google.com * this software without specific prior written permission.
2613465Sgabeblack@google.com *
2713465Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2813465Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2913465Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3013465Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3113465Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3213465Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3313465Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3413465Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3513465Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3613465Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3713465Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3813465Sgabeblack@google.com *
3913465Sgabeblack@google.com * Authors: Gabe Black
4014042Sgiacomo.travaglini@arm.com *          Giacomo Travaglini
4113465Sgabeblack@google.com */
4213465Sgabeblack@google.com
4313465Sgabeblack@google.com#include <gtest/gtest.h>
4413465Sgabeblack@google.com
4513465Sgabeblack@google.com#include <initializer_list>
4613465Sgabeblack@google.com#include <iostream>
4713465Sgabeblack@google.com#include <vector>
4813465Sgabeblack@google.com
4913465Sgabeblack@google.com#include "base/fiber.hh"
5013465Sgabeblack@google.com
5114042Sgiacomo.travaglini@arm.com/** This test is checking if the "started" member has its expected
5214042Sgiacomo.travaglini@arm.com * value before and after the fiber runs. In the test an empty fiber
5314042Sgiacomo.travaglini@arm.com * is used since we are just interested on the _started member and
5414042Sgiacomo.travaglini@arm.com * nothing more.
5514042Sgiacomo.travaglini@arm.com */
5614042Sgiacomo.travaglini@arm.comTEST(Fiber, Starting)
5714042Sgiacomo.travaglini@arm.com{
5814042Sgiacomo.travaglini@arm.com    class StartingFiber : public Fiber
5914042Sgiacomo.travaglini@arm.com    {
6014042Sgiacomo.travaglini@arm.com      public:
6114042Sgiacomo.travaglini@arm.com        StartingFiber(Fiber *link) : Fiber(link) {}
6214042Sgiacomo.travaglini@arm.com        void main() { /** Do nothing */ }
6314042Sgiacomo.travaglini@arm.com    };
6414042Sgiacomo.travaglini@arm.com
6514042Sgiacomo.travaglini@arm.com    StartingFiber fiber(Fiber::primaryFiber());
6614042Sgiacomo.travaglini@arm.com
6714042Sgiacomo.travaglini@arm.com    ASSERT_FALSE(fiber.started());
6814042Sgiacomo.travaglini@arm.com
6914042Sgiacomo.travaglini@arm.com    fiber.run();
7014042Sgiacomo.travaglini@arm.com
7114042Sgiacomo.travaglini@arm.com    ASSERT_TRUE(fiber.started());
7214042Sgiacomo.travaglini@arm.com}
7314042Sgiacomo.travaglini@arm.com
7414041Sgiacomo.travaglini@arm.comclass SwitchingFiber : public Fiber
7513465Sgabeblack@google.com{
7613465Sgabeblack@google.com  public:
7713465Sgabeblack@google.com    const char *name;
7813465Sgabeblack@google.com    std::vector<Fiber *> next;
7913465Sgabeblack@google.com
8014041Sgiacomo.travaglini@arm.com    SwitchingFiber(const char *name, std::initializer_list<Fiber *> l);
8113465Sgabeblack@google.com
8213465Sgabeblack@google.com    void checkExpected();
8313465Sgabeblack@google.com    void main();
8413465Sgabeblack@google.com};
8513465Sgabeblack@google.com
8614041Sgiacomo.travaglini@arm.comextern SwitchingFiber a;
8714041Sgiacomo.travaglini@arm.comextern SwitchingFiber b;
8814041Sgiacomo.travaglini@arm.comextern SwitchingFiber c;
8913465Sgabeblack@google.com
9014041Sgiacomo.travaglini@arm.comSwitchingFiber a("A", { &b, &a, Fiber::primaryFiber(), &b, &c });
9114041Sgiacomo.travaglini@arm.comSwitchingFiber b("B", { &a, &c });
9214041Sgiacomo.travaglini@arm.comSwitchingFiber c("C", { &a, Fiber::primaryFiber(), Fiber::primaryFiber() });
9313465Sgabeblack@google.com
9414041Sgiacomo.travaglini@arm.comstd::vector<SwitchingFiber *>::iterator expectedIt;
9514041Sgiacomo.travaglini@arm.comstd::vector<SwitchingFiber *> expected({
9613465Sgabeblack@google.com    &a, &b, &a, &a, /* main Fiber, */
9713465Sgabeblack@google.com    &a, &b, &c, &a, &c,
9813465Sgabeblack@google.com    /* main Fiber, */ &c, &c
9913465Sgabeblack@google.com});
10013465Sgabeblack@google.com
10114041Sgiacomo.travaglini@arm.comSwitchingFiber::SwitchingFiber(
10213465Sgabeblack@google.com        const char *name, std::initializer_list<Fiber *> l) :
10313465Sgabeblack@google.com    name(name), next(l)
10413465Sgabeblack@google.com{}
10513465Sgabeblack@google.com
10613465Sgabeblack@google.comvoid
10714041Sgiacomo.travaglini@arm.comSwitchingFiber::checkExpected()
10813465Sgabeblack@google.com{
10913465Sgabeblack@google.com    ASSERT_NE(expectedIt, expected.end());
11014041Sgiacomo.travaglini@arm.com    SwitchingFiber *e = *expectedIt++;
11113465Sgabeblack@google.com    EXPECT_EQ(e, this) << "Expected " << e->name << ", got " << name;
11213465Sgabeblack@google.com}
11313465Sgabeblack@google.com
11413465Sgabeblack@google.comvoid
11514041Sgiacomo.travaglini@arm.comSwitchingFiber::main()
11613465Sgabeblack@google.com{
11713465Sgabeblack@google.com    checkExpected();
11813465Sgabeblack@google.com    for (auto &n : next) {
11913465Sgabeblack@google.com        n->run();
12013465Sgabeblack@google.com        checkExpected();
12113465Sgabeblack@google.com    }
12213465Sgabeblack@google.com}
12313465Sgabeblack@google.com
12413465Sgabeblack@google.comTEST(Fiber, Switching)
12513465Sgabeblack@google.com{
12613465Sgabeblack@google.com    expectedIt = expected.begin();
12713465Sgabeblack@google.com
12813465Sgabeblack@google.com    a.run();
12913465Sgabeblack@google.com    EXPECT_EQ(expectedIt - expected.begin(), 4);
13013465Sgabeblack@google.com
13113465Sgabeblack@google.com    a.run();
13213465Sgabeblack@google.com    EXPECT_EQ(expectedIt - expected.begin(), 9);
13313465Sgabeblack@google.com
13413465Sgabeblack@google.com    c.run();
13513465Sgabeblack@google.com    EXPECT_EQ(expectedIt - expected.begin(), 10);
13613465Sgabeblack@google.com
13713465Sgabeblack@google.com    EXPECT_FALSE(a.finished());
13813465Sgabeblack@google.com    EXPECT_FALSE(b.finished());
13913465Sgabeblack@google.com    EXPECT_FALSE(c.finished());
14013465Sgabeblack@google.com
14113465Sgabeblack@google.com    c.run();
14213465Sgabeblack@google.com    EXPECT_EQ(expected.end(), expectedIt) <<
14313465Sgabeblack@google.com        "Didn't exactly use up the expected Fiber sequence";
14413465Sgabeblack@google.com
14513465Sgabeblack@google.com    EXPECT_TRUE(c.finished());
14613465Sgabeblack@google.com}
14713465Sgabeblack@google.com
14813465Sgabeblack@google.comint currentIndex = 0;
14913465Sgabeblack@google.com
15013465Sgabeblack@google.comclass LinkedFiber : public Fiber
15113465Sgabeblack@google.com{
15213465Sgabeblack@google.com  public:
15313465Sgabeblack@google.com    const int index;
15413465Sgabeblack@google.com    LinkedFiber(Fiber *link, int index) : Fiber(link), index(index) {}
15513465Sgabeblack@google.com
15613465Sgabeblack@google.com    void
15713465Sgabeblack@google.com    main()
15813465Sgabeblack@google.com    {
15913465Sgabeblack@google.com        EXPECT_EQ(currentIndex, index);
16013465Sgabeblack@google.com        currentIndex++;
16113465Sgabeblack@google.com    }
16213465Sgabeblack@google.com};
16313465Sgabeblack@google.com
16413465Sgabeblack@google.comTEST(Fiber, Linked)
16513465Sgabeblack@google.com{
16613465Sgabeblack@google.com    currentIndex = 0;
16713465Sgabeblack@google.com
16813465Sgabeblack@google.com    LinkedFiber lf3(Fiber::primaryFiber(), 3);
16913465Sgabeblack@google.com    LinkedFiber lf2(&lf3, 2);
17013465Sgabeblack@google.com    LinkedFiber lf1(&lf2, 1);
17113465Sgabeblack@google.com    LinkedFiber lf0(&lf1, 0);
17213465Sgabeblack@google.com
17313465Sgabeblack@google.com    lf0.run();
17413465Sgabeblack@google.com
17513465Sgabeblack@google.com    EXPECT_EQ(currentIndex, 4);
17613465Sgabeblack@google.com}
177