1 #pragma once
2 
3 #include <MTTools.h>
4 #include <MTPlatform.h>
5 #include <MTConcurrentQueueLIFO.h>
6 #include <MTStackArray.h>
7 #include <MTFixedArray.h>
8 #include <MTThreadContext.h>
9 #include <MTFiberContext.h>
10 #include <MTTaskBase.h>
11 
12 namespace MT
13 {
14 	const uint32 MT_MAX_THREAD_COUNT = 32;
15 	const uint32 MT_MAX_FIBERS_COUNT = 128;
16 	const uint32 MT_SCHEDULER_STACK_SIZE = 131072;
17 	const uint32 MT_FIBER_STACK_SIZE = 32768;
18 
19 	namespace internal
20 	{
21 		struct ThreadContext;
22 	}
23 
24 	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
25 	// Task scheduler
26 	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
27 	class TaskScheduler
28 	{
29 		friend class FiberContext;
30 		friend struct internal::ThreadContext;
31 
32 		struct GroupStats
33 		{
34 			AtomicInt inProgressTaskCount;
35 			Event allDoneEvent;
36 
37 			GroupStats()
38 			{
39 				inProgressTaskCount.Set(0);
40 				allDoneEvent.Create( EventReset::MANUAL, true );
41 			}
42 		};
43 
44 		// Thread index for new task
45 		AtomicInt roundRobinThreadIndex;
46 
47 		// Threads created by task manager
48 		uint32 threadsCount;
49 		internal::ThreadContext threadContext[MT_MAX_THREAD_COUNT];
50 
51 		// Per group task statistic
52 		GroupStats groupStats[TaskGroup::COUNT];
53 
54 		// All groups task statistic
55 		GroupStats allGroupStats;
56 
57 
58 		//Task awaiting group through FiberContext::WaitGroupAndYield call
59 		ConcurrentQueueLIFO<FiberContext*> waitTaskQueues[TaskGroup::COUNT];
60 
61 
62 		// Fibers pool
63 		ConcurrentQueueLIFO<FiberContext*> availableFibers;
64 
65 		// Fibers context
66 		FiberContext fiberContext[MT_MAX_FIBERS_COUNT];
67 
68 		FiberContext* RequestFiberContext(internal::GroupedTask& task);
69 		void ReleaseFiberContext(FiberContext* fiberExecutionContext);
70 
71 		void RunTasksImpl(fixed_array<internal::TaskBucket>& buckets, FiberContext * parentFiber, bool restoredFromAwaitState);
72 
73 		static void ThreadMain( void* userData );
74 		static void FiberMain( void* userData );
75 		static FiberContext* ExecuteTask (internal::ThreadContext& threadContext, FiberContext* fiberContext);
76 
77 	public:
78 
79 		TaskScheduler();
80 		~TaskScheduler();
81 
82 		template<class TTask>
83 		void RunAsync(TaskGroup::Type group, TTask* taskArray, uint32 taskCount);
84 
85 		bool WaitGroup(TaskGroup::Type group, uint32 milliseconds);
86 		bool WaitAll(uint32 milliseconds);
87 
88 		bool IsEmpty();
89 
90 		uint32 GetWorkerCount() const;
91 
92 		bool IsWorkerThread() const;
93 	};
94 }
95 
96 #include "MTScheduler.inl"
97 #include "MTFiberContext.inl"
98