MezzanineEngine 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Public Types | Public Member Functions | Protected Types | Protected Member Functions | Protected Attributes | Friends | List of all members
Mezzanine::Threading::FrameScheduler Class Reference

This is central object in this algorithm, it is responsible for spawning threads and managing the order that work units are executed. More...

#include <framescheduler.h>

+ Collaboration diagram for Mezzanine::Threading::FrameScheduler:

Public Types

typedef
DefaultThreadSpecificStorage::Type 
Resource
 The kind of Resource the frame scheduler will use.
 

Public Member Functions

 FrameScheduler (std::fstream *_LogDestination=0, Whole StartingThreadCount=GetCPUCount())
 Create a Framescheduler that owns a filestream for logging. More...
 
 FrameScheduler (std::ostream *_LogDestination, Whole StartingThreadCount=GetCPUCount())
 Create a Framescheduler, that logs to an unowned stream. More...
 
virtual ~FrameScheduler ()
 Destructor. More...
 
virtual void AddWorkUnitAffinity (iWorkUnit *MoreWork, const String &WorkUnitName)
 Add a normal Mezzanine::Threading::iWorkUnit to this For scheduling. More...
 
virtual void AddWorkUnitMain (iWorkUnit *MoreWork, const String &WorkUnitName)
 Add a normal Mezzanine::Threading::iWorkUnit to this For fcheduling. More...
 
virtual void AddWorkUnitMonopoly (MonopolyWorkUnit *MoreWork, const String &WorkUnitName)
 Add a MonopolyWorkUnit for execution at the beginning of the frame. More...
 
virtual bool AreAllWorkUnitsComplete ()
 Is the work of the frame done? More...
 
virtual void CreateThreads ()
 This is the 2nd step (of 6) in a frame. More...
 
void DependenciesChanged (bool Changed=true)
 Indicate to the framescheduler if dependencies need to be logged. More...
 
virtual void DoOneFrame ()
 Do one frame worth of work. More...
 
virtual MaxInt GetCurrentFrameStart () const
 When did this frame start? More...
 
virtual Whole GetDependentCountOf (iWorkUnit *Work, bool UsedCachedDepedentGraph=false)
 How many other WorkUnit instances must wait on this one. More...
 
virtual Whole GetFrameCount () const
 Get the current number of frames that have elapsed. More...
 
virtual Whole GetFrameLength () const
 Get the desired length of a frame. More...
 
DefaultRollingAverage< Whole >
::Type & 
GetFrameTimeRollingAverage ()
 Get The complete record of the durations of the last few frames. More...
 
Whole GetLastFrameTime () const
 How long was the previous frame? More...
 
Whole GetLastPauseTime () const
 How long was the pause, if any, last frame? More...
 
std::ostream & GetLog ()
 Get the endpoint for the logs. More...
 
virtual iWorkUnitGetNextWorkUnit ()
 Gets the next available workunit for execution. More...
 
virtual iWorkUnitGetNextWorkUnitAffinity ()
 Just like GetNextWorkUnit except that it also searches through and prioritizes work units with affinity too. More...
 
DefaultRollingAverage< Whole >
::Type & 
GetPauseTimeRollingAverage ()
 Get The complete record of the past durations of the Pauses Each frame. More...
 
virtual Whole GetThreadCount ()
 Get the amount of threads that will be used to execute WorkUnits a the start of the next frame. More...
 
ResourceGetThreadResource (ThreadId ID=this_thread::get_id())
 Get the Resource to go with a thread of a given ID. More...
 
LoggerGetThreadUsableLogger (ThreadId ID=this_thread::get_id())
 Get the logger safe to use this thread. More...
 
Whole GetWorkUnitAffinityCount () const
 Returns the amount of iWorkUnit ready to be scheduled in the Affinity pool. More...
 
Whole GetWorkUnitMainCount () const
 Returns the amount of iWorkUnit ready to be scheduled in the Main pool. More...
 
Whole GetWorkUnitMonopolyCount () const
 Returns the amount of MonopolyWorkUnit ready to be scheduled. More...
 
void JoinAllThreads ()
 This is the 4th step (of 6) in a frame. More...
 
