41 #ifndef _framescheduler_cpp
42 #define _framescheduler_cpp
48 #ifdef MEZZ_USEATOMICSTODECACHECOMPLETEWORK
62 #ifdef _MEZZ_THREAD_WIN32_
64 #pragma warning( disable : 4706) // Disable Legitimate assignment in a WorkUnit acquisition loops
78 void ThreadWork(
void* ThreadStorage)
80 DefaultThreadSpecificStorage::Type& Storage = *((DefaultThreadSpecificStorage::Type*)ThreadStorage);
81 FrameScheduler& FS = *(Storage.GetFrameScheduler());
82 iWorkUnit* CurrentUnit;
84 #ifdef MEZZ_USEBARRIERSEACHFRAME
87 FS.StartFrameSync.Wait();
94 while( (CurrentUnit = FS.GetNextWorkUnit()) )
96 if(
Starting==CurrentUnit->TakeOwnerShip())
97 { CurrentUnit->operator()(Storage); }
99 }
while(!FS.AreAllWorkUnitsComplete());
101 #ifdef MEZZ_USEBARRIERSEACHFRAME
102 FS.EndFrameSync.Wait();
109 void ThreadWorkAffinity(
void* ThreadStorage)
111 DefaultThreadSpecificStorage::Type& Storage = *((DefaultThreadSpecificStorage::Type*)ThreadStorage);
112 FrameScheduler& FS = *(Storage.GetFrameScheduler());
113 iWorkUnit* CurrentUnit;
116 while( (CurrentUnit = FS.GetNextWorkUnitAffinity()) )
118 if(
Starting==CurrentUnit->TakeOwnerShip())
119 { CurrentUnit->operator()(Storage); }
122 while(!FS.AreAllWorkUnitsComplete());
129 void FrameScheduler::CleanUpThreads()
131 #ifdef MEZZ_USEBARRIERSEACHFRAME
133 StartFrameSync.SetThreadSyncCount(0);
134 EndFrameSync.SetThreadSyncCount(0);
140 void FrameScheduler::DeleteThreads()
142 for(std::vector<Thread*>::iterator Iter = Threads.begin(); Iter!=Threads.end(); ++Iter)
146 void FrameScheduler::UpdateDependentGraph(
const std::vector<WorkUnitKey>& Units)
149 for(std::vector<WorkUnitKey>::const_iterator Iter=Units.begin(); Iter!=Units.end(); ++Iter)
152 size_t Max = Iter->Unit->GetImmediateDependencyCount();
153 for(
size_t Counter=0; Counter<Max; ++Counter)
154 { DependentGraph[Iter->Unit->GetDependency(Counter)].insert(Iter->Unit); }
158 void FrameScheduler::UpdateWorkUnitKeys(std::vector<WorkUnitKey> &Units)
160 for(std::vector<WorkUnitKey>::iterator Iter=Units.begin(); Iter!=Units.end(); ++Iter)
161 { *Iter = Iter->Unit->GetSortingKey(*
this); }
166 FrameScheduler::FrameScheduler(std::fstream *_LogDestination,
Whole StartingThreadCount) :
171 LogDestination(_LogDestination ? _LogDestination : new std::fstream(
"Mezzanine.log", std::ios::out | std::ios::trunc)),
174 StartFrameSync(StartingThreadCount),
175 EndFrameSync(StartingThreadCount),
182 CurrentThreadCount(StartingThreadCount),
183 FrameCount(0), TargetFrameLength(16666),
184 TimingCostAllowance(0),
185 MainThreadID(this_thread::
get_id()),
186 LoggingToAnOwnedFileStream(true),
190 GetLog() <<
"<MezzanineLog>" << std::endl;
198 LogDestination(_LogDestination),
201 StartFrameSync(StartingThreadCount),
202 EndFrameSync(StartingThreadCount),
209 CurrentThreadCount(StartingThreadCount),
210 FrameCount(0), TargetFrameLength(16666),
211 TimingCostAllowance(0),
212 MainThreadID(this_thread::
get_id()),
213 LoggingToAnOwnedFileStream(false),
217 (*LogDestination) <<
"<MezzanineLog>" << std::endl;
225 (*LogDestination) <<
"</MezzanineLog>" << std::endl;
234 {
delete Iter->Unit; }
237 for(std::vector<DefaultThreadSpecificStorage::Type*>::iterator Iter =
Resources.begin(); Iter!=
Resources.end(); ++Iter)
248 (*this->
LogDestination) <<
"<WorkUnitMainInsertion ID=\"" << hex << MoreWork <<
"\" Name=\"" << WorkUnitName <<
"\" />" << endl;
255 (*this->
LogDestination) <<
"<WorkUnitAffinityInsertion ID=\"" << hex << MoreWork <<
"\" Name=\"" << WorkUnitName <<
"\" />" << endl;
262 (*this->
LogDestination) <<
"<WorkUnitMonopolyInsertion ID=\"" << hex << MoreWork <<
"\" Name=\"" << WorkUnitName <<
"\" />" << endl;
267 if(UpdateDependentGraph_)
278 if(UpdateDependentGraph_)
300 if(Iter->Unit == LessWork)
303 { RemovalTarget = Iter;}
305 { std::swap (*Iter,*(Iter+1)); }
307 Iter->Unit->RemoveDependency(LessWork);
315 { Iter->Unit->RemoveDependency(LessWork); }
326 if(Iter->Unit == LessWork)
329 { RemovalTarget = Iter;}
331 { std::swap (*Iter,*(Iter+1)); }
333 Iter->Unit->RemoveDependency(LessWork);
341 { Iter->Unit->RemoveDependency(LessWork); }
350 { Iter->Unit->RemoveDependency(LessWork); }
355 { Iter->Unit->RemoveDependency(LessWork); }
375 if(UsedCachedDepedentGraph)
388 #ifdef MEZZ_USEATOMICSTODECACHECOMPLETEWORK
389 bool CompleteSoFar =
true;
390 Int32 CurrentRun = DecacheMain;
393 if (
NotStarted==Iter->Unit->GetRunningState())
395 if(Iter->Unit->IsEveryDependencyComplete())
396 {
return Iter->Unit; }
403 if(
Complete==Iter->Unit->GetRunningState())
410 if (
NotStarted==Iter->Unit->GetRunningState())
412 if(Iter->Unit->IsEveryDependencyComplete())
413 {
return Iter->Unit; }
423 #ifdef MEZZ_USEATOMICSTODECACHECOMPLETEWORK
424 bool CompleteSoFar =
true;
425 Int32 CurrentRun = DecacheAffinity;
428 if (
NotStarted==Iter->Unit->GetRunningState())
430 if(Iter->Unit->IsEveryDependencyComplete())
431 {
return Iter->Unit; }
438 if(
Complete==Iter->Unit->GetRunningState())
445 if (
NotStarted==Iter->Unit->GetRunningState())
447 if(Iter->Unit->IsEveryDependencyComplete())
448 {
return Iter->Unit; }
461 if(
Complete!=Iter->Unit->GetRunningState())
467 if(
Complete!=Iter->Unit->GetRunningState())
538 { (*Iter)->operator()(*(
Resources.at(0))); }
544 #ifdef MEZZ_USEBARRIERSEACHFRAME
552 Resources[Count]->SwapAllBufferedResources();
556 StartFrameSync.Wait();
562 Resources[Count]->SwapAllBufferedResources();
570 Resources[0]->SwapAllBufferedResources();
579 #ifdef MEZZ_USEBARRIERSEACHFRAME
582 for(std::vector<Thread*>::iterator Iter=
Threads.begin(); Iter!=
Threads.end(); ++Iter)
605 { Iter->Unit->PrepareForNextFrame(); }
607 { Iter->Unit->PrepareForNextFrame(); }
608 #ifdef MEZZ_USEATOMICSTODECACHECOMPLETEWORK
617 Whole TargetFrameEnd;
651 std::vector<Resource*>::iterator Results =
Resources.begin();
655 for(std::vector<Thread*>::iterator Iter=
Threads.begin(); Iter!=
Threads.end(); ++Iter)
658 if ( (*Iter)->get_id()==ID)
682 Whole MainCount = Iter->Unit->GetImmediateDependencyCount();
683 for(
Whole Counter = 0; Counter<MainCount; Counter++)
686 "Unit=\"" << hex << Iter->Unit
687 <<
"\" DependsOn=\"" << Iter->Unit->GetDependency(Counter) <<
"\" "
694 Whole AffinityCount = Iter->Unit->GetImmediateDependencyCount();
695 for(
Whole Counter = 0; Counter<AffinityCount; Counter++)
698 "Unit=\"" << hex << Iter->Unit
699 <<
"\" DependsOn=\"" << Iter->Unit->GetDependency(Counter) <<
"\" "
706 Whole MonopolyCount = (*Iter)->GetImmediateDependencyCount();
707 for(
Whole Counter = 0; Counter<MonopolyCount; Counter++)
710 "Unit=\"" << hex << (*Iter)
711 <<
"\" DependsOn=\"" << (*Iter)->GetDependency(Counter) <<
"\" "