Autonomy Software C++ 24.5.1
Welcome to the Autonomy Software repository of the Mars Rover Design Team (MRDT) at Missouri University of Science and Technology (Missouri S&T)! API reference contains the source code and other resources for the development of the autonomy software for our Mars rover. The Autonomy Software project aims to compete in the University Rover Challenge (URC) by demonstrating advanced autonomous capabilities and robust navigation algorithms.
Loading...
Searching...
No Matches
AutonomyThread< T > Class Template Referenceabstract

Interface class used to easily multithread a child class. More...

#include <AutonomyThread.hpp>

Collaboration diagram for AutonomyThread< T >:

Public Types

enum class  AutonomyThreadState { eStarting , eRunning , eStopping , eStopped }
 
enum class  AutonomyThreadPriority {
  eLowest = BS::pr::lowest , eLow = BS::pr::low , eNormal = BS::pr::normal , eHigh = BS::pr::high ,
  eHighest = BS::pr::highest
}
 

Public Member Functions

 AutonomyThread ()
 Construct a new Autonomy Thread object.
 
virtual ~AutonomyThread ()
 Destroy the Autonomy Thread object. If the parent object or main thread is destroyed or exited while this thread is still running, a race condition will occur. Stopping and joining the thread here insures that the main program can't exit if the user forgot to stop and join the thread.
 
void Start ()
 When this method is called, it starts a new thread that runs the code within the ThreadedContinuousCode method. This is the users main code that will run the important and continuous code for the class.
 
void RequestStop ()
 Signals threads to stop executing user code, terminate. DOES NOT JOIN. This method will not force the thread to exit, if the user code is not written properly and contains WHILE statement or any other long-executing or blocking code, then the thread will not exit until the next iteration.
 
void Join ()
 Waits for thread to finish executing and then closes thread. This method will block the calling code until thread is finished.
 
bool Joinable () const
 Check if the code within the thread and all pools created by it are finished executing and the thread is ready to be closed.
 
AutonomyThreadState GetThreadState () const
 Accessor for the Threads State private member.
 
std::string GetThreadUUID () const
 Accessor for the Thread U U I D private member.
 
IPSGetIPS ()
 Accessor for the Frame I P S private member.
 
void SetMainThreadPriority (AutonomyThreadPriority ePriority)
 Set the OS priority for the main continuous thread.
 
void SetPoolThreadPriority (AutonomyThreadPriority ePriority)
 Set the OS priority for the highly parallelized pool threads.
 

Protected Member Functions

void RunPool (const unsigned int nNumTasksToQueue, const unsigned int nNumThreads=2, const bool bForceStopCurrentThreads=false)
 When this method is called, it starts/adds tasks to a thread pool that runs nNumTasksToQueue copies of the code within the PooledLinearCode() method using nNumThreads number of threads. This is meant to be used as an internal utility of the child class to further improve parallelization. Default value for nNumThreads is 2.
 
void RunDetachedPool (const unsigned int nNumTasksToQueue, const unsigned int nNumThreads=2, const bool bForceStopCurrentThreads=false)
 When this method is called, it starts a thread pool full of threads that don't return std::futures (like a placeholder for the thread return type). This means the thread will not have a return type and there is no way to determine if the thread has finished other than calling the Join() method. Only use this if you want to 'set and forget'. It will be faster as it doesn't return futures. Runs PooledLinearCode() method code. This is meant to be used as an internal utility of the child class to further improve parallelization.
 
template<typename N , typename F >
void ParallelizeLoop (const int nNumThreads, const N tTotalIterations, F &&tLoopFunction)
 Given a ref-qualified looping function and an arbitrary number of iterations, this method will divide up the loop and run each section in a thread pool. This function must not return anything. This method will block until the loop has completed.
 
void ClearPoolQueue ()
 Clears any tasks waiting to be ran in the queue, tasks currently running will remain running.
 
void JoinPool ()
 Waits for pool to finish executing tasks. This method will block the calling code until thread is finished.
 
bool PoolJoinable () const
 Check if the internal pool threads are done executing code and the queue is empty.
 
