12f083884Ss.makeev_local // The MIT License (MIT)
22f083884Ss.makeev_local //
32f083884Ss.makeev_local // Copyright (c) 2015 Sergey Makeev, Vadim Slyusarev
42f083884Ss.makeev_local //
52f083884Ss.makeev_local // Permission is hereby granted, free of charge, to any person obtaining a copy
62f083884Ss.makeev_local // of this software and associated documentation files (the "Software"), to deal
72f083884Ss.makeev_local // in the Software without restriction, including without limitation the rights
82f083884Ss.makeev_local // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
92f083884Ss.makeev_local // copies of the Software, and to permit persons to whom the Software is
102f083884Ss.makeev_local // furnished to do so, subject to the following conditions:
112f083884Ss.makeev_local //
122f083884Ss.makeev_local // The above copyright notice and this permission notice shall be included in
132f083884Ss.makeev_local // all copies or substantial portions of the Software.
142f083884Ss.makeev_local //
152f083884Ss.makeev_local // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
162f083884Ss.makeev_local // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
172f083884Ss.makeev_local // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
182f083884Ss.makeev_local // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
192f083884Ss.makeev_local // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
202f083884Ss.makeev_local // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
212f083884Ss.makeev_local // THE SOFTWARE.
222f083884Ss.makeev_local
232f083884Ss.makeev_local #include "Tests.h"
242f083884Ss.makeev_local #include <UnitTest++.h>
252f083884Ss.makeev_local #include <MTScheduler.h>
262f083884Ss.makeev_local
272f083884Ss.makeev_local #ifdef MT_THREAD_SANITIZER
282f083884Ss.makeev_local #define SMALLEST_STACK_SIZE (566656)
292f083884Ss.makeev_local #else
302f083884Ss.makeev_local #define SMALLEST_STACK_SIZE (32768)
312f083884Ss.makeev_local #endif
322f083884Ss.makeev_local
336e90b535Ss.makeev_local int64 startTime = 0;
346e90b535Ss.makeev_local int64 endTime = 0;
356e90b535Ss.makeev_local
362f083884Ss.makeev_local
SUITE(FiberTests)372f083884Ss.makeev_local SUITE(FiberTests)
382f083884Ss.makeev_local {
392f083884Ss.makeev_local MT::Atomic32<int32> counter(0);
402f083884Ss.makeev_local MT::Fiber* fiberMain = nullptr;
412f083884Ss.makeev_local
422f083884Ss.makeev_local void FiberFunc( void* userData )
432f083884Ss.makeev_local {
442f083884Ss.makeev_local CHECK_EQUAL(0, counter.Load());
452f083884Ss.makeev_local counter.IncFetch();
462f083884Ss.makeev_local
472f083884Ss.makeev_local MT::Fiber* currentFiber = (MT::Fiber*)userData;
482f083884Ss.makeev_local MT::Fiber::SwitchTo(*currentFiber, *fiberMain);
492f083884Ss.makeev_local
502f083884Ss.makeev_local CHECK_EQUAL(2, counter.Load());
512f083884Ss.makeev_local counter.IncFetch();
522f083884Ss.makeev_local
532f083884Ss.makeev_local MT::Fiber::SwitchTo(*currentFiber, *fiberMain);
542f083884Ss.makeev_local }
552f083884Ss.makeev_local
562f083884Ss.makeev_local void FiberMain(void* userData)
572f083884Ss.makeev_local {
586e90b535Ss.makeev_local endTime = MT::GetTimeMicroSeconds();
596e90b535Ss.makeev_local uint32 microsecondsFromThreadToFiber = (uint32)(endTime - startTime);
606e90b535Ss.makeev_local printf("%d us to convert from thread to fiber\n", microsecondsFromThreadToFiber);
616e90b535Ss.makeev_local
622f083884Ss.makeev_local MT_UNUSED(userData);
632f083884Ss.makeev_local
642f083884Ss.makeev_local MT::Fiber fiber1;
652f083884Ss.makeev_local
662f083884Ss.makeev_local fiber1.Create(SMALLEST_STACK_SIZE, FiberFunc, &fiber1);
672f083884Ss.makeev_local
682f083884Ss.makeev_local MT::Fiber::SwitchTo(*fiberMain, fiber1);
692f083884Ss.makeev_local
702f083884Ss.makeev_local CHECK_EQUAL(1, counter.Load());
712f083884Ss.makeev_local counter.IncFetch();
722f083884Ss.makeev_local
732f083884Ss.makeev_local MT::Fiber::SwitchTo(*fiberMain, fiber1);
742f083884Ss.makeev_local
752f083884Ss.makeev_local CHECK_EQUAL(3, counter.Load());
762f083884Ss.makeev_local
772f083884Ss.makeev_local fiberMain = nullptr;
78*5786033aSSergey Makeev
79*5786033aSSergey Makeev printf("FiberMain - done\n");
802f083884Ss.makeev_local }
812f083884Ss.makeev_local
822f083884Ss.makeev_local
832f083884Ss.makeev_local
842f083884Ss.makeev_local TEST(FiberSimpleTest)
852f083884Ss.makeev_local {
863d930776Ss.makeev_local // Two fibers from same thread
873d930776Ss.makeev_local MT::Fiber fiber1;
883d930776Ss.makeev_local fiberMain = &fiber1;
89ae5bbefbSs.makeev_local counter.Store(0);
903d930776Ss.makeev_local startTime = MT::GetTimeMicroSeconds();
913d930776Ss.makeev_local fiberMain->CreateFromCurrentThreadAndRun(FiberMain, nullptr);
92ae5bbefbSs.makeev_local
933d930776Ss.makeev_local // CreateFromCurrentThreadAndRun from same fiber called twice for same fiber
943d930776Ss.makeev_local fiberMain = &fiber1;
953d930776Ss.makeev_local counter.Store(0);
963d930776Ss.makeev_local startTime = MT::GetTimeMicroSeconds();
973d930776Ss.makeev_local fiberMain->CreateFromCurrentThreadAndRun(FiberMain, nullptr);
983d930776Ss.makeev_local
993d930776Ss.makeev_local
1003d930776Ss.makeev_local MT::Fiber fiber2;
1013d930776Ss.makeev_local fiberMain = &fiber2;
1023d930776Ss.makeev_local counter.Store(0);
1036e90b535Ss.makeev_local startTime = MT::GetTimeMicroSeconds();
104ae5bbefbSs.makeev_local fiberMain->CreateFromCurrentThreadAndRun(FiberMain, nullptr);
105*5786033aSSergey Makeev
106*5786033aSSergey Makeev printf("Fiber test done\n");
1072f083884Ss.makeev_local }
1082f083884Ss.makeev_local ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1092f083884Ss.makeev_local }
110