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 #include <math.h> // for sin/cos
272f083884Ss.makeev_local 
SUITE(GroupTests)282f083884Ss.makeev_local SUITE(GroupTests)
292f083884Ss.makeev_local {
302f083884Ss.makeev_local ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
312f083884Ss.makeev_local namespace SimpleWaitFromSubtask
322f083884Ss.makeev_local {
332f083884Ss.makeev_local 	MT::Atomic32<int32> subtaskCount(0);
342f083884Ss.makeev_local 	MT::Atomic32<int32> animTaskCount(0);
352f083884Ss.makeev_local 	MT::Atomic32<int32> physTaskCount(0);
362f083884Ss.makeev_local 
372f083884Ss.makeev_local 
382f083884Ss.makeev_local 	struct DummySubTask
392f083884Ss.makeev_local 	{
40*b23bdf5aSs.makeev_local 		MT_DECLARE_TASK(DummySubTask, MT::StackRequirements::STANDARD, MT::TaskPriority::NORMAL, MT::Color::Blue);
412f083884Ss.makeev_local 
422f083884Ss.makeev_local 		float tempData[64];
432f083884Ss.makeev_local 
442f083884Ss.makeev_local 		void Do(MT::FiberContext& )
452f083884Ss.makeev_local 		{
462f083884Ss.makeev_local 			for (size_t i = 0; i < MT_ARRAY_SIZE(tempData); i++)
472f083884Ss.makeev_local 			{
482f083884Ss.makeev_local 				tempData[i] = cos((float)rand() / RAND_MAX) + sin((float)rand() / RAND_MAX);
492f083884Ss.makeev_local 			}
502f083884Ss.makeev_local 
512f083884Ss.makeev_local 			subtaskCount.IncFetch();
522f083884Ss.makeev_local 		}
532f083884Ss.makeev_local 	};
542f083884Ss.makeev_local 
552f083884Ss.makeev_local 
562f083884Ss.makeev_local 	struct DummyAnimTask
572f083884Ss.makeev_local 	{
58*b23bdf5aSs.makeev_local 		MT_DECLARE_TASK(DummyAnimTask, MT::StackRequirements::STANDARD, MT::TaskPriority::NORMAL, MT::Color::Blue);
592f083884Ss.makeev_local 
602f083884Ss.makeev_local 		float tempData[128];
612f083884Ss.makeev_local 
622f083884Ss.makeev_local 		void Do(MT::FiberContext& ctx)
632f083884Ss.makeev_local 		{
642f083884Ss.makeev_local 			for (size_t i = 0; i < MT_ARRAY_SIZE(tempData); i++)
652f083884Ss.makeev_local 			{
662f083884Ss.makeev_local 				tempData[i] = cos((float)rand() / RAND_MAX);
672f083884Ss.makeev_local 			}
682f083884Ss.makeev_local 
692f083884Ss.makeev_local 			DummySubTask subtasks[16];
709d94a278Ss.makeev_local 			ctx.RunSubtasksAndYield(MT::TaskGroup::Default(), &subtasks[0], MT_ARRAY_SIZE(subtasks));
712f083884Ss.makeev_local 
722f083884Ss.makeev_local 			animTaskCount.IncFetch();
732f083884Ss.makeev_local 		}
742f083884Ss.makeev_local 	};
752f083884Ss.makeev_local 
762f083884Ss.makeev_local 
772f083884Ss.makeev_local 	struct DummyPhysicTask
782f083884Ss.makeev_local 	{
79*b23bdf5aSs.makeev_local 		MT_DECLARE_TASK(DummyPhysicTask, MT::StackRequirements::STANDARD, MT::TaskPriority::NORMAL, MT::Color::Blue);
802f083884Ss.makeev_local 
812f083884Ss.makeev_local 		float tempData[128];
822f083884Ss.makeev_local 
832f083884Ss.makeev_local 		void Do(MT::FiberContext& ctx)
842f083884Ss.makeev_local 		{
852f083884Ss.makeev_local 			for (size_t i = 0; i < MT_ARRAY_SIZE(tempData); i++)
862f083884Ss.makeev_local 			{
872f083884Ss.makeev_local 				tempData[i] = sin((float)rand() / RAND_MAX);
882f083884Ss.makeev_local 			}
892f083884Ss.makeev_local 
902f083884Ss.makeev_local 			DummySubTask subtasks[8];
912f083884Ss.makeev_local 			ctx.RunSubtasksAndYield(MT::TaskGroup::Default(), &subtasks[0], MT_ARRAY_SIZE(subtasks));
922f083884Ss.makeev_local 
932f083884Ss.makeev_local 			physTaskCount.IncFetch();
942f083884Ss.makeev_local 		}
952f083884Ss.makeev_local 	};
962f083884Ss.makeev_local 
972f083884Ss.makeev_local 
982f083884Ss.makeev_local 
992f083884Ss.makeev_local 	TEST(RunGroupTests)
1002f083884Ss.makeev_local 	{
1012f083884Ss.makeev_local 		static uint32 waitTime = 50000;
1022f083884Ss.makeev_local 
1032f083884Ss.makeev_local 		subtaskCount.Store(0);
1042f083884Ss.makeev_local 		animTaskCount.Store(0);
1052f083884Ss.makeev_local 		physTaskCount.Store(0);
1062f083884Ss.makeev_local 
1072f083884Ss.makeev_local 		MT::TaskScheduler scheduler;
1082f083884Ss.makeev_local 
1092f083884Ss.makeev_local 		MT::TaskGroup groupEmpty = scheduler.CreateGroup();
1102f083884Ss.makeev_local 		MT::TaskGroup groupAnim = scheduler.CreateGroup();
1112f083884Ss.makeev_local 
1122f083884Ss.makeev_local 
1132f083884Ss.makeev_local 		bool emptyWaitRes0 = scheduler.WaitGroup(groupEmpty, 200);
1142f083884Ss.makeev_local 		CHECK(emptyWaitRes0 == true);
1152f083884Ss.makeev_local 
1162f083884Ss.makeev_local 		DummyAnimTask dummyAnim[4];
1172f083884Ss.makeev_local 		scheduler.RunAsync(groupAnim, &dummyAnim[0], MT_ARRAY_SIZE(dummyAnim));
1182f083884Ss.makeev_local 
1192f083884Ss.makeev_local 		MT::TaskGroup groupPhysic = scheduler.CreateGroup();
1202f083884Ss.makeev_local 		DummyPhysicTask dummyPhysic[4];
1212f083884Ss.makeev_local 		scheduler.RunAsync(groupPhysic, &dummyPhysic[0], MT_ARRAY_SIZE(dummyPhysic));
1222f083884Ss.makeev_local 
1232f083884Ss.makeev_local 		bool emptyWaitRes1 = scheduler.WaitGroup(groupEmpty, 20);
1242f083884Ss.makeev_local 		CHECK(emptyWaitRes1 == true);
1252f083884Ss.makeev_local 
1262f083884Ss.makeev_local 		CHECK(scheduler.WaitGroup(groupAnim, waitTime));
1272f083884Ss.makeev_local 
1282f083884Ss.makeev_local 		bool emptyWaitRes2 = scheduler.WaitGroup(groupEmpty, 200);
1292f083884Ss.makeev_local 		CHECK(emptyWaitRes2 == true);
1302f083884Ss.makeev_local 
1312f083884Ss.makeev_local 
1322f083884Ss.makeev_local 		CHECK_EQUAL(4, animTaskCount.Load());
1332f083884Ss.makeev_local 		CHECK(subtaskCount.Load() >= 4 * 16);
1342f083884Ss.makeev_local 
1352f083884Ss.makeev_local 
1362f083884Ss.makeev_local 		CHECK(scheduler.WaitGroup(groupPhysic, waitTime));
1372f083884Ss.makeev_local 
1382f083884Ss.makeev_local 		CHECK_EQUAL(4, animTaskCount.Load());
1392f083884Ss.makeev_local 		CHECK_EQUAL(4, physTaskCount.Load());
1402f083884Ss.makeev_local 		CHECK_EQUAL(96, subtaskCount.Load());
1412f083884Ss.makeev_local 	}
1422f083884Ss.makeev_local }
1432f083884Ss.makeev_local ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1442f083884Ss.makeev_local }
1452f083884Ss.makeev_local 
146