void SetMainThreadIPSLimit (int nMaxIterationsPerSecond=0)
 Mutator for the Main Thread Max I P S private member.
 
int GetPoolNumOfThreads ()
 Accessor for the Pool Num Of Threads private member.
 
int GetPoolQueueLength ()
 Accessor for the Pool Queue Size private member.
 
std::vector< T > GetPoolResults ()
 Accessor for the Pool Results private member. The action of getting results will destroy and remove them from this object. This method blocks if the thread is not finished, so no need to call JoinPool() before getting results.
 
int GetMainThreadMaxIPS () const
 Accessor for the Main Thread Max I P S private member.
 

Protected Attributes

IPS m_IPS = IPS()
 

Private Member Functions

virtual void ThreadedContinuousCode ()=0
 
virtual T PooledLinearCode ()=0
 
void RunThread (std::atomic_bool &bStopThread)
 This method is ran in a separate thread. It is a middleware between the class member thread and the user code that handles graceful stopping of user code. This method is intentionally designed to not return anything.
 
std::string GenerateUUIDV4 ()
 Generates a random UUID v4 string. This is useful for generating unique IDs for files, threads, or any other objects that need to be uniquely identified.
 

Private Attributes

BS::pr m_eMainThreadPriority = BS::pr::normal
 
BS::pr m_ePoolThreadPriority = BS::pr::normal
 
BS::thread_pool< BS::tp::pausem_thMainThread = BS::thread_pool<BS::tp::pause>(1)
 
BS::thread_pool< BS::tp::pausem_thPool = BS::thread_pool<BS::tp::pause>(2)
 
std::vector< std::future< T > > m_vPoolReturns
 
std::atomic_bool m_bStopThreads
 
std::atomic< AutonomyThreadState > m_eThreadState
 
std::mutex m_muThreadRunningConditionMutex
 
std::condition_variable m_cdThreadRunningCondition
 
int m_nMainThreadMaxIterationPerSecond
 
std::string m_szThreadUUID
 

Detailed Description

template<class T>
class AutonomyThread< T >

Interface class used to easily multithread a child class.

Template Parameters
T- Variable return type of internal pooled code.
Author
ClayJay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-07-27

Member Enumeration Documentation

◆ AutonomyThreadState

template<class T >
enum class AutonomyThread::AutonomyThreadState
strong
48 {
49 eStarting,
50 eRunning,
51 eStopping,
52 eStopped
53 };

◆ AutonomyThreadPriority

template<class T >
enum class AutonomyThread::AutonomyThreadPriority
strong
58 {
59 eLowest = BS::pr::lowest, // Thread will be scheduled less often and may not be able to reach the max IPS if the system is under heavy load.
60 eLow = BS::pr::low, // Thread will be scheduled less often and may not be able to reach the max IPS if the system is under heavy load.
61 eNormal = BS::pr::normal, // Default. Thread will be scheduled normally and should be able to reach the max IPS if the system is not under heavy load.
62 eHigh = BS::pr::high, // Thread will be scheduled more often and should be able to reach the max IPS even if the system is under
63 // heavy load, but it may starve other threads of CPU time.
64 eHighest = BS::pr::highest // Thread will be scheduled as often as possible and should be able to reach the max IPS even if the system is under heavy load.
65 };

Constructor & Destructor Documentation

◆ AutonomyThread()

template<class T >
AutonomyThread< T >::AutonomyThread ( )
inline

Construct a new Autonomy Thread object.

Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-12-30
78 {
79 // Initialize member variables.
80 m_bStopThreads = false;
81 m_eThreadState = AutonomyThreadState::eStopped;
82 m_nMainThreadMaxIterationPerSecond = 0;
83
84 // Generate a random UUID for this thread.
85 m_szThreadUUID = this->GenerateUUIDV4();
86 }
std::string GenerateUUIDV4()
Generates a random UUID v4 string. This is useful for generating unique IDs for files,...
Definition AutonomyThread.hpp:701
Here is the call graph for this function:

◆ ~AutonomyThread()