void LogDependencies ()
 This sends the dependencies to the LogDestination (Skipping any thread specific resources) More...
 
virtual void RemoveWorkUnitAffinity (iWorkUnit *LessWork)
 Remove a WorkUnit from the Affinity pool of WorkUnits (and not from the Main group or MonpolyWorkUnits). More...
 
virtual void RemoveWorkUnitMain (iWorkUnit *LessWork)
 Remove a WorkUnit from the main pool of WorkUnits (and not from the groups of Affinity or MonpolyWorkUnits). More...
 
virtual void RemoveWorkUnitMonopoly (MonopolyWorkUnit *LessWork)
 Remove a WorkUnit from the Monopoly pool of WorkUnits (and not from the Main or Affinity group). More...
 
virtual void ResetAllWorkUnits ()
 This is the 5th step (of 6) in a frame. More...
 
virtual void RunAllMonopolies ()
 This is the 1st step (of 6) in a frame. More...
 
virtual void RunMainThreadWork ()
 This is the 3rd step (of 6) in a frame. More...
 
virtual void SetFrameLength (const Whole &FrameLength)
 Set the Desired length of a frame in microseconds. More...
 
virtual void SetFrameRate (const Whole &FrameRate)
 Set the desired Frate rate. More...
 
virtual void SetThreadCount (const Whole &NewThreadCount)
 Set the amount of threads to use. More...
 
virtual void SortWorkUnitsAffinity (bool UpdateDependentGraph_=true)
 Sort the WorkUnits that must run on the main thread to allow them to be used more efficiently in the next frame executed. More...
 
virtual void SortWorkUnitsAll (bool UpdateDependentGraph_=true)
 Sort all the WorkUnits that must run on the main thread to allow them to be used more efficiently in the next frame executed. More...
 
virtual void SortWorkUnitsMain (bool UpdateDependentGraph_=true)
 Sort the the main pool of WorkUnits to allow them to be used more efficiently in the next frame executed. More...
 
virtual void UpdateDependentGraph ()
 Create a reverse depedent graph that can be used for sorting Mezzanine::Threading::iWorkUnit "iWorkUnit"s to optimize execution each frame. More...
 
void WaitUntilNextFrame ()
 This is the final step (of 6) in a frame. More...
 

Protected Types

typedef std::vector
< WorkUnitKey >
::const_iterator 
ConstIteratorAffinity
 A const iterator suitable for iterating over the main pool of work units.
 
typedef std::vector
< WorkUnitKey >
::const_iterator 
ConstIteratorMain
 A const iterator suitable for iterating over the main pool of work units.
 
typedef std::vector
< MonopolyWorkUnit * >
::const_iterator 
ConstIteratorMonopoly
 A const iterator suitable for iterating over the main pool of work units.
 
typedef std::map< iWorkUnit
*, std::set< iWorkUnit * > > 
DependentGraphType
 A structure designed to minimalistically represent Dependency and Reverse Dependency Graphs in work units.
 
typedef std::vector
< WorkUnitKey >::iterator 
IteratorAffinity
 An iterator suitable for iterating over the main pool of work units.
 
typedef std::vector
< WorkUnitKey >::iterator 
IteratorMain
 An iterator suitable for iterating over the main pool of work units.
 
typedef std::vector
< MonopolyWorkUnit * >
::iterator 
IteratorMonoply
 An iterator suitable for iterating over the main pool of work units.
 

Protected Member Functions

void CleanUpThreads ()
 Used in destruction to tear down threads.
 
void DeleteThreads ()
 Simply iterates over and deletes everything in Threads.
 
void UpdateDependentGraph (const std::vector< WorkUnitKey > &Units)
 Adds the dependencies of the iWorkUnits in the passed containter to the the internal reverse dependency graph. More...
 
void UpdateWorkUnitKeys (std::vector< WorkUnitKey > &Units)
 Iterate over the passed container of WorkUnitKeys and refresh them with the correct data from their respective iWorkUnits. More...
 

Protected Attributes

MaxInt CurrentFrameStart
 What time did the current Frame Start at.
 
