xref: /aosp_15_r20/external/swiftshader/third_party/marl/src/osfiber_test.cpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1 // Copyright 2019 The Marl Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "osfiber.h"
16 
17 #include "marl_test.h"
18 
19 namespace {
20 
21 // A custom, small stack size for the fibers in these tests.
22 // Note: Stack sizes less than 16KB may cause issues on some platforms.
23 // See: https://github.com/google/marl/issues/201
24 constexpr size_t fiberStackSize = 16 * 1024;
25 
26 }  // anonymous namespace
27 
TEST_F(WithoutBoundScheduler,OSFiber)28 TEST_F(WithoutBoundScheduler, OSFiber) {
29   std::string str;
30   auto main = marl::OSFiber::createFiberFromCurrentThread(allocator);
31   marl::Allocator::unique_ptr<marl::OSFiber> fiberA, fiberB, fiberC;
32   fiberC = marl::OSFiber::createFiber(allocator, fiberStackSize, [&] {
33     str += "C";
34     fiberC->switchTo(fiberB.get());
35   });
36   fiberB = marl::OSFiber::createFiber(allocator, fiberStackSize, [&] {
37     str += "B";
38     fiberB->switchTo(fiberA.get());
39   });
40   fiberA = marl::OSFiber::createFiber(allocator, fiberStackSize, [&] {
41     str += "A";
42     fiberA->switchTo(main.get());
43   });
44 
45   main->switchTo(fiberC.get());
46 
47   ASSERT_EQ(str, "CBA");
48 }
49 
TEST_F(WithoutBoundScheduler,StackAlignment)50 TEST_F(WithoutBoundScheduler, StackAlignment) {
51   uintptr_t address = 0;
52 
53   struct alignas(16) AlignTo16Bytes {
54     uint64_t a, b;
55   };
56 
57   auto main = marl::OSFiber::createFiberFromCurrentThread(allocator);
58   marl::Allocator::unique_ptr<marl::OSFiber> fiber;
59   fiber = marl::OSFiber::createFiber(allocator, fiberStackSize, [&] {
60     AlignTo16Bytes stack_var;
61 
62     address = reinterpret_cast<uintptr_t>(&stack_var);
63 
64     fiber->switchTo(main.get());
65   });
66 
67   main->switchTo(fiber.get());
68 
69   ASSERT_TRUE((address & 15) == 0)
70       << "Stack variable had unaligned address: 0x" << std::hex << address;
71 }
72