1*f25ce65dSSergey Makeev // The MIT License (MIT)
2*f25ce65dSSergey Makeev //
3*f25ce65dSSergey Makeev // 	Copyright (c) 2015 Sergey Makeev, Vadim Slyusarev
4*f25ce65dSSergey Makeev //
5*f25ce65dSSergey Makeev // 	Permission is hereby granted, free of charge, to any person obtaining a copy
6*f25ce65dSSergey Makeev // 	of this software and associated documentation files (the "Software"), to deal
7*f25ce65dSSergey Makeev // 	in the Software without restriction, including without limitation the rights
8*f25ce65dSSergey Makeev // 	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9*f25ce65dSSergey Makeev // 	copies of the Software, and to permit persons to whom the Software is
10*f25ce65dSSergey Makeev // 	furnished to do so, subject to the following conditions:
11*f25ce65dSSergey Makeev //
12*f25ce65dSSergey Makeev //  The above copyright notice and this permission notice shall be included in
13*f25ce65dSSergey Makeev // 	all copies or substantial portions of the Software.
14*f25ce65dSSergey Makeev //
15*f25ce65dSSergey Makeev // 	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*f25ce65dSSergey Makeev // 	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*f25ce65dSSergey Makeev // 	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18*f25ce65dSSergey Makeev // 	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*f25ce65dSSergey Makeev // 	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20*f25ce65dSSergey Makeev // 	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21*f25ce65dSSergey Makeev // 	THE SOFTWARE.
22*f25ce65dSSergey Makeev 
2358964d0bSSergey Makeev #include <MTScheduler.h>
2458964d0bSSergey Makeev 
2558964d0bSSergey Makeev namespace MT
2658964d0bSSergey Makeev {
2758964d0bSSergey Makeev 	namespace internal
2858964d0bSSergey Makeev 	{
2958964d0bSSergey Makeev 		static const size_t TASK_BUFFER_CAPACITY = 4096;
3058964d0bSSergey Makeev 
3158964d0bSSergey Makeev 		ThreadContext::ThreadContext()
3258964d0bSSergey Makeev 			: lastActiveFiberContext(nullptr)
3358964d0bSSergey Makeev 			, taskScheduler(nullptr)
3458964d0bSSergey Makeev 			, hasNewTasksEvent(EventReset::AUTOMATIC, true)
3558964d0bSSergey Makeev 			, state(ThreadState::ALIVE)
3658964d0bSSergey Makeev 			, descBuffer(TASK_BUFFER_CAPACITY)
3758964d0bSSergey Makeev 		{
3858964d0bSSergey Makeev 		}
3958964d0bSSergey Makeev 
4058964d0bSSergey Makeev 		ThreadContext::~ThreadContext()
4158964d0bSSergey Makeev 		{
4258964d0bSSergey Makeev 		}
4358964d0bSSergey Makeev 
4458964d0bSSergey Makeev 		void ThreadContext::RestoreAwaitingTasks(TaskGroup::Type taskGroup)
4558964d0bSSergey Makeev 		{
4658964d0bSSergey Makeev 			ASSERT(taskScheduler, "Invalid Task Scheduler");
4758964d0bSSergey Makeev 			ASSERT(taskScheduler->IsWorkerThread(), "Can't use RunAsync outside Task. Use TaskScheduler.RunAsync() instead.");
4858964d0bSSergey Makeev 
4958964d0bSSergey Makeev 			ConcurrentQueueLIFO<FiberContext*> & groupQueue = taskScheduler->waitTaskQueues[taskGroup];
5058964d0bSSergey Makeev 
5158964d0bSSergey Makeev 			if (groupQueue.IsEmpty())
5258964d0bSSergey Makeev 			{
5358964d0bSSergey Makeev 				return;
5458964d0bSSergey Makeev 			}
5558964d0bSSergey Makeev 
5658964d0bSSergey Makeev 			//copy awaiting tasks list to stack
5758964d0bSSergey Makeev 			stack_array<FiberContext*, MT_MAX_FIBERS_COUNT> groupQueueCopy(MT_MAX_FIBERS_COUNT, nullptr);
5858964d0bSSergey Makeev 			size_t taskCount = groupQueue.PopAll(groupQueueCopy.begin(), groupQueueCopy.size());
5958964d0bSSergey Makeev 
6058964d0bSSergey Makeev 			fixed_array<internal::GroupedTask> buffer(&descBuffer.front(), taskCount);
6158964d0bSSergey Makeev 
6258964d0bSSergey Makeev 			TaskScheduler & scheduler = *(taskScheduler);
6358964d0bSSergey Makeev 			size_t bucketCount = Min((size_t)scheduler.GetWorkerCount(), taskCount);
64b7b54a39SSergey Makeev 			fixed_array<internal::TaskBucket>	buckets(ALLOCATE_ON_STACK(sizeof(internal::TaskBucket) * bucketCount), bucketCount);
6558964d0bSSergey Makeev 
66b7b54a39SSergey Makeev 			internal::DistibuteDescriptions(TaskGroup::GROUP_UNDEFINED, groupQueueCopy.begin(), buffer, buckets);
6758964d0bSSergey Makeev 			scheduler.RunTasksImpl(buckets, nullptr, true);
6858964d0bSSergey Makeev 		}
6958964d0bSSergey Makeev 
7058964d0bSSergey Makeev 	}
7158964d0bSSergey Makeev 
7258964d0bSSergey Makeev }
73