MaxInt CurrentPauseStart
 What time did the current Frame Start at.
 
Whole CurrentThreadCount
 How many threads will this try to execute with in the next frame.
 
DependentGraphType DependentGraph
 This structure allows reverse lookup of dependencies. More...
 
Whole FrameCount
 Used to store a count of frames from the begining of game execution. More...
 
DefaultRollingAverage< Whole >
::Type 
FrameTimeLog
 A rolling average of Frame times.
 
std::ostream * LogDestination
 When the logs are aggregated, this is where they are sent.
 
bool LoggingToAnOwnedFileStream
 Set based on which constructor is called, and only used during destruction.
 
SpinLock LogResources
 Protects DoubleBufferedResources during creation from being accessed by the LogAggregator.
 
ThreadId MainThreadID
 For some task it is important to know the ID of the main thread.
 
bool NeedToLogDeps
 Brief Do we have to log ependencies have they changed since last logged? More...
 
DefaultRollingAverage< Whole >
::Type 
PauseTimeLog
 A rolling average of Frame Pause times.
 
std::vector< Resource * > Resources
 This maintains ownership of all the thread specific resources. More...
 
WorkSorterSorter
 If this pointer is non-zero then the WorkSorter it points at will be used to sort WorkUnits.
 
Whole TargetFrameLength
 The Maximum frame rate this algorithm should run at.
 
std::vector< Thread * > Threads
 A way to track an arbitrary number of threads. More...
 
Integer TimingCostAllowance
 To prevent frame time drift this many microseconds is subtracted from the wait period to allow time for calculations.
 
std::vector< WorkUnitKeyWorkUnitsAffinity
 A collection of iWorkUnits that must be run on the main thread. More...
 
std::vector< WorkUnitKeyWorkUnitsMain
 A collection of all the work units that are not Monopolies and do not have affinity for a given thread. More...
 
std::vector< MonopolyWorkUnit * > WorkUnitsMonopolies
 A collection of all the monopolies this scheduler must run and keep ownership of.
 

Friends

class LogAggregator
 
class WorkSorter
 

Detailed Description

This is central object in this algorithm, it is responsible for spawning threads and managing the order that work units are executed.

For a detailed description of the Algorithm this implements see the Algorithm section on the Main page.

Definition at line 75 of file framescheduler.h.

Constructor & Destructor Documentation

Mezzanine::Threading::FrameScheduler::FrameScheduler ( std::fstream *  _LogDestination = 0,
Whole  StartingThreadCount = GetCPUCount() 
)

Create a Framescheduler that owns a filestream for logging.

Parameters
_LogDestinationAn fstream that will be closed and deleted when this framescheduler is destroyed. Defaults to a new Filestream Logging to local file.
StartingThreadCountHow many threads. Defaults to the value returned by GetCPUCount().
Warning
This must be constructed from the Main(only) thread for any features with thread affinity to work correctly.

Definition at line 166 of file framescheduler.cpp.

Mezzanine::Threading::FrameScheduler::FrameScheduler ( std::ostream *  _LogDestination,
Whole  StartingThreadCount = GetCPUCount() 
)

Create a Framescheduler, that logs to an unowned stream.

Parameters
_LogDestinationAny stream, other than an fstream, and it will be closed (not deleted) when this frame scheduler is destroyed.
StartingThreadCountHow many threads. Defaults to the value returned by GetCPUCount().
Warning
This must be constructed from the Main(only) thread for any features with thread affinity to work correctly.

Definition at line 193 of file framescheduler.cpp.

Mezzanine::Threading::FrameScheduler::~FrameScheduler ( )
virtual

Destructor.

Deletes all std::fstream, WorkUnit, MonopolyWorkUnit and ThreadSpecificStorage objects that this was passed or created during its lifetime.

Definition at line 221 of file framescheduler.cpp.

Member Function Documentation

void Mezzanine::Threading::FrameScheduler::AddWorkUnitAffinity ( iWorkUnit MoreWork,
const String WorkUnitName 
)
virtual

Add a normal Mezzanine::Threading::iWorkUnit to this For scheduling.

