1f25ce65dSSergey Makeev // The MIT License (MIT)
2f25ce65dSSergey Makeev //
3f25ce65dSSergey Makeev // 	Copyright (c) 2015 Sergey Makeev, Vadim Slyusarev
4f25ce65dSSergey Makeev //
5f25ce65dSSergey Makeev // 	Permission is hereby granted, free of charge, to any person obtaining a copy
6f25ce65dSSergey Makeev // 	of this software and associated documentation files (the "Software"), to deal
7f25ce65dSSergey Makeev // 	in the Software without restriction, including without limitation the rights
8f25ce65dSSergey Makeev // 	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9f25ce65dSSergey Makeev // 	copies of the Software, and to permit persons to whom the Software is
10f25ce65dSSergey Makeev // 	furnished to do so, subject to the following conditions:
11f25ce65dSSergey Makeev //
12f25ce65dSSergey Makeev //  The above copyright notice and this permission notice shall be included in
13f25ce65dSSergey Makeev // 	all copies or substantial portions of the Software.
14f25ce65dSSergey Makeev //
15f25ce65dSSergey Makeev // 	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16f25ce65dSSergey Makeev // 	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17f25ce65dSSergey Makeev // 	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18f25ce65dSSergey Makeev // 	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19f25ce65dSSergey Makeev // 	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20f25ce65dSSergey Makeev // 	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21f25ce65dSSergey Makeev // 	THE SOFTWARE.
22f25ce65dSSergey Makeev 
2347d53e4dSSergey Makeev #pragma once
2447d53e4dSSergey Makeev 
2502d170cfSs.makeev_local #include <MTConfig.h>
264a90b4a6SSergey Makeev #include <MTColorTable.h>
2747d53e4dSSergey Makeev #include <MTTools.h>
2847d53e4dSSergey Makeev #include <MTPlatform.h>
2960ac17fbSs.makeev_local #include <MTQueueMPMC.h>
3056aa031bSSergey Makeev #include <MTArrayView.h>
3158964d0bSSergey Makeev #include <MTThreadContext.h>
3258964d0bSSergey Makeev #include <MTFiberContext.h>
3302d170cfSs.makeev_local #include <MTAppInterop.h>
34b7f5a220SSergey Makeev #include <MTTaskPool.h>
35f4db079dSs.makeev #include <MTStackRequirements.h>
362e846c40SSergey Makeev #include <Scopes/MTScopes.h>
373955e462SSergey Makeev 
389c716f68Ss.makeev_local /*
399c716f68Ss.makeev_local 	You can inject some profiler code right into the task scope using this macro.
409c716f68Ss.makeev_local */
419c716f68Ss.makeev_local #ifndef MT_SCHEDULER_PROFILER_TASK_SCOPE_CODE_INJECTION
429c716f68Ss.makeev_local #define MT_SCHEDULER_PROFILER_TASK_SCOPE_CODE_INJECTION( TYPE, DEBUG_COLOR, SRC_FILE, SRC_LINE)
439c716f68Ss.makeev_local #endif
4466de1283SSergey Makeev 
453955e462SSergey Makeev namespace MT
463955e462SSergey Makeev {
473955e462SSergey Makeev 
483955e462SSergey Makeev 	template<typename CLASS_TYPE, typename MACRO_TYPE>
493955e462SSergey Makeev 	struct CheckType
503955e462SSergey Makeev 	{
513955e462SSergey Makeev 		static_assert(std::is_same<CLASS_TYPE, MACRO_TYPE>::value, "Invalid type in MT_DECLARE_TASK macro. See CheckType template instantiation params to details.");
523955e462SSergey Makeev 	};
533955e462SSergey Makeev 
543955e462SSergey Makeev 	struct TypeChecker
553955e462SSergey Makeev 	{
563955e462SSergey Makeev 		template <typename T>
QueryThisTypeTypeChecker573955e462SSergey Makeev 		static T QueryThisType(T thisPtr)
583955e462SSergey Makeev 		{
59ea599e92Ss.makeev_local 			MT_UNUSED(thisPtr);
603955e462SSergey Makeev 			return (T)nullptr;
613955e462SSergey Makeev 		}
623955e462SSergey Makeev 	};
633955e462SSergey Makeev 
649e8a432bSSergey Makeev 
659e8a432bSSergey Makeev 	template <typename T>
CallDtor(T * p)669e8a432bSSergey Makeev 	inline void CallDtor(T* p)
679e8a432bSSergey Makeev 	{
682e846c40SSergey Makeev 		MT_UNUSED(p);
699e8a432bSSergey Makeev 		p->~T();
709e8a432bSSergey Makeev 	}
719e8a432bSSergey Makeev 
723955e462SSergey Makeev }
733955e462SSergey Makeev 
7402d170cfSs.makeev_local #if MT_MSVC_COMPILER_FAMILY
753955e462SSergey Makeev 
766b6075aaSSergey Makeev // Visual Studio compile time check
777f96f495SSergey Makeev #define MT_COMPILE_TIME_TYPE_CHECK(TYPE) \
783955e462SSergey Makeev 	void CompileTimeCheckMethod() \
793955e462SSergey Makeev 	{ \
80510585fbSSergey Makeev 		MT::CheckType< typename std::remove_pointer< decltype(MT::TypeChecker::QueryThisType(this)) >::type, typename TYPE > compileTypeTypesCheck; \
813955e462SSergey Makeev 		compileTypeTypesCheck; \
826b6075aaSSergey Makeev 	}
83510585fbSSergey Makeev 
8402d170cfSs.makeev_local #elif MT_GCC_COMPILER_FAMILY
857f96f495SSergey Makeev 
866b6075aaSSergey Makeev // GCC, Clang and other compilers compile time check
877f96f495SSergey Makeev #define MT_COMPILE_TIME_TYPE_CHECK(TYPE) \
886b6075aaSSergey Makeev 	void CompileTimeCheckMethod() \
896b6075aaSSergey Makeev 	{ \
90510585fbSSergey Makeev 		/* query this pointer type */ \
91510585fbSSergey Makeev 		typedef decltype(MT::TypeChecker::QueryThisType(this)) THIS_PTR_TYPE; \
92510585fbSSergey Makeev 		/* query class type from this pointer type */ \
93f15c226dSSergey Makeev 		typedef typename std::remove_pointer<THIS_PTR_TYPE>::type CPP_TYPE; \
94510585fbSSergey Makeev 		/* define macro type */ \
956b6075aaSSergey Makeev 		typedef TYPE MACRO_TYPE; \
96510585fbSSergey Makeev 		/* compile time checking that is same types */ \
97510585fbSSergey Makeev 		MT::CheckType< CPP_TYPE, MACRO_TYPE > compileTypeTypesCheck; \
98510585fbSSergey Makeev 		/* remove unused variable warning */ \
997f96f495SSergey Makeev 		MT_UNUSED(compileTypeTypesCheck); \
1006b6075aaSSergey Makeev 	}
101510585fbSSergey Makeev 
10202d170cfSs.makeev_local #else
10302d170cfSs.makeev_local 
10402d170cfSs.makeev_local #error Platform is not supported.
10502d170cfSs.makeev_local 
1066b6075aaSSergey Makeev #endif
1076b6075aaSSergey Makeev 
1086b6075aaSSergey Makeev 
1099c716f68Ss.makeev_local #define MT_DECLARE_TASK_IMPL(TYPE, STACK_REQUIREMENTS, TASK_PRIORITY, DEBUG_COLOR) \
1106b6075aaSSergey Makeev 	\
1117f96f495SSergey Makeev 	MT_COMPILE_TIME_TYPE_CHECK(TYPE) \
1123955e462SSergey Makeev 	\
113f4db079dSs.makeev 	static void TaskEntryPoint(MT::FiberContext& fiberContext, const void* userData) \
1143955e462SSergey Makeev 	{ \
1159c716f68Ss.makeev_local 		MT_SCHEDULER_PROFILER_TASK_SCOPE_CODE_INJECTION(TYPE, DEBUG_COLOR, __FILE__, __LINE__); \
116f4db079dSs.makeev 		/* C style cast */ \
117f4db079dSs.makeev 		TYPE * task = (TYPE *)(userData); \
1183955e462SSergey Makeev 		task->Do(fiberContext); \
1193955e462SSergey Makeev 	} \
1203955e462SSergey Makeev 	\
121f4db079dSs.makeev 	static void PoolTaskDestroy(const void* userData) \
1223955e462SSergey Makeev 	{ \
123f4db079dSs.makeev 		/* C style cast */ \
124f4db079dSs.makeev 		TYPE * task = (TYPE *)(userData); \
1259e8a432bSSergey Makeev 		MT::CallDtor( task ); \
1263955e462SSergey Makeev 		/* Find task pool header */ \
1273955e462SSergey Makeev 		MT::PoolElementHeader * poolHeader = (MT::PoolElementHeader *)((char*)userData - sizeof(MT::PoolElementHeader)); \
1283955e462SSergey Makeev 		/* Fixup pool header, mark task as unused */ \
1293955e462SSergey Makeev 		poolHeader->id.Store(MT::TaskID::UNUSED); \
1303955e462SSergey Makeev 	} \
131f4db079dSs.makeev 	\
132f4db079dSs.makeev 	static MT::StackRequirements::Type GetStackRequirements() \
133f4db079dSs.makeev 	{ \
134f4db079dSs.makeev 		return STACK_REQUIREMENTS; \
135f4db079dSs.makeev 	} \
136b23bdf5aSs.makeev_local 	static MT::TaskPriority::Type GetTaskPriority() \
137b23bdf5aSs.makeev_local 	{ \
138b23bdf5aSs.makeev_local 		return TASK_PRIORITY; \
139b23bdf5aSs.makeev_local 	} \
1403955e462SSergey Makeev 
1413955e462SSergey Makeev 
1423955e462SSergey Makeev 
143ff5c86b0SSergey Makeev #ifdef MT_INSTRUMENTED_BUILD
1440727c1f9SSergey Makeev #include <MTProfilerEventListener.h>
1453955e462SSergey Makeev 
146b23bdf5aSs.makeev_local #define MT_DECLARE_TASK(TYPE, STACK_REQUIREMENTS, TASK_PRIORITY, DEBUG_COLOR) \
147f371f0bdSSergey Makeev 	static const mt_char* GetDebugID() \
1483955e462SSergey Makeev 	{ \
149f371f0bdSSergey Makeev 		return MT_TEXT( #TYPE ); \
1503955e462SSergey Makeev 	} \
1513955e462SSergey Makeev 	\
1524a90b4a6SSergey Makeev 	static MT::Color::Type GetDebugColor() \
1533955e462SSergey Makeev 	{ \
1544a90b4a6SSergey Makeev 		return DEBUG_COLOR; \
1553955e462SSergey Makeev 	} \
1563955e462SSergey Makeev 	\
1579c716f68Ss.makeev_local 	MT_DECLARE_TASK_IMPL(TYPE, STACK_REQUIREMENTS, TASK_PRIORITY, DEBUG_COLOR);
1583955e462SSergey Makeev 
1593955e462SSergey Makeev #else
1603955e462SSergey Makeev 
161b23bdf5aSs.makeev_local #define MT_DECLARE_TASK(TYPE, STACK_REQUIREMENTS, TASK_PRIORITY, DEBUG_COLOR) \
1629c716f68Ss.makeev_local 	MT_DECLARE_TASK_IMPL(TYPE, STACK_REQUIREMENTS, TASK_PRIORITY, DEBUG_COLOR);
1633955e462SSergey Makeev 
164ff5c86b0SSergey Makeev #endif
165ff5c86b0SSergey Makeev 
1663955e462SSergey Makeev 
1673955e462SSergey Makeev 
1683955e462SSergey Makeev 
1699d94a278Ss.makeev_local #if defined(MT_DEBUG) || defined(MT_INSTRUMENTED_BUILD)
1709d94a278Ss.makeev_local #define MT_GROUP_DEBUG (1)
1719d94a278Ss.makeev_local #endif
1729d94a278Ss.makeev_local 
1733955e462SSergey Makeev 
1743955e462SSergey Makeev 
17547d53e4dSSergey Makeev namespace MT
17647d53e4dSSergey Makeev {
17743c41d5cSSergey Makeev 	const uint32 MT_MAX_THREAD_COUNT = 64;
178f4db079dSs.makeev 	const uint32 MT_SCHEDULER_STACK_SIZE = 1048576; // 1Mb
179f4db079dSs.makeev 
180f4db079dSs.makeev 	const uint32 MT_MAX_STANDART_FIBERS_COUNT = 256;
181f4db079dSs.makeev 	const uint32 MT_STANDART_FIBER_STACK_SIZE = 32768; //32Kb
182f4db079dSs.makeev 
183f4db079dSs.makeev 	const uint32 MT_MAX_EXTENDED_FIBERS_COUNT = 8;
184f4db079dSs.makeev 	const uint32 MT_EXTENDED_FIBER_STACK_SIZE = 1048576; // 1Mb
18547d53e4dSSergey Makeev 
18658964d0bSSergey Makeev 	namespace internal
18747d53e4dSSergey Makeev 	{
18847d53e4dSSergey Makeev 		struct ThreadContext;
18947d53e4dSSergey Makeev 	}
19047d53e4dSSergey Makeev 
191b23bdf5aSs.makeev_local 	namespace TaskStealingMode
192b23bdf5aSs.makeev_local 	{
193b23bdf5aSs.makeev_local 		enum Type
194b23bdf5aSs.makeev_local 		{
195b23bdf5aSs.makeev_local 			DISABLED = 0,
196b23bdf5aSs.makeev_local 			ENABLED = 1,
197b23bdf5aSs.makeev_local 		};
198b23bdf5aSs.makeev_local 	}
199b23bdf5aSs.makeev_local 
200d7cf17b1Ss.makeev_local 	struct WorkerThreadParams
201d7cf17b1Ss.makeev_local 	{
202d7cf17b1Ss.makeev_local 		uint32 core;
203d7cf17b1Ss.makeev_local 		ThreadPriority::Type priority;
204d7cf17b1Ss.makeev_local 
WorkerThreadParamsWorkerThreadParams205d7cf17b1Ss.makeev_local 		WorkerThreadParams()
206d7cf17b1Ss.makeev_local 			: core(MT_CPUCORE_ANY)
207d7cf17b1Ss.makeev_local 			, priority(ThreadPriority::DEFAULT)
208d7cf17b1Ss.makeev_local 		{
209d7cf17b1Ss.makeev_local 		}
210d7cf17b1Ss.makeev_local 	};
211d7cf17b1Ss.makeev_local 
21247d53e4dSSergey Makeev 	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
21347d53e4dSSergey Makeev 	// Task scheduler
21447d53e4dSSergey Makeev 	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
21547d53e4dSSergey Makeev 	class TaskScheduler
21647d53e4dSSergey Makeev 	{
21747d53e4dSSergey Makeev 		friend class FiberContext;
21858964d0bSSergey Makeev 		friend struct internal::ThreadContext;
21947d53e4dSSergey Makeev 
22047d53e4dSSergey Makeev 
221806ef292SSergey Makeev 
222806ef292SSergey Makeev 		////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
223806ef292SSergey Makeev 		// Task group description
224806ef292SSergey Makeev 		////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
225806ef292SSergey Makeev 		// Application can assign task group to task and later wait until group was finished.
226806ef292SSergey Makeev 		class TaskGroupDescription
227806ef292SSergey Makeev 		{
228721f8c0bSs.makeev_local 			Atomic32<int32> inProgressTaskCount;
229806ef292SSergey Makeev 
2309d94a278Ss.makeev_local #if MT_GROUP_DEBUG
231806ef292SSergey Makeev 			bool debugIsFree;
2329d94a278Ss.makeev_local #endif
233806ef292SSergey Makeev 
234806ef292SSergey Makeev 		public:
235806ef292SSergey Makeev 
2362e846c40SSergey Makeev 			MT_NOCOPYABLE(TaskGroupDescription);
2372e846c40SSergey Makeev 
TaskGroupDescription()238806ef292SSergey Makeev 			TaskGroupDescription()
239806ef292SSergey Makeev 			{
24081ec7369SSergey Makeev 				inProgressTaskCount.Store(0);
2419d94a278Ss.makeev_local #if MT_GROUP_DEBUG
242806ef292SSergey Makeev 				debugIsFree = true;
2439d94a278Ss.makeev_local #endif
244806ef292SSergey Makeev 			}
245806ef292SSergey Makeev 
GetTaskCount()246f7a9bfc3Ss.makeev_local 			int32 GetTaskCount() const
24781ec7369SSergey Makeev 			{
24881ec7369SSergey Makeev 				return inProgressTaskCount.Load();
24981ec7369SSergey Makeev 			}
25081ec7369SSergey Makeev 
Dec()251f7a9bfc3Ss.makeev_local 			int32 Dec()
25281ec7369SSergey Makeev 			{
25381ec7369SSergey Makeev 				return inProgressTaskCount.DecFetch();
25481ec7369SSergey Makeev 			}
25581ec7369SSergey Makeev 
Inc()256f7a9bfc3Ss.makeev_local 			int32 Inc()
25781ec7369SSergey Makeev 			{
25881ec7369SSergey Makeev 				return inProgressTaskCount.IncFetch();
25981ec7369SSergey Makeev 			}
26081ec7369SSergey Makeev 
Add(int sum)261f7a9bfc3Ss.makeev_local 			int32 Add(int sum)
26281ec7369SSergey Makeev 			{
26381ec7369SSergey Makeev 				return inProgressTaskCount.AddFetch(sum);
26481ec7369SSergey Makeev 			}
26581ec7369SSergey Makeev 
GetWaitCounter()2663d930776Ss.makeev_local 			Atomic32<int32>* GetWaitCounter()
26781ec7369SSergey Makeev 			{
2683d930776Ss.makeev_local 				return &inProgressTaskCount;
26981ec7369SSergey Makeev 			}
2702e846c40SSergey Makeev 
2719d94a278Ss.makeev_local #if MT_GROUP_DEBUG
SetDebugIsFree(bool _debugIsFree)2722e846c40SSergey Makeev 			void SetDebugIsFree(bool _debugIsFree)
2732e846c40SSergey Makeev 			{
2742e846c40SSergey Makeev 				debugIsFree = _debugIsFree;
2752e846c40SSergey Makeev 			}
2762e846c40SSergey Makeev 
GetDebugIsFree()2772e846c40SSergey Makeev 			bool GetDebugIsFree() const
2782e846c40SSergey Makeev 			{
2792e846c40SSergey Makeev 				return debugIsFree;
2802e846c40SSergey Makeev 			}
2819d94a278Ss.makeev_local #endif
282806ef292SSergey Makeev 		};
283806ef292SSergey Makeev 
284806ef292SSergey Makeev 
2853d930776Ss.makeev_local 		struct WaitContext
2863d930776Ss.makeev_local 		{
2873d930776Ss.makeev_local 			Atomic32<int32>* waitCounter;
2883d930776Ss.makeev_local 			internal::ThreadContext* threadContext;
2893d930776Ss.makeev_local 			uint32 waitTimeMs;
2903d930776Ss.makeev_local 			uint32 exitCode;
2913d930776Ss.makeev_local 		};
2923d930776Ss.makeev_local 
2933d930776Ss.makeev_local 
29447d53e4dSSergey Makeev 		// Thread index for new task
295721f8c0bSs.makeev_local 		Atomic32<int32> roundRobinThreadIndex;
29647d53e4dSSergey Makeev 
29743c41d5cSSergey Makeev 		// Started threads count
298721f8c0bSs.makeev_local 		Atomic32<int32> startedThreadsCount;
29943c41d5cSSergey Makeev 
30047ecee31Ss.makeev_local 		std::array<ThreadId, 4 > waitingThreads;
30147ecee31Ss.makeev_local 		Atomic32<int32> nextWaitingThreadSlotIndex;
30247ecee31Ss.makeev_local 
30347d53e4dSSergey Makeev 		// Threads created by task manager
304721f8c0bSs.makeev_local 		Atomic32<int32> threadsCount;
30547ecee31Ss.makeev_local 
30658964d0bSSergey Makeev 		internal::ThreadContext threadContext[MT_MAX_THREAD_COUNT];
30747d53e4dSSergey Makeev 
30847d53e4dSSergey Makeev 		// All groups task statistic
309806ef292SSergey Makeev 		TaskGroupDescription allGroups;
310806ef292SSergey Makeev 
311806ef292SSergey Makeev 		// Groups pool
3124965e494Ss.makeev_local 		LockFreeQueueMPMC<TaskGroup, TaskGroup::MT_MAX_GROUPS_COUNT * 2> availableGroups;
313806ef292SSergey Makeev 
314806ef292SSergey Makeev 		//
315754cb997SSergey Makeev 		TaskGroupDescription groupStats[TaskGroup::MT_MAX_GROUPS_COUNT];
31647d53e4dSSergey Makeev 
31747d53e4dSSergey Makeev 		// Fibers context
318f4db079dSs.makeev 		FiberContext standartFiberContexts[MT_MAX_STANDART_FIBERS_COUNT];
319f4db079dSs.makeev 		FiberContext extendedFiberContexts[MT_MAX_EXTENDED_FIBERS_COUNT];
320f4db079dSs.makeev 
321f4db079dSs.makeev 		// Fibers pool
3224965e494Ss.makeev_local 		LockFreeQueueMPMC<FiberContext*, MT_MAX_STANDART_FIBERS_COUNT * 2> standartFibersAvailable;
3234965e494Ss.makeev_local 		LockFreeQueueMPMC<FiberContext*, MT_MAX_EXTENDED_FIBERS_COUNT * 2> extendedFibersAvailable;
32447d53e4dSSergey Makeev 
325ff5c86b0SSergey Makeev #ifdef MT_INSTRUMENTED_BUILD
3260727c1f9SSergey Makeev 		IProfilerEventListener * profilerEventListener;
327ff5c86b0SSergey Makeev #endif
328ff5c86b0SSergey Makeev 
329b23bdf5aSs.makeev_local 		bool taskStealingDisabled;
330b23bdf5aSs.makeev_local 
33158964d0bSSergey Makeev 		FiberContext* RequestFiberContext(internal::GroupedTask& task);
33260ac17fbSs.makeev_local 		void ReleaseFiberContext(FiberContext*&& fiberExecutionContext);
33356aa031bSSergey Makeev 		void RunTasksImpl(ArrayView<internal::TaskBucket>& buckets, FiberContext * parentFiber, bool restoredFromAwaitState);
334806ef292SSergey Makeev 		TaskGroupDescription & GetGroupDesc(TaskGroup group);
33547d53e4dSSergey Makeev 
336c88507a8Ss.makeev_local 		static void WorkerThreadMain( void* userData );
33771198a5eSs.makeev_local 		static void SchedulerFiberMain( void* userData );
3383d930776Ss.makeev_local 		static void SchedulerFiberWait( void* userData );
3393cb1fd8eSs.makeev_local 		static bool SchedulerFiberStep( internal::ThreadContext& context, bool disableTaskStealing);
3403cb1fd8eSs.makeev_local 		static void SchedulerFiberProcessTask( internal::ThreadContext& context, internal::GroupedTask& task );
34147d53e4dSSergey Makeev 		static void FiberMain( void* userData );
3423d930776Ss.makeev_local 		static bool TryStealTask(internal::ThreadContext& threadContext, internal::GroupedTask & task);
3432b4df162SSergey Makeev 
34458964d0bSSergey Makeev 		static FiberContext* ExecuteTask (internal::ThreadContext& threadContext, FiberContext* fiberContext);
34547d53e4dSSergey Makeev 
34647d53e4dSSergey Makeev 	public:
34747d53e4dSSergey Makeev 
34834a394c3SSergey Makeev 		/// \brief Initializes a new instance of the TaskScheduler class.
34934a394c3SSergey Makeev 		/// \param workerThreadsCount Worker threads count. Automatically determines the required number of threads if workerThreadsCount set to 0
3500727c1f9SSergey Makeev #ifdef MT_INSTRUMENTED_BUILD
351b23bdf5aSs.makeev_local 		TaskScheduler(uint32 workerThreadsCount = 0, WorkerThreadParams* workerParameters = nullptr, IProfilerEventListener* listener = nullptr, TaskStealingMode::Type stealMode = TaskStealingMode::ENABLED);
3520727c1f9SSergey Makeev #else
353b23bdf5aSs.makeev_local 		TaskScheduler(uint32 workerThreadsCount = 0, WorkerThreadParams* workerParameters = nullptr, TaskStealingMode::Type stealMode = TaskStealingMode::ENABLED);
3540727c1f9SSergey Makeev #endif
3550727c1f9SSergey Makeev 
3560727c1f9SSergey Makeev 
35747d53e4dSSergey Makeev 		~TaskScheduler();
35847d53e4dSSergey Makeev 
359*01616bcfSs.makeev_local 		void JoinWorkerThreads();
360*01616bcfSs.makeev_local 
36147d53e4dSSergey Makeev 		template<class TTask>
362f4db079dSs.makeev 		void RunAsync(TaskGroup group, const TTask* taskArray, uint32 taskCount);
36347d53e4dSSergey Makeev 
364f4db079dSs.makeev 		void RunAsync(TaskGroup group, const TaskHandle* taskHandleArray, uint32 taskHandleCount);
36558d12dadSSergey Makeev 
3662f083884Ss.makeev_local 		/// \brief Wait while no more tasks in specific group.
3672f083884Ss.makeev_local 		/// \return true - if no more tasks in specific group. false - if timeout in milliseconds has reached and group still has some tasks.
368806ef292SSergey Makeev 		bool WaitGroup(TaskGroup group, uint32 milliseconds);
3692f083884Ss.makeev_local 
37047d53e4dSSergey Makeev 		bool WaitAll(uint32 milliseconds);
37147d53e4dSSergey Makeev 
372806ef292SSergey Makeev 		TaskGroup CreateGroup();
373806ef292SSergey Makeev 		void ReleaseGroup(TaskGroup group);
374806ef292SSergey Makeev 
375a23fd933SSergey Makeev 		int32 GetWorkersCount() const;
37647d53e4dSSergey Makeev 
377ef444cf7Ss.makeev_local 		bool IsTaskStealingDisabled(uint32 minWorkersCount = 1) const;
378b23bdf5aSs.makeev_local 
37947d53e4dSSergey Makeev 		bool IsWorkerThread() const;
3808112dedfSSergey Makeev 
3818112dedfSSergey Makeev #ifdef MT_INSTRUMENTED_BUILD
3828112dedfSSergey Makeev 
GetProfilerEventListener()3830727c1f9SSergey Makeev 		inline IProfilerEventListener* GetProfilerEventListener()
3840727c1f9SSergey Makeev 		{
3850727c1f9SSergey Makeev 			return profilerEventListener;
3860727c1f9SSergey Makeev 		}
3870727c1f9SSergey Makeev 
3889c716f68Ss.makeev_local 		void NotifyFibersCreated(uint32 fibersCount);
3899c716f68Ss.makeev_local 		void NotifyThreadsCreated(uint32 threadsCount);
3909c716f68Ss.makeev_local 
3919c716f68Ss.makeev_local 
3928112dedfSSergey Makeev #endif
39347d53e4dSSergey Makeev 	};
39447d53e4dSSergey Makeev }
39547d53e4dSSergey Makeev 
396b7b54a39SSergey Makeev #include "MTScheduler.inl"
397b7b54a39SSergey Makeev #include "MTFiberContext.inl"
398