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 
2358964d0bSSergey Makeev #include <MTScheduler.h>
2458964d0bSSergey Makeev 
2558964d0bSSergey Makeev namespace MT
2658964d0bSSergey Makeev {
2758964d0bSSergey Makeev 	namespace internal
2858964d0bSSergey Makeev 	{
292b4df162SSergey Makeev 		// Prime numbers for linear congruential generator seed
302b4df162SSergey Makeev 		static const uint32 primeNumbers[] = {
312b4df162SSergey Makeev 			128473, 135349, 159499, 173839, 209213, 241603, 292709, 314723,
322b4df162SSergey Makeev 			343943, 389299, 419473, 465169, 518327, 649921, 748271, 851087,
332b4df162SSergey Makeev 			862171, 974551, 1002973, 1034639, 1096289, 1153123, 1251037, 1299269,
342b4df162SSergey Makeev 			1272941, 1252151, 1231091, 1206761, 1185469, 1169933, 1141351, 1011583 };
352b4df162SSergey Makeev 
362b4df162SSergey Makeev 		uint32 GetPrimeNumber(uint32 index)
372b4df162SSergey Makeev 		{
3834a394c3SSergey Makeev 			return primeNumbers[index % MT_ARRAY_SIZE(primeNumbers)];
392b4df162SSergey Makeev 		}
402b4df162SSergey Makeev 
412b4df162SSergey Makeev 
422b4df162SSergey Makeev 
4358964d0bSSergey Makeev 		ThreadContext::ThreadContext()
4458964d0bSSergey Makeev 			: lastActiveFiberContext(nullptr)
4558964d0bSSergey Makeev 			, taskScheduler(nullptr)
4658964d0bSSergey Makeev 			, hasNewTasksEvent(EventReset::AUTOMATIC, true)
4758964d0bSSergey Makeev 			, state(ThreadState::ALIVE)
482b4df162SSergey Makeev 			, workerIndex(0)
4958964d0bSSergey Makeev 		{
50d6661c78SSergey Makeev 			 descBuffer = Memory::Alloc( sizeof(internal::GroupedTask) * TASK_BUFFER_CAPACITY );
5158964d0bSSergey Makeev 		}
5258964d0bSSergey Makeev 
5358964d0bSSergey Makeev 		ThreadContext::~ThreadContext()
5458964d0bSSergey Makeev 		{
55d6661c78SSergey Makeev 			Memory::Free(descBuffer);
56d6661c78SSergey Makeev 			descBuffer = nullptr;
5758964d0bSSergey Makeev 		}
5858964d0bSSergey Makeev 
592b4df162SSergey Makeev 		void ThreadContext::SetThreadIndex(uint32 threadIndex)
602b4df162SSergey Makeev 		{
612b4df162SSergey Makeev 			workerIndex = threadIndex;
622b4df162SSergey Makeev 			random.SetSeed( GetPrimeNumber(threadIndex) );
632b4df162SSergey Makeev 		}
642b4df162SSergey Makeev 
658112dedfSSergey Makeev #ifdef MT_INSTRUMENTED_BUILD
668112dedfSSergey Makeev 
67*6e90b535Ss.makeev_local 		void ThreadContext::NotifyTaskExecuteStateChanged(MT::Color::Type debugColor, const mt_char* debugID, TaskExecuteState::Type type)
688112dedfSSergey Makeev 		{
690727c1f9SSergey Makeev 			if (IProfilerEventListener* eventListener = taskScheduler->GetProfilerEventListener())
700727c1f9SSergey Makeev 			{
71*6e90b535Ss.makeev_local 				eventListener->NotifyTaskExecuteStateChanged(debugColor, debugID, type);
720727c1f9SSergey Makeev 			}
738112dedfSSergey Makeev 		}
748112dedfSSergey Makeev 
750727c1f9SSergey Makeev 		void ThreadContext::NotifyThreadCreate(uint32 threadIndex)
76a1626843SSergey Makeev 		{
770727c1f9SSergey Makeev 			if (IProfilerEventListener* eventListener = taskScheduler->GetProfilerEventListener())
78a1626843SSergey Makeev 			{
794a90b4a6SSergey Makeev 				eventListener->OnThreadCreated(threadIndex);
80a1626843SSergey Makeev 			}
810727c1f9SSergey Makeev 		}
820727c1f9SSergey Makeev 
830727c1f9SSergey Makeev 		void ThreadContext::NotifyThreadStart(uint32 threadIndex)
840727c1f9SSergey Makeev 		{
850727c1f9SSergey Makeev 			if (IProfilerEventListener* eventListener = taskScheduler->GetProfilerEventListener())
860727c1f9SSergey Makeev 			{
874a90b4a6SSergey Makeev 				eventListener->OnThreadStarted(threadIndex);
880727c1f9SSergey Makeev 			}
890727c1f9SSergey Makeev 		}
900727c1f9SSergey Makeev 
910727c1f9SSergey Makeev 		void ThreadContext::NotifyThreadStop(uint32 threadIndex)
920727c1f9SSergey Makeev 		{
930727c1f9SSergey Makeev 			if (IProfilerEventListener* eventListener = taskScheduler->GetProfilerEventListener())
940727c1f9SSergey Makeev 			{
954a90b4a6SSergey Makeev 				eventListener->OnThreadStoped(threadIndex);
960727c1f9SSergey Makeev 			}
970727c1f9SSergey Makeev 		}
980727c1f9SSergey Makeev 
994a90b4a6SSergey Makeev 		void ThreadContext::NotifyThreadIdleBegin(uint32 threadIndex)
1000727c1f9SSergey Makeev 		{
1010727c1f9SSergey Makeev 			if (IProfilerEventListener* eventListener = taskScheduler->GetProfilerEventListener())
1020727c1f9SSergey Makeev 			{
1034a90b4a6SSergey Makeev 				eventListener->OnThreadIdleBegin(threadIndex);
1044a90b4a6SSergey Makeev 			}
1050727c1f9SSergey Makeev 		}
106a1626843SSergey Makeev 
1074a90b4a6SSergey Makeev 		void ThreadContext::NotifyThreadIdleEnd(uint32 threadIndex)
1084a90b4a6SSergey Makeev 		{
1094a90b4a6SSergey Makeev 			if (IProfilerEventListener* eventListener = taskScheduler->GetProfilerEventListener())
1104a90b4a6SSergey Makeev 			{
1114a90b4a6SSergey Makeev 				eventListener->OnThreadIdleEnd(threadIndex);
112a1626843SSergey Makeev 			}
1134a90b4a6SSergey Makeev 		}
1144a90b4a6SSergey Makeev 
1158112dedfSSergey Makeev #endif
1168112dedfSSergey Makeev 
11758964d0bSSergey Makeev 	}
11858964d0bSSergey Makeev 
11958964d0bSSergey Makeev }
120