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