template<class T >
virtual AutonomyThread< T >::~AutonomyThread ( )
inlinevirtual

Destroy the Autonomy Thread object. If the parent object or main thread is destroyed or exited while this thread is still running, a race condition will occur. Stopping and joining the thread here insures that the main program can't exit if the user forgot to stop and join the thread.

Author
ClayJay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-07-23
99 {
100 // Tell all threads to stop executing user code.
101 m_bStopThreads = true;
102 // Update thread state.
103 m_eThreadState = AutonomyThreadState::eStopping;
104
105 // Pause and clear pool queues.
106 m_thPool.pause();
107 m_thPool.purge();
108 m_thMainThread.pause();
109 m_thMainThread.purge();
110
111 // Wait for all pools to finish.
112 m_thPool.wait();
113 m_thMainThread.wait();
114 // Update thread state.
115 m_eThreadState = AutonomyThreadState::eStopped;
116 }
BS_THREAD_POOL_IF_PAUSE_ENABLED void pause()
Pause the pool. The workers will temporarily stop retrieving new tasks out of the queue,...
Definition BS_thread_pool.hpp:1726
void purge()
Purge all the tasks waiting in the queue. Tasks that are currently running will not be affected,...
Definition BS_thread_pool.hpp:1735
void wait()
Wait for tasks to be completed. Normally, this function waits for all tasks, both those that are curr...
Definition BS_thread_pool.hpp:1964
Here is the call graph for this function:

Member Function Documentation

◆ Start()

template<class T >
void AutonomyThread< T >::Start ( )
inline

When this method is called, it starts a new thread that runs the code within the ThreadedContinuousCode method. This is the users main code that will run the important and continuous code for the class.

If this method is called directly after itself, RunPool(), or RunDetachedPool(), it will signal for those threads to stop and wait until they exit on their next iteration. Any number of tasks that are still queued will be cleared. Old results will be destroyed. If you want to wait until they fully execute their code, then call the Join() method before starting a new thread.

Note
This method will block until the thread state is eRunning.
Author
ClayJay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-07-22
135 {
136 // Tell any open thread to stop.
137 m_bStopThreads = true;
138 // Update thread state.
139 m_eThreadState = AutonomyThreadState::eStopping;
140
141 // Pause queuing of new tasks to the threads, then purge them.
142 m_thPool.pause();
143 m_thPool.purge();
144 m_thMainThread.pause();
145 m_thMainThread.purge();
146
147 // Wait for loop, pool and main thread to join.
148 this->Join();
149
150 // Update thread state.
151 m_eThreadState = AutonomyThreadState::eStarting;
152 // Clear results vector.
153 m_vPoolReturns.clear();
154 // Reset thread stop toggle.
155 m_bStopThreads = false;
156
157 // Submit single task to pool queue and store resulting future. Still using pool, as it's scheduling is more efficient.
158 std::future<void> fuMainReturn = m_thMainThread.submit_task(
159 [this]()
160 {
161 // Note: BS::this_thread::set_os_thread_priority was completely removed in BS v5.1.0.
162 // Priority is kept in memory but not applied to OS threads natively by the library anymore.
163 this->RunThread(m_bStopThreads);
164 });
165
166 // Unpause pool queues.
167 m_thPool.unpause();
168 m_thMainThread.unpause();
169
170 // Block until thread is started or currently stopping if thread start failed.
171 std::unique_lock<std::mutex> lkStartLock(m_muThreadRunningConditionMutex);
172 m_cdThreadRunningCondition.wait(lkStartLock,
173 [this]
174 { return this->m_eThreadState == AutonomyThreadState::eRunning || this->m_eThreadState == AutonomyThreadState::eStopping; });
175 }
void Join()
Waits for thread to finish executing and then closes thread. This method will block the calling code ...
Definition AutonomyThread.hpp:203
void RunThread(std::atomic_bool &bStopThread)
This method is ran in a separate thread. It is a middleware between the class member thread and the u...
Definition AutonomyThread.hpp:640
std::future< R > submit_task(F &&task, const priority_t priority=0)
Submit a function with no arguments into the task queue, with the specified priority....
Definition BS_thread_pool.hpp:1939
BS_THREAD_POOL_IF_PAUSE_ENABLED void unpause()
Unpause the pool. The workers will resume retrieving new tasks out of the queue. Only enabled if the ...
Definition BS_thread_pool.hpp:1950
Here is the call graph for this function:
Here is the caller graph for this function:

