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) 49*3d930776Ss.makeev_local , isExternalDescBuffer(false) 5058964d0bSSergey Makeev { 51*3d930776Ss.makeev_local descBuffer = Memory::Alloc( GetMemoryRequrementInBytesForDescBuffer() ); 52*3d930776Ss.makeev_local } 53*3d930776Ss.makeev_local 54*3d930776Ss.makeev_local ThreadContext::ThreadContext(void* externalDescBuffer) 55*3d930776Ss.makeev_local : lastActiveFiberContext(nullptr) 56*3d930776Ss.makeev_local , taskScheduler(nullptr) 57*3d930776Ss.makeev_local , queue(DummyQueueFlag::IS_DUMMY_QUEUE) 58*3d930776Ss.makeev_local , hasNewTasksEvent(EventReset::AUTOMATIC, true) 59*3d930776Ss.makeev_local , state(ThreadState::ALIVE) 60*3d930776Ss.makeev_local , workerIndex(0) 61*3d930776Ss.makeev_local , isExternalDescBuffer(true) 62*3d930776Ss.makeev_local { 63*3d930776Ss.makeev_local descBuffer = externalDescBuffer; 6458964d0bSSergey Makeev } 6558964d0bSSergey Makeev 6658964d0bSSergey Makeev ThreadContext::~ThreadContext() 6758964d0bSSergey Makeev { 68*3d930776Ss.makeev_local if (isExternalDescBuffer == false) 69*3d930776Ss.makeev_local { 70d6661c78SSergey Makeev Memory::Free(descBuffer); 71*3d930776Ss.makeev_local } 72d6661c78SSergey Makeev descBuffer = nullptr; 7358964d0bSSergey Makeev } 7458964d0bSSergey Makeev 75*3d930776Ss.makeev_local size_t ThreadContext::GetMemoryRequrementInBytesForDescBuffer() 76*3d930776Ss.makeev_local { 77*3d930776Ss.makeev_local return sizeof(internal::GroupedTask) * TASK_BUFFER_CAPACITY; 78*3d930776Ss.makeev_local } 79*3d930776Ss.makeev_local 802b4df162SSergey Makeev void ThreadContext::SetThreadIndex(uint32 threadIndex) 812b4df162SSergey Makeev { 822b4df162SSergey Makeev workerIndex = threadIndex; 832b4df162SSergey Makeev random.SetSeed( GetPrimeNumber(threadIndex) ); 842b4df162SSergey Makeev } 852b4df162SSergey Makeev 868112dedfSSergey Makeev #ifdef MT_INSTRUMENTED_BUILD 878112dedfSSergey Makeev 88*3d930776Ss.makeev_local void ThreadContext::NotifyWaitStarted() 89*3d930776Ss.makeev_local { 90*3d930776Ss.makeev_local if (IProfilerEventListener* eventListener = taskScheduler->GetProfilerEventListener()) 91*3d930776Ss.makeev_local { 92*3d930776Ss.makeev_local eventListener->OnThreadWaitStarted(); 93*3d930776Ss.makeev_local } 94*3d930776Ss.makeev_local } 95*3d930776Ss.makeev_local 96*3d930776Ss.makeev_local void ThreadContext::NotifyWaitFinished() 97*3d930776Ss.makeev_local { 98*3d930776Ss.makeev_local if (IProfilerEventListener* eventListener = taskScheduler->GetProfilerEventListener()) 99*3d930776Ss.makeev_local { 100*3d930776Ss.makeev_local eventListener->OnThreadWaitFinished(); 101*3d930776Ss.makeev_local } 102*3d930776Ss.makeev_local } 103*3d930776Ss.makeev_local 104*3d930776Ss.makeev_local 1056e90b535Ss.makeev_local void ThreadContext::NotifyTaskExecuteStateChanged(MT::Color::Type debugColor, const mt_char* debugID, TaskExecuteState::Type type) 1068112dedfSSergey Makeev { 1070727c1f9SSergey Makeev if (IProfilerEventListener* eventListener = taskScheduler->GetProfilerEventListener()) 1080727c1f9SSergey Makeev { 1096e90b535Ss.makeev_local eventListener->NotifyTaskExecuteStateChanged(debugColor, debugID, type); 1100727c1f9SSergey Makeev } 1118112dedfSSergey Makeev } 1128112dedfSSergey Makeev 113*3d930776Ss.makeev_local void ThreadContext::NotifyThreadCreated(uint32 threadIndex) 114a1626843SSergey Makeev { 1150727c1f9SSergey Makeev if (IProfilerEventListener* eventListener = taskScheduler->GetProfilerEventListener()) 116a1626843SSergey Makeev { 1174a90b4a6SSergey Makeev eventListener->OnThreadCreated(threadIndex); 118a1626843SSergey Makeev } 1190727c1f9SSergey Makeev } 1200727c1f9SSergey Makeev 121*3d930776Ss.makeev_local void ThreadContext::NotifyThreadStarted(uint32 threadIndex) 1220727c1f9SSergey Makeev { 1230727c1f9SSergey Makeev if (IProfilerEventListener* eventListener = taskScheduler->GetProfilerEventListener()) 1240727c1f9SSergey Makeev { 1254a90b4a6SSergey Makeev eventListener->OnThreadStarted(threadIndex); 1260727c1f9SSergey Makeev } 1270727c1f9SSergey Makeev } 1280727c1f9SSergey Makeev 129*3d930776Ss.makeev_local void ThreadContext::NotifyThreadStoped(uint32 threadIndex) 1300727c1f9SSergey Makeev { 1310727c1f9SSergey Makeev if (IProfilerEventListener* eventListener = taskScheduler->GetProfilerEventListener()) 1320727c1f9SSergey Makeev { 1334a90b4a6SSergey Makeev eventListener->OnThreadStoped(threadIndex); 1340727c1f9SSergey Makeev } 1350727c1f9SSergey Makeev } 1360727c1f9SSergey Makeev 137*3d930776Ss.makeev_local void ThreadContext::NotifyThreadIdleStarted(uint32 threadIndex) 1380727c1f9SSergey Makeev { 1390727c1f9SSergey Makeev if (IProfilerEventListener* eventListener = taskScheduler->GetProfilerEventListener()) 1400727c1f9SSergey Makeev { 141*3d930776Ss.makeev_local eventListener->OnThreadIdleStarted(threadIndex); 1424a90b4a6SSergey Makeev } 1430727c1f9SSergey Makeev } 144a1626843SSergey Makeev 145*3d930776Ss.makeev_local void ThreadContext::NotifyThreadIdleFinished(uint32 threadIndex) 1464a90b4a6SSergey Makeev { 1474a90b4a6SSergey Makeev if (IProfilerEventListener* eventListener = taskScheduler->GetProfilerEventListener()) 1484a90b4a6SSergey Makeev { 149*3d930776Ss.makeev_local eventListener->OnThreadIdleFinished(threadIndex); 150a1626843SSergey Makeev } 1514a90b4a6SSergey Makeev } 1524a90b4a6SSergey Makeev 1538112dedfSSergey Makeev #endif 1548112dedfSSergey Makeev 15558964d0bSSergey Makeev } 15658964d0bSSergey Makeev 15758964d0bSSergey Makeev } 158