1*58964d0bSSergey Makeev #include <MTScheduler.h>
2*58964d0bSSergey Makeev 
3*58964d0bSSergey Makeev namespace MT
4*58964d0bSSergey Makeev {
5*58964d0bSSergey Makeev 	namespace internal
6*58964d0bSSergey Makeev 	{
7*58964d0bSSergey Makeev 		static const size_t TASK_BUFFER_CAPACITY = 4096;
8*58964d0bSSergey Makeev 
9*58964d0bSSergey Makeev 		ThreadContext::ThreadContext()
10*58964d0bSSergey Makeev 			: lastActiveFiberContext(nullptr)
11*58964d0bSSergey Makeev 			, taskScheduler(nullptr)
12*58964d0bSSergey Makeev 			, hasNewTasksEvent(EventReset::AUTOMATIC, true)
13*58964d0bSSergey Makeev 			, state(ThreadState::ALIVE)
14*58964d0bSSergey Makeev 			, descBuffer(TASK_BUFFER_CAPACITY)
15*58964d0bSSergey Makeev 		{
16*58964d0bSSergey Makeev 		}
17*58964d0bSSergey Makeev 
18*58964d0bSSergey Makeev 		ThreadContext::~ThreadContext()
19*58964d0bSSergey Makeev 		{
20*58964d0bSSergey Makeev 		}
21*58964d0bSSergey Makeev 
22*58964d0bSSergey Makeev 		void ThreadContext::RestoreAwaitingTasks(TaskGroup::Type taskGroup)
23*58964d0bSSergey Makeev 		{
24*58964d0bSSergey Makeev 			ASSERT(taskScheduler, "Invalid Task Scheduler");
25*58964d0bSSergey Makeev 			ASSERT(taskScheduler->IsWorkerThread(), "Can't use RunAsync outside Task. Use TaskScheduler.RunAsync() instead.");
26*58964d0bSSergey Makeev 
27*58964d0bSSergey Makeev 			ConcurrentQueueLIFO<FiberContext*> & groupQueue = taskScheduler->waitTaskQueues[taskGroup];
28*58964d0bSSergey Makeev 
29*58964d0bSSergey Makeev 			if (groupQueue.IsEmpty())
30*58964d0bSSergey Makeev 			{
31*58964d0bSSergey Makeev 				return;
32*58964d0bSSergey Makeev 			}
33*58964d0bSSergey Makeev 
34*58964d0bSSergey Makeev 			//copy awaiting tasks list to stack
35*58964d0bSSergey Makeev 			stack_array<FiberContext*, MT_MAX_FIBERS_COUNT> groupQueueCopy(MT_MAX_FIBERS_COUNT, nullptr);
36*58964d0bSSergey Makeev 			size_t taskCount = groupQueue.PopAll(groupQueueCopy.begin(), groupQueueCopy.size());
37*58964d0bSSergey Makeev 
38*58964d0bSSergey Makeev 			fixed_array<internal::GroupedTask> buffer(&descBuffer.front(), taskCount);
39*58964d0bSSergey Makeev 
40*58964d0bSSergey Makeev 			TaskScheduler & scheduler = *(taskScheduler);
41*58964d0bSSergey Makeev 			size_t bucketCount = Min((size_t)scheduler.GetWorkerCount(), taskCount);
42*58964d0bSSergey Makeev 			fixed_array<internal::TaskBucket>	buckets(ALLOCATE_ON_STACK(internal::TaskBucket, bucketCount), bucketCount);
43*58964d0bSSergey Makeev 
44*58964d0bSSergey Makeev 			scheduler.DistibuteDescriptions(TaskGroup::GROUP_UNDEFINED, groupQueueCopy.begin(), buffer, buckets);
45*58964d0bSSergey Makeev 			scheduler.RunTasksImpl(buckets, nullptr, true);
46*58964d0bSSergey Makeev 		}
47*58964d0bSSergey Makeev 
48*58964d0bSSergey Makeev 	}
49*58964d0bSSergey Makeev 
50*58964d0bSSergey Makeev }
51