Parameters
MoreWorkA pointer the the WorkUnit, that the FrameScheduler will take ownership of, and schedule for work.
WorkUnitNameA name to uniquely identify this work unit in the logs

Definition at line 251 of file framescheduler.cpp.

void Mezzanine::Threading::FrameScheduler::AddWorkUnitMain ( iWorkUnit MoreWork,
const String WorkUnitName 
)
virtual

Add a normal Mezzanine::Threading::iWorkUnit to this For fcheduling.

Parameters
MoreWorkA pointer the the WorkUnit, that the FrameScheduler will take ownership of, and schedule for work.
WorkUnitNameA name to uniquely identify this work unit in the logs

Definition at line 244 of file framescheduler.cpp.

void Mezzanine::Threading::FrameScheduler::AddWorkUnitMonopoly ( MonopolyWorkUnit MoreWork,
const String WorkUnitName 
)
virtual

Add a MonopolyWorkUnit for execution at the beginning of the frame.

Parameters
MoreWorkA pointer to the MonopolyWorkUnit to add.
WorkUnitNameA name to uniquely identify this work unit in the logs

Definition at line 258 of file framescheduler.cpp.

bool Mezzanine::Threading::FrameScheduler::AreAllWorkUnitsComplete ( )
virtual

Is the work of the frame done?

Returns
This returns true if all the WorkUnit instances are complete, and false otherwise.

Definition at line 456 of file framescheduler.cpp.

void Mezzanine::Threading::FrameScheduler::CreateThreads ( )
virtual

This is the 2nd step (of 6) in a frame.

This starts all the threads on their work. Until JoinAllThreads() is called some thread may still be working. This thread starts the man scheduling algorithm working on every thread except the calling thread. This call does not block and tends to return very quickly.

This checks the amount of threads as set by SetFrameLength. It creates any ThreadSpecificStorage instances required and creates threads if they are required. SwapAllBufferedResources() Is called on each ThreadSpecificStorage before being passed into the thread. If extra double buffered resources are required per thread and they need to be swapped each frame, SwapAllBufferedResources() should be inherited or adjusted to account for these new resources.

If the build option MEZZ_USEBARRIERSEACHFRAME Mezz_MinimizeThreadsEachFrame was enabled then this will reuse threads from previous frames, otherwise this will re-use thread specific resources and create a new set of threads. Re-use of threads is synchronized with the Barrier StartFrameSync member variable. It is unclear, and likely platform specific, which option has better performance characteristics.

Warning
While this is running any changes to the FrameScheduler must be made with an atomic operation like the AtomicCompareAndSwap32 or AtomicAdd. Any other threads workunit may be accessed as any normal shared data, but Thread specific Resources should not be accessed while this runs.
This uses a Spinlock to prevent accesss to ThreadSpecificResources that the LogAggregator needs. This is unlocked in RunMainThreadWork.

Definition at line 541 of file framescheduler.cpp.

void Mezzanine::Threading::FrameScheduler::DependenciesChanged ( bool  Changed = true)

Indicate to the framescheduler if dependencies need to be logged.

Parameters
ChangedDefaults to true, and sets a flag that tells the framescheduler if it needs to log dependencies.

If false is passed, this prevents the FrameScheduler from logging until the next change.

Definition at line 672 of file framescheduler.cpp.

void Mezzanine::Threading::FrameScheduler::DoOneFrame ( )
virtual

Do one frame worth of work.

This just calls the following functions in the order presented:

This can be replaced calling these functions in this order. You can add any other calls you like between the various stages. This can be done to allow maximum integration with existing projects. It can also be used to prevent a giant migration and replace it with a piecemeal upgrade.

Warning
Do not call this on an unsorted set of WorkUnits. Use FrameScheduler::SortWorkUnitsAll() and the DependentGraph to sort WorkUnits after they are inserted into the frame scheduler for the first time. This doesn't need to happen each frame, just after any new work units are added or removed (except Monopolies) or you want to take the most recent performance number into account.

Definition at line 525 of file framescheduler.cpp.

MaxInt Mezzanine::Threading::FrameScheduler::GetCurrentFrameStart ( ) const
virtual

