Spinning Topp Logo BlackTopp Studios
inc
Public Types | Public Member Functions | Protected Types | Protected Member Functions | Static Protected Member Functions | Protected Attributes | Static 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...
 
void ChangeLogTarget (std::ostream *LogTarget)
 
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 Boole ForceLogFlush ()
 Forces the FrameScheduler to find Its LogAggregator and make it flush the logs if it can. 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...
 
void SetErrorHandler ()
 When Things crash the logs still needs to be flushed and other resources cleaned. This sets a function for when std::terminate is called.
 
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...
 
void SwapBufferedResources ()
 This takes all active buffered resources offline (therfore available for async processing) and makes all the offline resources active for normal thread use. 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.
 
virtual LogAggregatorGetLogAggregator ()
 Get the Log aggregation work unit if one exists for emergency loggin purposes only. More...
 
void InstallLog (std::ostream *LogTarget)
 
void RemoveLog ()
 
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...
 

Static Protected Member Functions

static void AddErrorScheduler (FrameScheduler *SchedulerToAdd)
 Add this scheduler to the list that will log in the event of an unhand;ed exception. More...
 
static void RemoveErrorScheduler (FrameScheduler *SchedulerToRemove)
 Remove the passed scheduler from the list that will log in the event of an unhand;ed exception. 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 and error handling 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.
 

Static Protected Attributes

static std::vector< FrameScheduler * > FrameSchedulers
 A list frame schedulers, for use in the event of an error.
 
static SpinLock FrameSchedulersLock
 A lock that protects the list frame schedulers, for use in the event of an error.
 

Friends

class LogAggregator
 
void TerminateHandler ()
 
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 71 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 177 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 203 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 232 of file framescheduler.cpp.

Member Function Documentation

void Mezzanine::Threading::FrameScheduler::AddErrorScheduler ( FrameScheduler SchedulerToAdd)
staticprotected

Add this scheduler to the list that will log in the event of an unhand;ed exception.

Parameters
SchedulerToAddThe scheduler to add to the list list that will be cleaned up in the event of an error.

Definition at line 135 of file framescheduler.cpp.

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 255 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 248 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 262 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 460 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

Definition at line 545 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 650 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 529 of file framescheduler.cpp.

Boole Mezzanine::Threading::FrameScheduler::ForceLogFlush ( )
virtual

Forces the FrameScheduler to find Its LogAggregator and make it flush the logs if it can.

Warning
This is not thread safe at all. Any time during the frame using this can break everything.
Returns
This return True if it flushed the logs and false otherwise.

Definition at line 751 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 511 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 377 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 488 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 491 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 520 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 523 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 517 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 696 of file framescheduler.cpp.

LogAggregator * Mezzanine::Threading::FrameScheduler::GetLogAggregator ( )
protectedvirtual

Get the Log aggregation work unit if one exists for emergency loggin purposes only.

Warning
This is not thread safe at all. Any time during the frame using this can break everything.

Use by the termination handler in the even of an uncaught exception. This should also be avoided because It is is implemented a linear search over every workunit and returns the first one derived from LogAggregator.

Returns
A null pointer or a pointer to a workunit that aggregates if it exists.

Definition at line 724 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 390 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 425 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 514 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 505 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 627 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 642 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 618 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 621 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 615 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 559 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 653 of file framescheduler.cpp.

void Mezzanine::Threading::FrameScheduler::RemoveErrorScheduler ( FrameScheduler SchedulerToRemove)
staticprotected

Remove the passed scheduler from the list that will log in the event of an unhand;ed exception.

Parameters
SchedulerToRemoveThe scheduler to remove from the list list that will be cleaned up in the event of an error.

Definition at line 141 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 323 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 297 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 349 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 579 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 539 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 551 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 502 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 494 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 508 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 280 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 291 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 269 of file framescheduler.cpp.

void Mezzanine::Threading::FrameScheduler::SwapBufferedResources ( )

This takes all active buffered resources offline (therfore available for async processing) and makes all the offline resources active for normal thread use.

Warning
This is not thread safe at all. Any time during the frame using this can break everything.

Definition at line 768 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 157 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 478 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 169 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 592 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 182 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 200 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 133 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 137 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: