Spinning Topp Logo BlackTopp Studios
inc
doublebufferedresource.h
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 _doublebufferedresource_h
42 #define _doublebufferedresource_h
43 
44 #include "datatypes.h"
45 
46 /// @file
47 /// @brief This file defines the template double buffered resources that can be attached to a thread.
48 
49 namespace Mezzanine
50 {
51  namespace Threading
52  {
53 #ifndef SWIG
54  /// @brief Double buffered resources are identified by a @ref Whole which is their type ID, This number identifies an invalid entry.
55  const static Whole DBRInvalid = 10000000;
56 
57  /// @brief Double buffered resources are identified by a @ref Whole which is their type ID, This number identifies logging.
58  const static Whole DBRLogger = 0;
59 
60  /// @brief Double buffered resources are identified by a @ref Whole which is their type ID, All System Type IDs will be less than this amount.
61  /// @note Do not use the value of this directly, it is subject to change. In code using this, use: @code const static whole FreshDBRType = BDRUser+YourValue; @endcode
62  const static Whole DBRUser = 1;
63 #endif
64  /// @brief A thread specific resource that uses double buffering to avoid multithreaded synchronization mechanisms.
65  /// @details It is intended for a Mezzanine::Threading::iWorkUnit "iWorkUnit" like the to provide asynchronous
66  /// access to resources that to not need immediate atomicity. For example, it is ok if logs are gathered asynchronously
67  /// and aggregated later as long no log messages are damaged, lost or taken out of order. This allows IO and other potentially
68  /// expensive tasks to be used without blocking the current thread.
69  template<typename T>
71  {
72  private:
73  /// @brief One of the resources to be buffered
74  T* ResourceA;
75 
76  /// @brief The other of the resources to be buffered
77  T* ResourceB;
78 
79  public:
80  /// @brief A Constructor that creates default versions of the resources.
81  /// @details This calls the default constructors for type T.
82  DoubleBufferedResource() : ResourceA(0), ResourceB(0)
83  {
84  try
85  {
86  ResourceA = new T;
87  ResourceB = new T;
88  }catch(std::exception& e){
89  if (ResourceA)
90  { delete ResourceA; ResourceA=0; }
91  if (ResourceB)
92  { delete ResourceB; ResourceB=0; }
93  throw e;
94  }
95 
96  }
97 
98  /// @brief A constructor that takes ownership of the the resources passed.
99  /// @param Current This will be used as the first resource for threads to use.
100  /// @param Buffer This will wait for the other thread
101  DoubleBufferedResource(T* Current, T* Buffer) : ResourceA(Current), ResourceB(Buffer)
102  {}
103 
104  /// @brief Make the buffered resource the active and vice versa.
106  { std::swap(ResourceA,ResourceB); }
107 
108  /// @brief Get a pointer to the resource that can be used
109  /// @return A pointer to the usable resource
110  T* GetUsablePointer() const
111  { return ResourceA; }
112 
113  /// @brief Get a pointer to the resource that can be committed.
114  /// @return A pointer to the commitable resource
116  { return ResourceB; }
117 
118  /// @brief Get a reference to the resource that can be used
119  /// @return A reference to the usable resource
121  { return *ResourceA; }
122 
123  /// @brief Get a reference to the resource that can be committed.
124  /// @return A reference to the commitable resource
126  { return *ResourceB; }
127 
128  /// @brief Destructor, this deletes both the resources managed. Regardless of how it got a hold of the pointers.
130  {
131  delete ResourceA;
132  delete ResourceB;
133  }
134  };//DoubleBufferedResource
135 
136 
137  /// @brief A better default name for the Default Logger instance.
139 
140  // forward declarations
141  class FrameScheduler;
142 
143  /// @brief A thread specific collection of double-buffered and algorithm specific resources.
144  /// @details This class is intended to be expanded via derived classes if it is to return extra resource types
146  {
147  private:
148  /// @brief Stores the pounters to the thread local resources.
149  std::vector<ConvertiblePointer> ThreadResources;
150 
151  /// @brief A pointer to the FrameScheduler that this belongs to.
152  FrameScheduler* Scheduler;
153 
154  public:
155  /// @brief A constructor that automatically creates the resources it supports
157 
158  /// @brief Get a Specific kind of double buffered resource.
159  /// @param ResourceID The ID the resource provided.
160  /// @return A reference to the resource if it exists, or undefined behavior and maybe an exception if it doesn't.
161  template <typename DBR>
162  DBR& GetResource(const Whole& ResourceID)
163  { return *((DBR*)(this->ThreadResources[ResourceID])); }
164 
165  /// @brief Get the usable logger for this thread specific resource
166  /// @return A reference to the logger.
167  /// @note A function like this should be provided for any other resources added to derived versions of this class. This encourages getting resources for this thread, and not providing a method to get the commitable resource gently discourages doing it unless its really required.
168  Logger& GetUsableLogger();
169 
170  /// @brief Get a pointer to the FrameScheduler that owns this resource.
171  /// @details This is not required very often by application code, but is used
172  /// in places in this scheduler library. This is primarily used to gain access
173  /// to commitable parts of double buffered resources. This pointer does not
174  /// confer ownership.
175  /// @return A pointer to the FrameScheduler that owns this resource.
176  FrameScheduler* GetFrameScheduler();
177 
178  /// @copydoc FrameScheduler::GetLastFrameTime() const
179  Whole GetLastFrameTime() const;
180 
181  /// @copydoc FrameScheduler::GetLastPauseTime() const
182  Whole GetLastPauseTime() const;
183 
184  /// @copydoc FrameScheduler::GetCurrentFrameStart() const
185  MaxInt GetCurrentFrameStart() const;
186 
187  /// @brief The commitable and usable version of every double buffered resource for this thread specific storage will be swapped.
188  void SwapAllBufferedResources();
189 
190  /// @brief Deletes all the resources.
191  virtual ~ThreadSpecificStorage();
192 
193  };//ThreadSpecificStorage
194 
195  /// @brief Use this to change the default resource type.
196  /// @details use "DefaultThreadSpecificStorage::Type" as Type to instantiate an instance of whatever type this is.
198  {
199  /// @brief A single point at which all the thread specific resources can be changed.
201  };//DefaultThreadSpecificStorage
202  }//Threading
203 }//Mezzanine
204 
205 #endif
std::stringstream Logger
In case we ever replace the stringstream with another class, this will allow us to swap it out...
Definition: datatypes.h:180
static const Whole DBRInvalid
Double buffered resources are identified by a Whole which is their type ID, This number identifies an...
DoubleBufferedResource(T *Current, T *Buffer)
A constructor that takes ownership of the the resources passed.
All the definitions for datatypes as well as some basic conversion functions are defined here...
DoubleBufferedResource< std::stringstream > DoubleBufferedLogger
A better default name for the Default Logger instance.
DoubleBufferedResource()
A Constructor that creates default versions of the resources.
void SwapUsableAndCommitable()
Make the buffered resource the active and vice versa.
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.
Use this to change the default resource type.
static const Whole DBRUser
Double buffered resources are identified by a Whole which is their type ID, All System Type IDs will ...
ThreadSpecificStorage Type
A single point at which all the thread specific resources can be changed.
This is central object in this algorithm, it is responsible for spawning threads and managing the ord...
A thread specific resource that uses double buffering to avoid multithreaded synchronization mechanis...
T * GetCommittablePointer() const
Get a pointer to the resource that can be committed.
~DoubleBufferedResource()
Destructor, this deletes both the resources managed. Regardless of how it got a hold of the pointers...
T * GetUsablePointer() const
Get a pointer to the resource that can be used.
#define MEZZ_LIB
Some platforms require special decorations to denote what is exported/imported in a share library...
long long MaxInt
A large integer type suitable for compile time math and long term microsecond time keeping...
Definition: datatypes.h:190
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
T & GetUsable()
Get a reference to the resource that can be used.
DBR & GetResource(const Whole &ResourceID)
Get a Specific kind of double buffered resource.