When did this frame start?

Returns
A MaxInt with the timestamp corresponding to when this frame started.

Definition at line 507 of file framescheduler.cpp.

Whole Mezzanine::Threading::FrameScheduler::GetDependentCountOf ( iWorkUnit Work,
bool  UsedCachedDepedentGraph = false 
)
virtual

How many other WorkUnit instances must wait on this one.

Parameters
WorkThe WorkUnit to get the updated count of.
UsedCachedDepedentGraphIf the cache is already up to date leaving this false, and not updating it can save significant time.
Returns
A Whole Number representing the amount of WorkUnit instances that cannot start until this finishes.

Definition at line 373 of file framescheduler.cpp.

Whole Mezzanine::Threading::FrameScheduler::GetFrameCount ( ) const
virtual

Get the current number of frames that have elapsed.

Returns
A Whole containing the frame count.

Definition at line 484 of file framescheduler.cpp.

Whole Mezzanine::Threading::FrameScheduler::GetFrameLength ( ) const
virtual

Get the desired length of a frame.

Returns
The desired frame length as a Whole in Microseconds

Definition at line 487 of file framescheduler.cpp.

DefaultRollingAverage< Whole >::Type & Mezzanine::Threading::FrameScheduler::GetFrameTimeRollingAverage ( )

Get The complete record of the durations of the last few frames.

Returns
A Rolling average of the default type.

Definition at line 516 of file framescheduler.cpp.

Whole Mezzanine::Threading::FrameScheduler::GetLastFrameTime ( ) const

How long was the previous frame?

Returns
A Whole containing the duration of the last frame.

Definition at line 519 of file framescheduler.cpp.

Whole Mezzanine::Threading::FrameScheduler::GetLastPauseTime ( ) const

How long was the pause, if any, last frame?

Returns
A whole containing the duration of the last pause.

Definition at line 513 of file framescheduler.cpp.

std::ostream & Mezzanine::Threading::FrameScheduler::GetLog ( )

Get the endpoint for the logs.

Warning
This is not thread safe at all. Any time during the frame using this can send gibberish to the log. Use GetThreadUsableLogger instead.
Returns
An std:ostream reference which can be streamed to commit log entries.

Definition at line 718 of file framescheduler.cpp.

iWorkUnit * Mezzanine::Threading::FrameScheduler::GetNextWorkUnit ( )
virtual

Gets the next available workunit for execution.

This finds the next available WorkUnit which has not started execution, has no dependencies that have not complete, has the most WorkUnits that depend on it (has the highest runtime in the case of a tie).

Returns
A pointer to the WorkUnit that could be executed or a null pointer if that could not be acquired. This does not give ownership of that WorkUnit.

Definition at line 386 of file framescheduler.cpp.

iWorkUnit * Mezzanine::Threading::FrameScheduler::GetNextWorkUnitAffinity ( )
virtual

Just like GetNextWorkUnit except that it also searches through and prioritizes work units with affinity too.

Returns
A pointer to the WorkUnit that could be executed in the main thread or a null pointer if that could not be acquired. This does not give ownership of that WorkUnit.

Definition at line 421 of file framescheduler.cpp.

DefaultRollingAverage< Whole >::Type & Mezzanine::Threading::FrameScheduler::GetPauseTimeRollingAverage ( )

Get The complete record of the past durations of the Pauses Each frame.

Returns
A Rolling average of the default type.

Definition at line 510 of file framescheduler.cpp.

Whole Mezzanine::Threading::FrameScheduler::GetThreadCount ( )
virtual

Get the amount of threads that will be used to execute WorkUnits a the start of the next frame.

Returns
A Whole with the current desired thread count.

Definition at line 501 of file framescheduler.cpp.

FrameScheduler::Resource * Mezzanine::Threading::FrameScheduler::GetThreadResource ( ThreadId  ID = this_thread::get_id())

Get the Resource to go with a thread of a given ID.

This gets the Resource that goes with a given thread by performing a linear search through the available threads.

This is cheap computationly but will likely perform much slower than other methods of getting the resource, because the ID is unlikely be be cached and it may require a system call to retrieve. If used consider wrapping it in #ifdef MEZZ_DEBUG + #endif to disable for release builds.

