Spinning Topp Logo BlackTopp Studios
inc
thread.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 _btsthread_h
42 #define _btsthread_h
43 
44 /// @file
45 /// @brief This file defines a minimalistic cross-platform thread that the scheduler uses to schedule tasks.
46 
47 // Parts of this library use the TinyThread++ libary and those parts are also covered by the following license
48 /*
49 Copyright (c) 2010-2012 Marcus Geelnard
50 
51 This software is provided 'as-is', without any express or implied
52 warranty. In no event will the authors be held liable for any damages
53 arising from the use of this software.
54 
55 Permission is granted to anyone to use this software for any purpose,
56 including commercial applications, and to alter it and redistribute it
57 freely, subject to the following restrictions:
58 
59  1. The origin of this software must not be misrepresented; you must not
60  claim that you wrote the original software. If you use this software
61  in a product, an acknowledgment in the product documentation would be
62  appreciated but is not required.
63 
64  2. Altered source versions must be plainly marked as such, and must not be
65  misrepresented as being the original software.
66 
67  3. This notice may not be removed or altered from any source
68  distribution.
69 */
70 
71 #if !defined(SWIG) || defined(SWIG_THREADING) // Do not read when in swig and not in the threading module
72 #include "systemcalls.h"
73 #include "mutex.h"
74 #endif
75 
76 #ifndef WINAPI
77  /// @brief Used to force the aclling convention of a function to match the way windows does it.
78  #define WINAPI __stdcall
79 #endif
80 
81 namespace Mezzanine
82 {
83  namespace Threading
84  {
85  // Forward Declaration
86  class ThreadId;
87 
88  /// @brief A small wrapper around the system thread.
89  /// @details In general game code should not be creating this if they are using the
90  /// DAG Frame Scheduler, as it tries to maintain control over the threads created
91  /// by a game. This tries to keep the names the same as the standard thread, and might
92  /// at some point be replace by some template machinery that wraps the minor difference
93  /// that currently exist.
95  {
96  public:
97  #if defined(_MEZZ_THREAD_WIN32_)
98  /// @brief Currently windows defines this to be a void pointer. This might have to be adjusted in the future.
99  typedef void* HANDLE;
100  #endif
101 
102  /// @brief The native handle type, made available with requiring specific knowledge of whether it is a posix or win32 handle.
103  #if defined(_MEZZ_THREAD_WIN32_)
104  typedef HANDLE native_handle_type;
105  #else
106  typedef pthread_t native_handle_type;
107  #endif
108 
109  /// @brief Default constructor.
110  /// @details Construct a @c thread object without an associated thread of execution
111  /// (i.e. non-joinable).
112  Thread() : mHandle(0), mNotAThread(true)
113  #if defined(_MEZZ_WIN32_)
114  , mWin32ThreadID(0)
115  #endif
116  {}
117 
118  /// @brief Thread starting constructor with no parameters.
119  /// @note May work in templates that do not attempt to pass values to threads, but not standard conformant.
120  /// @param[in] aFunction A function pointer to a function of type:
121  /// @code void fun(void * arg) @endcode
122  explicit Thread(void (*aFunction)(void *));
123 
124  /// @brief Thread starting constructor.
125  /// @details Construct a @c thread object with a new thread of execution.
126  /// @param[in] aFunction A function pointer to a function of type:
127  /// @code void fun(void * arg) @endcode
128  /// @param[in] aArg Argument to the thread function.
129  /// @note This constructor is not fully compatible with the standard C++
130  /// thread class. It is more similar to the pthread_create() (POSIX) and
131  /// CreateThread() (Windows) functions.
132  Thread(void (*aFunction)(void *), void * aArg);
133 
134  /// @brief Destructor.
135  /// @note If the thread is joinable upon destruction, @c std::terminate()
136  /// will be called, which terminates the process. It is always wise to do
137  /// @c join() before deleting a thread object.
138  ~Thread();
139 
140  /// @brief Wait for the thread to finish (join execution flows).
141  /// @details After calling @c join(), the thread object is no longer associated with
142  /// a thread of execution (i.e. it is not joinable, and you may not join
143  /// with it nor detach from it).
144  void join();
145 
146  /// @brief Check if the thread is joinable.
147  /// @details A thread object is joinable if it has an associated thread of execution.
148  /// @return A bool, false if the thread has been detached, joined or otherwise made unjoinable by exceptional circumstances, true otherwise.
149  bool joinable() const;
150 
151  /// @brief Detach from the thread.
152  /// @details After calling @c detach(), the thread object is no longer assicated with
153  /// a thread of execution (i.e. it is not joinable). The thread continues
154  /// execution without the calling thread blocking, and when the thread
155  /// ends execution, any owned resources are released.
156  void detach();
157 
158  /// @brief Return the thread ID of a thread object.
159  /// @return A platform specific handle for the thread.
160  ThreadId get_id() const;
161 
162  /// @brief Get the native handle for this thread.
163  /// @note Under Windows, this is a @c HANDLE, and under POSIX systems, this is a @c pthread_t.
164  /// @return The native handle for the thread in case it is desired to use it with OS APIs.
165  inline native_handle_type native_handle()
166  { return mHandle; }
167 
168  /// @brief Determine the number of threads which can possibly execute concurrently.
169  /// @details This function is useful for determining the optimal number of threads to
170  /// use for a task.
171  /// @return The number of hardware thread contexts in the system.
172  /// @note If this value is not defined, the function returns zero (0).
173  static unsigned hardware_concurrency();
174 
175  private:
176  /// @brief Deleted assignment operator.
177  #ifdef _MEZZ_CPP11_PARTIAL_
178  Thread& operator=(const Thread&) = delete;
179  #else
180  Thread& operator=(const Thread&);
181  #endif
182 
183  /// @brief Deleted assignment operator copy constructor.
184  #ifdef _MEZZ_CPP11_PARTIAL_
185  Thread(const Thread&) = delete;
186  #else
187  Thread(const Thread&);
188  #endif
189 
190 
191  native_handle_type mHandle; ///< Thread handle.
192  mutable Mutex mDataMutex; ///< Serializer for access to the thread private data.
193  bool mNotAThread; ///< True if this object is not a thread of execution.
194  #if defined(_MEZZ_THREAD_WIN32_)
195  unsigned int mWin32ThreadID; ///< Unique thread ID (filled out by _beginthreadex).
196  #endif
197 
198  #if defined(_MEZZ_THREAD_WIN32_)
199  /// @brief This is the internal thread wrapper function.
200  static unsigned WINAPI wrapper_function(void * aArg);
201  #else
202  /// @brief This is the internal thread wrapper function.
203  static void * wrapper_function(void * aArg);
204  #endif
205  };//Thread
206 
207  /// @brief The thread ID is a unique identifier for each thread.
208  /// @see thread::get_id()
210  {
211  public:
212  /// @brief Default constructor.
213  /// @details The default constructed ID is that of thread without a thread of
214  /// execution.
215  ThreadId() : mId(0)
216  {}
217 
218  /// @brief Creation from long.
219  /// @param aId The OS provided long to create an ID from.
220  ThreadId(unsigned long int aId) : mId(aId)
221  {}
222 
223  /// @brief Copy constructor.
224  /// @param aId The other id to create a copy of.
225  ThreadId(const ThreadId& aId) : mId(aId.mId)
226  {}
227 
228  /// @brief Assignment Operator.
229  /// @param aId The right hand operand during assignment.
230  /// @return A reference to the left hand operand after it has been assigned.
231  inline ThreadId & operator=(const ThreadId &aId)
232  {
233  mId = aId.mId;
234  return *this;
235  }
236 
237  /// @brief Equality Comparison.
238  /// @param aId1 Left hand operand.
239  /// @param aId2 Right hand operand.
240  /// @returns True boolean value if the OS specific IDs match and false otherwise.
241  inline friend bool operator==(const ThreadId &aId1, const ThreadId &aId2)
242  { return (aId1.mId == aId2.mId); }
243 
244  /// @brief Inequality Comparison.
245  /// @param aId1 Left hand operand.
246  /// @param aId2 Right hand operand.
247  /// @returns False boolean value if the OS specific IDs match and true otherwise.
248  inline friend bool operator!=(const ThreadId &aId1, const ThreadId &aId2)
249  { return (aId1.mId != aId2.mId); }
250 
251  /// @brief Greater than or equal to Comparison.
252  /// @param aId1 Left hand operand.
253  /// @param aId2 Right hand operand.
254  /// @returns A consistent value to allow for sorting/ordering of threads.
255  inline friend bool operator<=(const ThreadId &aId1, const ThreadId &aId2)
256  { return (aId1.mId <= aId2.mId); }
257 
258  /// @brief Greater than Comparison.
259  /// @param aId1 Left hand operand.
260  /// @param aId2 Right hand operand.
261  /// @returns A consistent value to allow for sorting/ordering of threads.
262  inline friend bool operator<(const ThreadId &aId1, const ThreadId &aId2)
263  { return (aId1.mId < aId2.mId); }
264 
265  /// @brief Less than or equal to Comparison.
266  /// @param aId1 Left hand operand.
267  /// @param aId2 Right hand operand.
268  /// @returns A consistent value to allow for sorting/ordering of threads.
269  inline friend bool operator>=(const ThreadId &aId1, const ThreadId &aId2)
270  { return (aId1.mId >= aId2.mId); }
271 
272  /// @brief Less than Comparison.
273  /// @param aId1 Left hand operand.
274  /// @param aId2 Right hand operand.
275  /// @returns A consistent value to allow for sorting/ordering of threads.
276  inline friend bool operator>(const ThreadId &aId1, const ThreadId &aId2)
277  { return (aId1.mId > aId2.mId); }
278 
279  #ifndef SWIG
280  /// @brief Output Streaming operator.
281  /// @param os The output stream to send the id into.
282  /// @param obj the streamed id.
283  /// @returns A reference to the output stream to allow for operator chaining.
284  inline friend std::ostream& operator <<(std::ostream &os, const ThreadId &obj)
285  {
286  os << obj.mId;
287  return os;
288  }
289  #endif
290 
291  private:
292  /// @internal
293  /// @brief The ID value
294  unsigned long int mId;
295  };//Thread::id
296 
297  /// @brief A partial implementation of std::thread::this_thread.
298  namespace this_thread
299  {
300  /// @brief Return the thread ID of the calling thread.
301  /// @return A thread::id unique to this thread.
303 
304  /// @brief Yield execution to another thread.
305  /// @details Offers the operating system the opportunity to schedule another thread
306  /// that is ready to run on the current processor.
307  void MEZZ_LIB yield();
308 
309  /// @brief Blocks the calling thread for a period of time.
310  /// @param MicroSeconds Minimum time to put the thread to sleep.
311  void MEZZ_LIB sleep_for(UInt32 MicroSeconds);
312 
313  } // namespace this_thread
314  }//Threading
315 }//Mezzanine
316 
317 #endif
ThreadId MEZZ_LIB get_id()
Return the thread ID of the calling thread.
friend bool operator<(const ThreadId &aId1, const ThreadId &aId2)
Greater than Comparison.
Definition: thread.h:262
ThreadId(const ThreadId &aId)
Copy constructor.
Definition: thread.h:225
ThreadId()
Default constructor.
Definition: thread.h:215
pthread_t native_handle_type
The native handle type, made available with requiring specific knowledge of whether it is a posix or ...
Definition: thread.h:106
#define WINAPI
Used to force the aclling convention of a function to match the way windows does it.
Definition: thread.h:78
A cross-platform abstraction of the OS's mutex.
Definition: mutex.h:97
void MEZZ_LIB yield()
Yield execution to another thread.
std::ostream & operator<<(std::ostream &stream, const Mezzanine::HashedString32 &x)
Send a HashedString32 down a stream serialized.
native_handle_type native_handle()
Get the native handle for this thread.
Definition: thread.h:165
friend bool operator!=(const ThreadId &aId1, const ThreadId &aId2)
Inequality Comparison.
Definition: thread.h:248
A small wrapper around the system thread.
Definition: thread.h:94
friend bool operator>=(const ThreadId &aId1, const ThreadId &aId2)
Less than or equal to Comparison.
Definition: thread.h:269
uint32_t UInt32
An 32-bit unsigned integer.
Definition: datatypes.h:126
friend bool operator==(const ThreadId &aId1, const ThreadId &aId2)
Equality Comparison.
Definition: thread.h:241
void MEZZ_LIB sleep_for(UInt32 MicroSeconds)
Blocks the calling thread for a period of time.
Thread()
Default constructor.
Definition: thread.h:112
This file declares and defines a mutex that is a partial implementation.
ThreadId & operator=(const ThreadId &aId)
Assignment Operator.
Definition: thread.h:231
This file defines a minimalistic cross-platform thread that the scheduler uses to schedule tasks...
ThreadId(unsigned long int aId)
Creation from long.
Definition: thread.h:220
#define MEZZ_LIB
Some platforms require special decorations to denote what is exported/imported in a share library...
The bulk of the engine components go in this namspace.
Definition: actor.cpp:56
friend bool operator<=(const ThreadId &aId1, const ThreadId &aId2)
Greater than or equal to Comparison.
Definition: thread.h:255
The thread ID is a unique identifier for each thread.
Definition: thread.h:209
friend bool operator>(const ThreadId &aId1, const ThreadId &aId2)
Less than Comparison.
Definition: thread.h:276