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