Parameters
IDThis uses the current Threads ID by default but can search for any thread.
Returns
A pointer to ThreadSpecificResource or a null pointer on error.
Warning
The thread that 'owns' this resource could do just about anything with it while the frame is running, so this should only outside a frame and carefully or inside a frame and only from the owning thread.

Definition at line 649 of file framescheduler.cpp.

Logger * Mezzanine::Threading::FrameScheduler::GetThreadUsableLogger ( ThreadId  ID = this_thread::get_id())

Get the logger safe to use this thread.

Warning
This is written in terms of GetThreadResource and has all the same limitations.
Parameters
IDThis uses the current Threads ID by default but can search for any thread.
Returns
A null pointer if there is an error or a pointer to the Logger that goes with the passed Thread::Id

Definition at line 664 of file framescheduler.cpp.

Whole Mezzanine::Threading::FrameScheduler::GetWorkUnitAffinityCount ( ) const

Returns the amount of iWorkUnit ready to be scheduled in the Affinity pool.

Returns
A Whole containing this amount

Definition at line 640 of file framescheduler.cpp.

Whole Mezzanine::Threading::FrameScheduler::GetWorkUnitMainCount ( ) const

Returns the amount of iWorkUnit ready to be scheduled in the Main pool.

Returns
A Whole containing this amount

Definition at line 643 of file framescheduler.cpp.

Whole Mezzanine::Threading::FrameScheduler::GetWorkUnitMonopolyCount ( ) const

Returns the amount of MonopolyWorkUnit ready to be scheduled.

Returns
A Whole containing this amount

Definition at line 637 of file framescheduler.cpp.

void Mezzanine::Threading::FrameScheduler::JoinAllThreads ( )

This is the 4th step (of 6) in a frame.

Used when completing the work of a frame, to cleaning end the execution of the threads. This function will only return when all the work started by CreateThreads() and RunMainThreadWork() have completed. This call blocks until all threads executing. If a thread takes too long then this simply waits for it to finish. No attempt is made to timeout or interupt a work unit before it finishes.

Definition at line 577 of file framescheduler.cpp.

void Mezzanine::Threading::FrameScheduler::LogDependencies ( )

This sends the dependencies to the LogDestination (Skipping any thread specific resources)

Warning
This should not be executed during the frame, unless the FrameScheduler is calling it.

Definition at line 675 of file framescheduler.cpp.

void Mezzanine::Threading::FrameScheduler::RemoveWorkUnitAffinity ( iWorkUnit LessWork)
virtual

Remove a WorkUnit from the Affinity pool of WorkUnits (and not from the Main group or MonpolyWorkUnits).

Parameters
LessWorkA pointer to the workunit the calling coding will reclaim ownership of and will no longer be scheduled, and have its dependencies removed.

Definition at line 319 of file framescheduler.cpp.

void Mezzanine::Threading::FrameScheduler::RemoveWorkUnitMain ( iWorkUnit LessWork)
virtual

Remove a WorkUnit from the main pool of WorkUnits (and not from the groups of Affinity or MonpolyWorkUnits).

Parameters
LessWorkA pointer to the workunit the calling coding will reclaim ownership of and will no longer be scheduled, and have its dependencies removed.

Definition at line 293 of file framescheduler.cpp.

void Mezzanine::Threading::FrameScheduler::RemoveWorkUnitMonopoly ( MonopolyWorkUnit LessWork)
virtual

Remove a WorkUnit from the Monopoly pool of WorkUnits (and not from the Main or Affinity group).

Parameters
LessWorkA pointer to the MonopolyWorkUnit the calling coding will reclaim ownership of and will no longer be scheduled, and have its dependencies removed.

Definition at line 345 of file framescheduler.cpp.

void Mezzanine::Threading::FrameScheduler::ResetAllWorkUnits ( )
virtual

This is the 5th step (of 6) in a frame.

Take any steps required to prepare all owned WorkUnits for execution next frame. This usually includes reseting all the work units running state to NotStarted. This can cause work units to be executed multiple times if a thread is still executing.

