1*2f083884Ss.makeev_local // The MIT License (MIT) 2*2f083884Ss.makeev_local // 3*2f083884Ss.makeev_local // Copyright (c) 2015 Sergey Makeev, Vadim Slyusarev 4*2f083884Ss.makeev_local // 5*2f083884Ss.makeev_local // Permission is hereby granted, free of charge, to any person obtaining a copy 6*2f083884Ss.makeev_local // of this software and associated documentation files (the "Software"), to deal 7*2f083884Ss.makeev_local // in the Software without restriction, including without limitation the rights 8*2f083884Ss.makeev_local // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9*2f083884Ss.makeev_local // copies of the Software, and to permit persons to whom the Software is 10*2f083884Ss.makeev_local // furnished to do so, subject to the following conditions: 11*2f083884Ss.makeev_local // 12*2f083884Ss.makeev_local // The above copyright notice and this permission notice shall be included in 13*2f083884Ss.makeev_local // all copies or substantial portions of the Software. 14*2f083884Ss.makeev_local // 15*2f083884Ss.makeev_local // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16*2f083884Ss.makeev_local // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17*2f083884Ss.makeev_local // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18*2f083884Ss.makeev_local // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19*2f083884Ss.makeev_local // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20*2f083884Ss.makeev_local // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21*2f083884Ss.makeev_local // THE SOFTWARE. 22*2f083884Ss.makeev_local 23*2f083884Ss.makeev_local #include "Tests.h" 24*2f083884Ss.makeev_local #include <UnitTest++.h> 25*2f083884Ss.makeev_local #include <MTScheduler.h> 26*2f083884Ss.makeev_local #include <math.h> // for sin/cos 27*2f083884Ss.makeev_local 28*2f083884Ss.makeev_local SUITE(GroupTests) 29*2f083884Ss.makeev_local { 30*2f083884Ss.makeev_local //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 31*2f083884Ss.makeev_local namespace SimpleWaitFromSubtask 32*2f083884Ss.makeev_local { 33*2f083884Ss.makeev_local MT::Atomic32<int32> subtaskCount(0); 34*2f083884Ss.makeev_local MT::Atomic32<int32> animTaskCount(0); 35*2f083884Ss.makeev_local MT::Atomic32<int32> physTaskCount(0); 36*2f083884Ss.makeev_local 37*2f083884Ss.makeev_local 38*2f083884Ss.makeev_local struct DummySubTask 39*2f083884Ss.makeev_local { 40*2f083884Ss.makeev_local MT_DECLARE_TASK(DummySubTask, MT::StackRequirements::STANDARD, MT::Color::Blue); 41*2f083884Ss.makeev_local 42*2f083884Ss.makeev_local float tempData[64]; 43*2f083884Ss.makeev_local 44*2f083884Ss.makeev_local void Do(MT::FiberContext& ) 45*2f083884Ss.makeev_local { 46*2f083884Ss.makeev_local for (size_t i = 0; i < MT_ARRAY_SIZE(tempData); i++) 47*2f083884Ss.makeev_local { 48*2f083884Ss.makeev_local tempData[i] = cos((float)rand() / RAND_MAX) + sin((float)rand() / RAND_MAX); 49*2f083884Ss.makeev_local } 50*2f083884Ss.makeev_local 51*2f083884Ss.makeev_local subtaskCount.IncFetch(); 52*2f083884Ss.makeev_local } 53*2f083884Ss.makeev_local }; 54*2f083884Ss.makeev_local 55*2f083884Ss.makeev_local 56*2f083884Ss.makeev_local struct DummyAnimTask 57*2f083884Ss.makeev_local { 58*2f083884Ss.makeev_local MT_DECLARE_TASK(DummyAnimTask, MT::StackRequirements::STANDARD, MT::Color::Blue); 59*2f083884Ss.makeev_local 60*2f083884Ss.makeev_local float tempData[128]; 61*2f083884Ss.makeev_local 62*2f083884Ss.makeev_local void Do(MT::FiberContext& ctx) 63*2f083884Ss.makeev_local { 64*2f083884Ss.makeev_local for (size_t i = 0; i < MT_ARRAY_SIZE(tempData); i++) 65*2f083884Ss.makeev_local { 66*2f083884Ss.makeev_local tempData[i] = cos((float)rand() / RAND_MAX); 67*2f083884Ss.makeev_local } 68*2f083884Ss.makeev_local 69*2f083884Ss.makeev_local DummySubTask subtasks[16]; 70*2f083884Ss.makeev_local ctx.RunAsync(MT::TaskGroup::Default(), &subtasks[0], MT_ARRAY_SIZE(subtasks)); 71*2f083884Ss.makeev_local ctx.WaitGroupAndYield(MT::TaskGroup::Default()); 72*2f083884Ss.makeev_local 73*2f083884Ss.makeev_local animTaskCount.IncFetch(); 74*2f083884Ss.makeev_local } 75*2f083884Ss.makeev_local }; 76*2f083884Ss.makeev_local 77*2f083884Ss.makeev_local 78*2f083884Ss.makeev_local struct DummyPhysicTask 79*2f083884Ss.makeev_local { 80*2f083884Ss.makeev_local MT_DECLARE_TASK(DummyPhysicTask, MT::StackRequirements::STANDARD, MT::Color::Blue); 81*2f083884Ss.makeev_local 82*2f083884Ss.makeev_local float tempData[128]; 83*2f083884Ss.makeev_local 84*2f083884Ss.makeev_local void Do(MT::FiberContext& ctx) 85*2f083884Ss.makeev_local { 86*2f083884Ss.makeev_local for (size_t i = 0; i < MT_ARRAY_SIZE(tempData); i++) 87*2f083884Ss.makeev_local { 88*2f083884Ss.makeev_local tempData[i] = sin((float)rand() / RAND_MAX); 89*2f083884Ss.makeev_local } 90*2f083884Ss.makeev_local 91*2f083884Ss.makeev_local DummySubTask subtasks[8]; 92*2f083884Ss.makeev_local ctx.RunSubtasksAndYield(MT::TaskGroup::Default(), &subtasks[0], MT_ARRAY_SIZE(subtasks)); 93*2f083884Ss.makeev_local 94*2f083884Ss.makeev_local physTaskCount.IncFetch(); 95*2f083884Ss.makeev_local } 96*2f083884Ss.makeev_local }; 97*2f083884Ss.makeev_local 98*2f083884Ss.makeev_local 99*2f083884Ss.makeev_local 100*2f083884Ss.makeev_local TEST(RunGroupTests) 101*2f083884Ss.makeev_local { 102*2f083884Ss.makeev_local static uint32 waitTime = 50000; 103*2f083884Ss.makeev_local 104*2f083884Ss.makeev_local subtaskCount.Store(0); 105*2f083884Ss.makeev_local animTaskCount.Store(0); 106*2f083884Ss.makeev_local physTaskCount.Store(0); 107*2f083884Ss.makeev_local 108*2f083884Ss.makeev_local MT::TaskScheduler scheduler; 109*2f083884Ss.makeev_local 110*2f083884Ss.makeev_local MT::TaskGroup groupEmpty = scheduler.CreateGroup(); 111*2f083884Ss.makeev_local MT::TaskGroup groupAnim = scheduler.CreateGroup(); 112*2f083884Ss.makeev_local 113*2f083884Ss.makeev_local 114*2f083884Ss.makeev_local bool emptyWaitRes0 = scheduler.WaitGroup(groupEmpty, 200); 115*2f083884Ss.makeev_local CHECK(emptyWaitRes0 == true); 116*2f083884Ss.makeev_local 117*2f083884Ss.makeev_local DummyAnimTask dummyAnim[4]; 118*2f083884Ss.makeev_local scheduler.RunAsync(groupAnim, &dummyAnim[0], MT_ARRAY_SIZE(dummyAnim)); 119*2f083884Ss.makeev_local 120*2f083884Ss.makeev_local MT::TaskGroup groupPhysic = scheduler.CreateGroup(); 121*2f083884Ss.makeev_local DummyPhysicTask dummyPhysic[4]; 122*2f083884Ss.makeev_local scheduler.RunAsync(groupPhysic, &dummyPhysic[0], MT_ARRAY_SIZE(dummyPhysic)); 123*2f083884Ss.makeev_local 124*2f083884Ss.makeev_local bool emptyWaitRes1 = scheduler.WaitGroup(groupEmpty, 20); 125*2f083884Ss.makeev_local CHECK(emptyWaitRes1 == true); 126*2f083884Ss.makeev_local 127*2f083884Ss.makeev_local CHECK(scheduler.WaitGroup(groupAnim, waitTime)); 128*2f083884Ss.makeev_local 129*2f083884Ss.makeev_local bool emptyWaitRes2 = scheduler.WaitGroup(groupEmpty, 200); 130*2f083884Ss.makeev_local CHECK(emptyWaitRes2 == true); 131*2f083884Ss.makeev_local 132*2f083884Ss.makeev_local 133*2f083884Ss.makeev_local CHECK_EQUAL(4, animTaskCount.Load()); 134*2f083884Ss.makeev_local CHECK(subtaskCount.Load() >= 4 * 16); 135*2f083884Ss.makeev_local 136*2f083884Ss.makeev_local 137*2f083884Ss.makeev_local CHECK(scheduler.WaitGroup(groupPhysic, waitTime)); 138*2f083884Ss.makeev_local 139*2f083884Ss.makeev_local CHECK_EQUAL(4, animTaskCount.Load()); 140*2f083884Ss.makeev_local CHECK_EQUAL(4, physTaskCount.Load()); 141*2f083884Ss.makeev_local CHECK_EQUAL(96, subtaskCount.Load()); 142*2f083884Ss.makeev_local } 143*2f083884Ss.makeev_local } 144*2f083884Ss.makeev_local //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 145*2f083884Ss.makeev_local } 146*2f083884Ss.makeev_local 147