◆ RequestStop()

template<class T >
void AutonomyThread< T >::RequestStop ( )
inline

Signals threads to stop executing user code, terminate. DOES NOT JOIN. This method will not force the thread to exit, if the user code is not written properly and contains WHILE statement or any other long-executing or blocking code, then the thread will not exit until the next iteration.

Author
ClayJay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-07-22
188 {
189 // Signal for any open threads to stop executing,
190 m_bStopThreads = true;
191 // Update thread state.
192 m_eThreadState = AutonomyThreadState::eStopping;
193 }
Here is the caller graph for this function:

◆ Join()

template<class T >
void AutonomyThread< T >::Join ( )
inline

Waits for thread to finish executing and then closes thread. This method will block the calling code until thread is finished.

Author
ClayJay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-07-22
204 {
205 // Wait for pool to finish all tasks.
206 m_thPool.wait();
207 // Wait for main thread to finish.
208 m_thMainThread.wait();
209
210 // Update thread state.
211 m_eThreadState = AutonomyThreadState::eStopped;
212 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Joinable()

template<class T >
bool AutonomyThread< T >::Joinable ( ) const
inline

Check if the code within the thread and all pools created by it are finished executing and the thread is ready to be closed.

Returns
true - The thread is finished and joinable.
false - The thread is still running code.
Author
ClayJay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-07-22
225 { // Check current number of running and queued tasks.
226 return (m_thMainThread.get_tasks_total() <= 0 && m_thPool.get_tasks_total() <= 0);
227 }
std::size_t get_tasks_total() const
Get the total number of unfinished tasks: either still waiting in the queue, or running in a thread....
Definition BS_thread_pool.hpp:1681
Here is the call graph for this function:

◆ GetThreadState()

template<class T >
AutonomyThreadState AutonomyThread< T >::GetThreadState ( ) const
inline

Accessor for the Threads State private member.

Returns
AutonomyThreadState - The current state of the main thread.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-01-08
237{ return m_eThreadState; }

◆ GetThreadUUID()

template<class T >
std::string AutonomyThread< T >::GetThreadUUID ( ) const
inline

Accessor for the Thread U U I D private member.

Returns
std::string - The randomly generated UUID for this thread, used for logging and debugging.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2026-04-21
247{ return m_szThreadUUID; }

◆ GetIPS()

template<class T >
IPS & AutonomyThread< T >::GetIPS ( )
inline

Accessor for the Frame I P S private member.

Returns
IPS& - The iteration per second counter for the ThreadedContinuousCode()
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-08-20
257{ return m_IPS; }
Here is the caller graph for this function:

◆ SetMainThreadPriority()

template<class T >
void AutonomyThread< T >::SetMainThreadPriority ( AutonomyThreadPriority  ePriority)
inline

Set the OS priority for the main continuous thread.

Parameters
thPriority- The OS thread priority to set.
Note
This will take effect the next time Start() is called.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2026-03-21
269{ m_eMainThreadPriority = static_cast<BS::pr>(ePriority); }
pr
An enum containing some pre-defined priorities for convenience.
Definition BS_thread_pool.hpp:398

◆ SetPoolThreadPriority()

template<class T >
void AutonomyThread< T >::SetPoolThreadPriority ( AutonomyThreadPriority  ePriority)
inline

Set the OS priority for the highly parallelized pool threads.

Parameters
thPriority- The OS thread priority to set.
Note
This immediately resets the pool and applies the priority.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2026-03-21
282 {
283 // Update member variable.
284 m_ePoolThreadPriority = static_cast<BS::pr>(ePriority);
285 // Native OS priority extensions were removed in BS v5.1.0, so we just reset thread count.
286 m_thPool.reset(m_thPool.get_thread_count());
287 }
std::size_t get_thread_count() const noexcept
Get the number of threads in the pool.
Definition BS_thread_pool.hpp:1692
void reset()
Reset the pool with the default number of threads (as if constructed with the default constructor)....
Definition BS_thread_pool.hpp:1744
Here is the call graph for this function:

◆ RunPool()

template<class T >
void AutonomyThread< T >::RunPool ( const unsigned int  nNumTasksToQueue,
const unsigned int  nNumThreads = 2,
const bool  bForceStopCurrentThreads = false 
)
inlineprotected

When this method is called, it starts/adds tasks to a thread pool that runs nNumTasksToQueue copies of the code within the PooledLinearCode() method using nNumThreads number of threads. This is meant to be used as an internal utility of the child class to further improve parallelization. Default value for nNumThreads is 2.

If this method is called directly after itself or RunDetachedPool(), it will just add more tasks to the queue. If the bForceStopCurrentThreads is enabled, it will signal for those threads to stop and wait until they exit on their next iteration. Any number of tasks that are still queued will be cleared. Old results will be destroyed. If you want to wait until they fully execute their code, then call the Join() method before this one.

Once the pool is created it stays alive for as long as the program runs or until a different threading method is called. So there's no overhead with starting and stopping threads or queueing more tasks.

YOU MUST HANDLE MUTEX LOCKS AND ATOMICS. It is impossible for this class to handle locks as all possible solutions lead to a solution that only lets one thread run at a time, essentially canceling out the parallelism.

Parameters
nNumTasksToQueue- The number of tasks running PooledLinearCode() to queue.
nNumThreads- The number of threads to run user code in.
bForceStopCurrentThreads- Clears the current tasks queue then signals and waits for existing tasks to stop before queueing more.
Author
ClayJay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-07-23
328 {
329 // Check if the pools need to be resized.
330 if (m_thPool.get_thread_count() != nNumThreads)
331 {
332 // Pause queuing of new tasks to the threads, then purge them.
333 m_thPool.pause();
334 m_thPool.purge();
335 // Wait for open threads to terminate, then resize the pool.
336 m_thPool.reset(nNumThreads);
337 // Unpause queue.
338 m_thPool.unpause();
339
340 // Clear results vector.
341 m_vPoolReturns.clear();
342 }
343 // Check if the current pool tasks should be stopped before queueing more tasks.
344 else if (bForceStopCurrentThreads)
345 {
346 // Pause queuing of new tasks to the threads, then purge them.
347 m_thPool.pause();
348 m_thPool.purge();
349 // Wait for threadpool to join.
350 m_thPool.wait();
351 // Unpause queue.
352 m_thPool.unpause();
353 }
354
355 // Loop nNumThreads times and queue tasks.
356 for (unsigned int nIter = 0; nIter < nNumTasksToQueue; ++nIter)
357 {
358 // Submit single task to pool queue.
359 m_vPoolReturns.emplace_back(m_thPool.submit_task(
360 [this]()
361 {
362 // Run user pool code without lock.
363 this->PooledLinearCode();
364 }));
365 }
366 }
Here is the call graph for this function:

◆ RunDetachedPool()

template<class T >
void AutonomyThread< T >::RunDetachedPool ( const unsigned int  nNumTasksToQueue,
const unsigned int  nNumThreads = 2,
const bool  bForceStopCurrentThreads = false 
)
inlineprotected

When this method is called, it starts a thread pool full of threads that don't return std::futures (like a placeholder for the thread return type). This means the thread will not have a return type and there is no way to determine if the thread has finished other than calling the Join() method. Only use this if you want to 'set and forget'. It will be faster as it doesn't return futures. Runs PooledLinearCode() method code. This is meant to be used as an internal utility of the child class to further improve parallelization.

If this method is called directly after itself or RunPool(), it will just add more tasks to the queue. If the bForceStopCurrentThreads is enabled, it will signal for those threads to stop and wait until they exit on their next iteration. Any number of tasks that are still queued will be cleared. Old results will be destroyed. If you want to wait until they fully execute their code, then call the Join() method before this one.

Once the pool is created it stays alive for as long as the program runs or until a different threading method is called. So there's no overhead with starting and stopping threads or queueing more tasks.

YOU MUST HANDLE MUTEX LOCKS AND ATOMICS. It is impossible for this class to handle locks as all possible solutions lead to a solution that only lets one thread run at a time, essentially canceling out the parallelism.

Parameters
nNumTasksToQueue- The number of tasks running PooledLinearCode() to queue.
nNumThreads- The number of threads to run user code in.
bForceStopCurrentThreads- Clears the current tasks queue then signals and waits for existing tasks to stop before queueing more.
Author
ClayJay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-07-23
400 {
401 // Check if the pools need to be resized.
402 if (m_thPool.get_thread_count() != nNumThreads)
403 {
404 // Pause queuing of new tasks to the threads, then purge them.
405 m_thPool.pause();
406 m_thPool.purge();
407 // Wait for open threads to terminate, then resize the pool.
408 m_thPool.reset(nNumThreads);
409 // Unpause queue.
410 m_thPool.unpause();
411
412 // Clear results vector.
413 m_vPoolReturns.clear();
414 }
415 // Check if the current pool tasks should be stopped before queueing more tasks.
416 else if (bForceStopCurrentThreads)
417 {
418 // Pause queuing of new tasks to the threads, then purge them.
419 m_thPool.pause();
420 m_thPool.purge();
421 // Wait for threadpool to join.
422 m_thPool.wait();
423 // Unpause queue.
424 m_thPool.unpause();
425 }
426
427 // Loop nNumThreads times and queue tasks.
428 for (unsigned int nIter = 0; nIter < nNumTasksToQueue; ++nIter)
429 {
430 // Push single task to pool queue. No return value no control.
431 m_thPool.detach_task(
432 [this]()
433 {
434 // Run user code without lock.
435 this->PooledLinearCode();
436 });
437 }
438 }
void detach_task(F &&task, const priority_t priority=0)
Submit a function with no arguments and no return value into the task queue, with the specified prior...
Definition BS_thread_pool.hpp:1627
Here is the call graph for this function:

◆ ParallelizeLoop()

template<class T >
template<typename N , typename F >
void AutonomyThread< T >::ParallelizeLoop ( const int  nNumThreads,
const N  tTotalIterations,
F &&  tLoopFunction 
)
inlineprotected

Given a ref-qualified looping function and an arbitrary number of iterations, this method will divide up the loop and run each section in a thread pool. This function must not return anything. This method will block until the loop has completed.

To see an example of how to use this function, check out ArucoGenerateTags in the threads example folder.

YOU MUST HANDLE MUTEX LOCKS AND ATOMICS. It is impossible for this class to handle locks as all possible solutions lead to a solution that only lets one thread run at a time, essentially canceling out the parallelism.

Template Parameters
N- Template argument for the nTotalIterations type.
F- Template argument for the given function reference.
Parameters
nNumThreads- The number of threads to use for the thread pool.
nTotalIterations- The total iterations to loop for.
tLoopFunction- Ref-qualified function to run. MUST ACCEPT TWO ARGS: const int a, const int b. a - loop start b - loop end
Author
ClayJay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-07-26
468 {
469 // Create new thread pool (no specific template flags needed for basic detaching).
470 BS::thread_pool<> m_thLoopPool(nNumThreads);
471
472 m_thLoopPool.detach_blocks(0,
473 tTotalIterations,
474 [&tLoopFunction](const int nStart, const int nEnd)
475 {
476 // Call loop function without lock.
477 tLoopFunction(nStart, nEnd);
478 });
479
480 // Wait for loop to finish.
481 m_thLoopPool.wait();
482 }
A fast, lightweight, modern, and easy-to-use C++17/C++20/C++23 thread pool class.
Definition BS_thread_pool.hpp:1429
Here is the call graph for this function:

◆ ClearPoolQueue()

template<class T >
void AutonomyThread< T >::ClearPoolQueue ( )
inlineprotected

Clears any tasks waiting to be ran in the queue, tasks currently running will remain running.

Author
ClayJay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-09-09
492{ m_thPool.purge(); }
Here is the call graph for this function:

◆ JoinPool()

template<class T >
void AutonomyThread< T >::JoinPool ( )
inlineprotected

Waits for pool to finish executing tasks. This method will block the calling code until thread is finished.

Author
ClayJay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-07-22
502{ m_thPool.wait(); }
Here is the call graph for this function:

◆ PoolJoinable()

template<class T >
bool AutonomyThread< T >::PoolJoinable ( ) const
inlineprotected

Check if the internal pool threads are done executing code and the queue is empty.

Returns
true - The thread is finished and joinable.
false - The thread is still running code.
Author
ClayJay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-07-22
515 {
516 // Check current number of running and queued tasks.
517 return (m_thPool.get_tasks_total() <= 0);
518 }
Here is the call graph for this function:

◆ SetMainThreadIPSLimit()

template<class T >
void AutonomyThread< T >::SetMainThreadIPSLimit ( int  nMaxIterationsPerSecond = 0)
inlineprotected

Mutator for the Main Thread Max I P S private member.

Parameters
nMaxIterationsPerSecond- The max iteration per second limit of the main thread.
Note
- Set to zero to disable the max iteration per second limit.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-12-30
531 {
532 // Assign member variable.
533 m_nMainThreadMaxIterationPerSecond = nMaxIterationsPerSecond;
534 }

◆ GetPoolNumOfThreads()

template<class T >
int AutonomyThread< T >::GetPoolNumOfThreads ( )
inlineprotected

Accessor for the Pool Num Of Threads private member.

Returns
int - The number of threads available to the pool.
Author
ClayJay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-09-09
544{ return m_thPool.get_thread_count(); }
Here is the call graph for this function:

◆ GetPoolQueueLength()

template<class T >
int AutonomyThread< T >::GetPoolQueueLength ( )
inlineprotected

Accessor for the Pool Queue Size private member.

Returns
int - The number of tasks queued for the pool.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2024-03-14
554{ return m_thPool.get_tasks_queued(); }
std::size_t get_tasks_queued() const
Get the number of tasks currently waiting in the queue to be executed by the threads.
Definition BS_thread_pool.hpp:1659
Here is the call graph for this function:

◆ GetPoolResults()

template<class T >
std::vector< T > AutonomyThread< T >::GetPoolResults ( )
inlineprotected

Accessor for the Pool Results private member. The action of getting results will destroy and remove them from this object. This method blocks if the thread is not finished, so no need to call JoinPool() before getting results.

Returns
std::vector<T> - A vector containing the returns from each thread that ran the PooledLinearCode.
Author
ClayJay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-07-26
569 {
570 // Create instance variable.
571 std::vector<T> vResults;
572
573 // Loop the pool futures and get result.
574 for (std::future<T> fResult : m_vPoolReturns)
575 {
576 // Store returned value.
577 vResults.emplace_back(fResult.get());
578 }
579
580 // Clear pool returns member variable.
581 m_vPoolReturns.clear();
582
583 return vResults;
584 }

◆ GetMainThreadMaxIPS()

template<class T >
int AutonomyThread< T >::GetMainThreadMaxIPS ( ) const
inlineprotected

Accessor for the Main Thread Max I P S private member.

Returns
int - The max iterations per second the main thread can reach.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-12-31
595 {
596 // Return member variable value.
597 return m_nMainThreadMaxIterationPerSecond;
598 }

◆ ThreadedContinuousCode()

template<class T >
virtual void AutonomyThread< T >::ThreadedContinuousCode ( )
privatepure virtual

◆ PooledLinearCode()

◆ RunThread()

template<class T >
void AutonomyThread< T >::RunThread ( std::atomic_bool &  bStopThread)
inlineprivate

This method is ran in a separate thread. It is a middleware between the class member thread and the user code that handles graceful stopping of user code. This method is intentionally designed to not return anything.

Parameters
bStopThread- Atomic shared variable that signals the thread to stop iterating.
Author
ClayJay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2023-07-24
641 {
642 // Declare instance variables.
643 std::chrono::_V2::system_clock::time_point tmStartTime;
644
645 // Loop until stop flag is set.
646 while (!bStopThread)
647 {
648 // Check if max IPS limit has been set.
649 if (m_nMainThreadMaxIterationPerSecond > 0)
650 {
651 // Get start execution time.
652 tmStartTime = std::chrono::high_resolution_clock::now();
653 }
654
655 // Call method containing user code.
656 this->ThreadedContinuousCode();
657
658 // Check if max IPS limit has been set.
659 if (m_nMainThreadMaxIterationPerSecond > 0)
660 {
661 // Get end execution time.
662 std::chrono::_V2::system_clock::time_point tmEndTime = std::chrono::high_resolution_clock::now();
663 // Get execution time of user code.
664 std::chrono::microseconds tmElapsedTime = std::chrono::duration_cast<std::chrono::microseconds>(tmEndTime - tmStartTime);
665 // Check if the elapsed time is slower than the max iterations per seconds.
666 if (tmElapsedTime.count() < (1.0 / m_nMainThreadMaxIterationPerSecond) * 1000000)
667 {
668 // Calculate the time to wait to stay under IPS cap.
669 int nSleepTime = ((1.0 / m_nMainThreadMaxIterationPerSecond) * 1000000) - tmElapsedTime.count();
670 // Make this thread sleep for the remaining time.
671 std::this_thread::sleep_for(std::chrono::microseconds(nSleepTime));
672 }
673 }
674
675 // Check if thread state needs to be updated.
676 if (m_eThreadState != AutonomyThreadState::eRunning && m_eThreadState != AutonomyThreadState::eStopping)
677 {
678 // Update thread state to running.
679 m_eThreadState = AutonomyThreadState::eRunning;
680 // Notify waiting start method that thread is now running.
681 m_cdThreadRunningCondition.notify_all();
682 }
683
684 // Call iteration per second tracking tick.
685 m_IPS.Tick();
686 }
687
688 // Notify waiting start method that thread is now stopping.
689 m_cdThreadRunningCondition.notify_all();
690 }
void Tick()
This method is used to update the iterations per second counter and recalculate all of the IPS metric...
Definition IPS.hpp:138
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GenerateUUIDV4()

template<class T >
std::string AutonomyThread< T >::GenerateUUIDV4 ( )
inlineprivate

Generates a random UUID v4 string. This is useful for generating unique IDs for files, threads, or any other objects that need to be uniquely identified.

Returns
std::string - A random UUID v4 string.
Author
clayjay3 (clayt.nosp@m.onra.nosp@m.ycowe.nosp@m.n@gm.nosp@m.ail.c.nosp@m.om)
Date
2026-04-21
702 {
703 static std::random_device stdRandomDevice;
704 static std::mt19937 stdGen(stdRandomDevice());
705 static std::uniform_int_distribution<> stdDist1(0, 15);
706 static std::uniform_int_distribution<> stdDist2(8, 11);
707
708 std::stringstream stdStream;
709 stdStream << std::hex;
710 for (int nIter = 0; nIter < 8; nIter++)
711 {
712 stdStream << stdDist1(stdGen);
713 }
714 stdStream << "-";
715 for (int nIter = 0; nIter < 4; nIter++)
716 {
717 stdStream << stdDist1(stdGen);
718 }
719 stdStream << "-4";
720 for (int nIter = 0; nIter < 3; nIter++)
721 {
722 stdStream << stdDist1(stdGen);
723 }
724 stdStream << "-";
725 stdStream << stdDist2(stdGen);
726 for (int nIter = 0; nIter < 3; nIter++)
727 {
728 stdStream << stdDist1(stdGen);
729 }
730 stdStream << "-";
731 for (int nIter = 0; nIter < 12; nIter++)
732 {
733 stdStream << stdDist1(stdGen);
734 }
735 return stdStream.str();
736 }
Here is the caller graph for this function:

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