Todo:
could be replace with a parallel for, or a monopoly

Definition at line 601 of file framescheduler.cpp.

void Mezzanine::Threading::FrameScheduler::RunAllMonopolies ( )
virtual

This is the 1st step (of 6) in a frame.

This iterates over the listing of MonopolyWorkUnits and executes each one in the order it was added. This should be considered as consuming all available CPU time until it returns. This call blocks until execution of monopolies is complete.

Definition at line 535 of file framescheduler.cpp.

void Mezzanine::Threading::FrameScheduler::RunMainThreadWork ( )
virtual

This is the 3rd step (of 6) in a frame.

This runs the main portion of the scheduling algorithm on the main thread. This call blocks until the execution of all workunits with main thread affinity are complete and all other work units have at least started. This could return and other threads could still be working.

Before executing any work this checks a flag to determine if it should log the current work unit dependencies. After this check or logging has occurred this then this releases the spinlock on the log, so there is a chance of brief contention between a LogAggregator and this if depedencies have just changed or change frequently.

Warning
This uses a Spinlock to prevent accesss to ThreadSpecificResources that the LogAggregator needs. This should be called immediately after CreateThreads to minimize any possible contention.

Definition at line 568 of file framescheduler.cpp.

void Mezzanine::Threading::FrameScheduler::SetFrameLength ( const Whole FrameLength)
virtual

Set the Desired length of a frame in microseconds.

Parameters
FrameLengthThe desired minimum length of the frame. Use 0 for no pause.

Definition at line 498 of file framescheduler.cpp.

void Mezzanine::Threading::FrameScheduler::SetFrameRate ( const Whole FrameRate)
virtual

Set the desired Frate rate.

Parameters
FrameRatein frames per second

Defaults to 60, to maximize smoothmess of execution (no human can see that fast), while not killing battery life. This is a maximum framerate, if WorkUnits take too long to execute this will not make them finish faster. This controls a delay to prevent the machine's resources from being completely tapped.

Set this to 0 to never pause and run as fast as possible.

Returns
A Whole containing the Target frame rate.

Definition at line 490 of file framescheduler.cpp.

void Mezzanine::Threading::FrameScheduler::SetThreadCount ( const Whole NewThreadCount)
virtual

Set the amount of threads to use.

Parameters
NewThreadCountThe amount of threads to use starting at the begining of the next frame.
Note
Currently the thread count cannot be reduced if Mezz_MinimizeThreadsEachFrame is selected in cmake configuration.

Definition at line 504 of file framescheduler.cpp.

void Mezzanine::Threading::FrameScheduler::SortWorkUnitsAffinity ( bool  UpdateDependentGraph_ = true)
virtual

Sort the WorkUnits that must run on the main thread to allow them to be used more efficiently in the next frame executed.

Parameters
UpdateDependentGraph_Should the internal cache of reverse dependents be updated.

See DependentGraph for the appropriate times to use this.

Definition at line 276 of file framescheduler.cpp.

void Mezzanine::Threading::FrameScheduler::SortWorkUnitsAll ( bool  UpdateDependentGraph_ = true)
virtual

Sort all the WorkUnits that must run on the main thread to allow them to be used more efficiently in the next frame executed.

Parameters
UpdateDependentGraph_Should the internal cache of reverse dependents be updated.

See DependentGraph for the appropriate times to use this.

Definition at line 287 of file framescheduler.cpp.

void Mezzanine::Threading::FrameScheduler::SortWorkUnitsMain ( bool  UpdateDependentGraph_ = true)
virtual

Sort the the main pool of WorkUnits to allow them to be used more efficiently in the next frame executed.

Parameters
UpdateDependentGraph_Should the internal cache of reverse dependents be updated.

See DependentGraph for the appropriate times to use this.

Definition at line 265 of file framescheduler.cpp.

void Mezzanine::Threading::FrameScheduler::UpdateDependentGraph ( const std::vector< WorkUnitKey > &  Units)
protected

Adds the dependencies of the iWorkUnits in the passed containter to the the internal reverse dependency graph.

Parameters
UnitsThe container to examine for dependency relationships.

