Spinning Topp Logo BlackTopp Studios
inc
frameschedulerworkunits.cpp
Go to the documentation of this file.
1 // The DAGFrameScheduler is a Multi-Threaded lock free and wait free scheduling library.
2 // © Copyright 2010 - 2016 BlackTopp Studios Inc.
3 /* This file is part of The DAGFrameScheduler.
4 
5  The DAGFrameScheduler is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  The DAGFrameScheduler is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with The DAGFrameScheduler. If not, see <http://www.gnu.org/licenses/>.
17 */
18 /* The original authors have included a copy of the license specified above in the
19  'doc' folder. See 'gpl.txt'
20 */
21 /* We welcome the use of the DAGFrameScheduler to anyone, including companies who wish to
22  Build professional software and charge for their product.
23 
24  However there are some practical restrictions, so if your project involves
25  any of the following you should contact us and we will try to work something
26  out:
27  - DRM or Copy Protection of any kind(except Copyrights)
28  - Software Patents You Do Not Wish to Freely License
29  - Any Kind of Linking to Non-GPL licensed Works
30  - Are Currently In Violation of Another Copyright Holder's GPL License
31  - If You want to change our code and not add a few hundred MB of stuff to
32  your distribution
33 
34  These and other limitations could cause serious legal problems if you ignore
35  them, so it is best to simply contact us or the Free Software Foundation, if
36  you have any questions.
37 
38  Joseph Toppi - toppij@gmail.com
39  John Blackwood - makoenergy02@gmail.com
40 */
41 #ifndef _frameschedulerworkunits_cpp
42 #define _frameschedulerworkunits_cpp
43 
45 #include "doublebufferedresource.h"
46 #include "lockguard.h"
47 #include "spinlock.h"
48 
49 /// @file
50 /// @brief The implementation of any workunits the framescheduler needs to work correctly
51 
52 namespace Mezzanine
53 {
54  namespace Threading
55  {
56 
57  LogAggregator::LogAggregator() : AggregationTarget(NULL), ForcedLog(false)
58  {}
59 
61  {}
62 
64  { ForcedLog = Force; }
65 
66 
68  {
69  if(!AggregationTarget)
70  { AggregationTarget = CurrentThreadStorage.GetFrameScheduler(); }
71  lock_guard<SpinLock> g(AggregationTarget->LogResources);
72 
73  std::ostream& Log = AggregationTarget->GetLog();
74  Log << "<Frame Count=\"" << AggregationTarget->GetFrameCount() << "\">" << std::endl;
75  for(std::vector<DefaultThreadSpecificStorage::Type*>::const_iterator Iter=AggregationTarget->Resources.begin();
76  Iter!=AggregationTarget->Resources.end();
77  ++Iter)
78  {
79 
80  String Forced;
81  if(ForcedLog)
82  {
83  Forced = (" Forced=\"True\"");
84  NextFlushForced(false);
85  }
86 
87  Log << "<Thread Main=\"" << (AggregationTarget->Resources.begin()==Iter?1:0) << "\"" << Forced << " >" << std::endl
88  << (*Iter)->GetResource<DoubleBufferedLogger>(DBRLogger).GetCommittable().str()
89  << "</Thread>" << std::endl;
90  (*Iter)->GetResource<DoubleBufferedLogger>(DBRLogger).GetCommittable().str("");
91  }
92  AggregationTarget->LogResources.Unlock();
93  Log << "</Frame>" << std::endl;
94  }
95 
96 
98  { return AggregationTarget; }
99 
101  { AggregationTarget = NewTarget; }
102 
104  SortingFrequency(MEZZ_FRAMESTOTRACK*2),
105  FramesSinceLastSort(0)
106  {}
107 
109  {
112  {
113  #ifdef MEZZ_DEBUG
114  CurrentThreadStorage.GetResource<DoubleBufferedLogger>(DBRLogger).GetUsable() << "<SortWork sorting=\"0\" ThreadID=\"" << Mezzanine::Threading::this_thread::get_id() << "\" />" << std::endl;
115  #endif
117  FrameScheduler& FS = *CurrentThreadStorage.GetFrameScheduler();
118  //WorkUnitsMain.clear(); // should be cleared by the framescheduler or whatever copies this into the framscheduler
119  //WorkUnitsAffinity.clear();
120  WorkUnitsMain.clear();
121  WorkUnitsAffinity.clear();
122  WorkUnitsMain.insert(WorkUnitsMain.end(),FS.WorkUnitsMain.begin(),FS.WorkUnitsMain.end());
126  FS.Sorter = this;
127  }else{
128  #ifdef MEZZ_DEBUG
129  CurrentThreadStorage.GetResource<DoubleBufferedLogger>(DBRLogger).GetUsable() << "<SortWork sorting=\"1\" ThreadID=\"" << Mezzanine::Threading::this_thread::get_id() << "\" />" << std::endl;
130  #endif
131  }
132  }
133 
134  void WorkSorter::SetSortingFrequency(Whole FramesBetweenSorts)
135  { SortingFrequency = FramesBetweenSorts; }
136 
138  { return SortingFrequency; }
139 
140  }//Threading
141 }//Mezzanine
142 
143 
144 #endif
ThreadId MEZZ_LIB get_id()
Return the thread ID of the calling thread.
bool Boole
Generally acts a single bit, true or false.
Definition: datatypes.h:173
std::vector< WorkUnitKey > WorkUnitsAffinity
A collection of iWorkUnits that must be run on the main thread.
std::vector< Resource * > Resources
This maintains ownership of all the thread specific resources.
FrameScheduler * GetFrameScheduler()
Get a pointer to the FrameScheduler that owns this resource.
Whole FramesSinceLastSort
How long since the last sort?
virtual ~LogAggregator()
Virtual Deconstructor.
std::ostream & GetLog()
Get the endpoint for the logs.
Declares a Mutex, Mutex tools, and at least one MutexLike object.
std::vector< WorkUnitKey > WorkUnitsAffinity
A freshly sorted WorkUnitsAffinity or an empty vector.
#define MEZZ_FRAMESTOTRACK
Used to control how long frames track length and other similar values. This is controlled by the CMak...
This file defines the template double buffered resources that can be attached to a thread...
Whole SortingFrequency
1 in every this many frames Sorting happens.
LogAggregator()
Create a default log agregator with no target.
static const Whole DBRLogger
Double buffered resources are identified by a Whole which is their type ID, This number identifies lo...
A thread specific collection of double-buffered and algorithm specific resources. ...
T & GetCommittable()
Get a reference to the resource that can be committed.
std::vector< WorkUnitKey > WorkUnitsMain
A collection of all the work units that are not Monopolies and do not have affinity for a given threa...
Declares a tool for automatically unlocking a mutex in an exception safe way.
SpinLock LogResources
Protects DoubleBufferedResources during creation and error handling from being accessed by the LogAgg...
virtual Whole GetFrameCount() const
Get the current number of frames that have elapsed.
std::vector< WorkUnitKey > WorkUnitsMain
A freshly sorted WorkUnitsMain or an empty vector.
This is central object in this algorithm, it is responsible for spawning threads and managing the ord...
virtual Whole GetSortingFrequency()
Check how often this sorts.
void NextFlushForced(Boole Force=true)
Used to indicate the next log flush is abnormally forced.
A thread specific resource that uses double buffering to avoid multithreaded synchronization mechanis...
This defines a number of workunits that are required for doing some tasks that the Framescheduler req...
virtual void SetSortingFrequency(Whole FramesBetweenSorts)
Set how often this actually does work.
void UpdateWorkUnitKeys(std::vector< WorkUnitKey > &Units)
Iterate over the passed container of WorkUnitKeys and refresh them with the correct data from their r...
The bulk of the engine components go in this namspace.
Definition: actor.cpp:56
unsigned long Whole
Whole is an unsigned integer, it will be at least 32bits in size.
Definition: datatypes.h:151
FrameScheduler * GetAggregationTarget() const
Get the current Aggregation Target.
virtual void DoWork(DefaultThreadSpecificStorage::Type &CurrentThreadStorage)
This usually does nothing, but sometimes it will do a whole bunch of work sorting.
void SetAggregationTarget(FrameScheduler *NewTarget)
Set which framescheduler will be aggregated.
WorkSorter * Sorter
If this pointer is non-zero then the WorkSorter it points at will be used to sort WorkUnits...
void Unlock()
Unlock the spinlock.
Definition: spinlock.cpp:70
virtual void DoWork(DefaultThreadSpecificStorage::Type &CurrentThreadStorage)
This does the actual work of log aggregation.
DBR & GetResource(const Whole &ResourceID)
Get a Specific kind of double buffered resource.
std::string String
A datatype used to a series of characters.
Definition: datatypes.h:159