Definition at line 146 of file framescheduler.cpp.

void Mezzanine::Threading::FrameScheduler::UpdateDependentGraph ( )
virtual

Create a reverse depedent graph that can be used for sorting Mezzanine::Threading::iWorkUnit "iWorkUnit"s to optimize execution each frame.

This can be called automatically from any of several places that make sense by passing a boolean true value. These place include create a WorkUnitKey or Sorting the work units in a framescheduler.

Definition at line 474 of file framescheduler.cpp.

void Mezzanine::Threading::FrameScheduler::UpdateWorkUnitKeys ( std::vector< WorkUnitKey > &  Units)
protected

Iterate over the passed container of WorkUnitKeys and refresh them with the correct data from their respective iWorkUnits.

Parameters
UnitsThe container to examine for WorkUnitKey metadata.

Definition at line 158 of file framescheduler.cpp.

void Mezzanine::Threading::FrameScheduler::WaitUntilNextFrame ( )

This is the final step (of 6) in a frame.

Wait until this frame has consumed its fair share of a second. This uses the value passed in SetFrameRate to determine what portion of a second each frame should use. If a frame took too long to execute this calculates that and returns.

Wait 1/TargetFrame seconds, minus time already run. This also starts the timer for the next frame so any other logic that needs to run after the frame does not interfere with frame timing. Because This is designed to wait fractions of a second any amount of waiting above 1 second fails automaticall.

Todo:
Replace hard-code timeout with compiler/define/cmake_option

Definition at line 614 of file framescheduler.cpp.

Member Data Documentation

DependentGraphType Mezzanine::Threading::FrameScheduler::DependentGraph
protected

This structure allows reverse lookup of dependencies.

This is is a key part of the workunit sorting algorithm. This is calculated during calls to generate WorkUnitKeys,

Warning
Todo:
write this warning, it is important, but not easy to lay out.

Definition at line 119 of file framescheduler.h.

Whole Mezzanine::Threading::FrameScheduler::FrameCount
protected

Used to store a count of frames from the begining of game execution.

Warning
At 60 Frames per second this loops in 2 years, 3 months, 6 days and around 18 hours, this may not be suitable for high uptime servers. Using a MaxInt fixes this.

Definition at line 190 of file framescheduler.h.

bool Mezzanine::Threading::FrameScheduler::NeedToLogDeps
protected

Brief Do we have to log ependencies have they changed since last logged?

Since each workunit tracks its own dependencies this cannot easily be directly checked. There is a function to set and since dependencies are likely to be between adding a working and runninf a frame, adding a workunit sets this flag.

Definition at line 208 of file framescheduler.h.

std::vector<Resource*> Mezzanine::Threading::FrameScheduler::Resources
protected

This maintains ownership of all the thread specific resources.

Note
There should be the same amount or more of these than entries in the Threads vector.

Definition at line 128 of file framescheduler.h.

std::vector<Thread*> Mezzanine::Threading::FrameScheduler::Threads
protected

A way to track an arbitrary number of threads.

Note
There should never be more of these than Resources, and if there are more at the beginning of a frame the resources will be created in CreateThreads().

Definition at line 132 of file framescheduler.h.

std::vector<WorkUnitKey> Mezzanine::Threading::FrameScheduler::WorkUnitsAffinity
protected

A collection of iWorkUnits that must be run on the main thread.

This is very similar to WorkUnitsMain except that the iWorkUnits are only run in the main thread and are sorted by calls to SortWorkUnitsAll or SortWorkUnitsAffinity .

Definition at line 100 of file framescheduler.h.

std::vector<WorkUnitKey> Mezzanine::Threading::FrameScheduler::WorkUnitsMain
protected

A collection of all the work units that are not Monopolies and do not have affinity for a given thread.

This stores a sorted listing(currently a vector) of WorkUnitKey instances. These include just the metadata required for sorting iWorkUnits. Higher priority iWorkUnits are higher/later in the collection. This list is sorted by calls to SortWorkUnitsMain or SortWorkUnitsAll.

Definition at line 89 of file framescheduler.h.


The documentation for this class was generated from the following files: