14#ifndef AUTONOMYTHREAD_H
15#define AUTONOMYTHREAD_H
17#include "../util/IPS.hpp"
20#include "../../external/threadpool/include/BS_thread_pool.hpp"
23#include <condition_variable>
47 enum class AutonomyThreadState
57 enum class AutonomyThreadPriority
59 eLowest = BS::pr::lowest,
61 eNormal = BS::pr::normal,
64 eHighest = BS::pr::highest
80 m_bStopThreads =
false;
81 m_eThreadState = AutonomyThreadState::eStopped;
82 m_nMainThreadMaxIterationPerSecond = 0;
101 m_bStopThreads =
true;
103 m_eThreadState = AutonomyThreadState::eStopping;
108 m_thMainThread.
pause();
109 m_thMainThread.
purge();
113 m_thMainThread.
wait();
115 m_eThreadState = AutonomyThreadState::eStopped;
137 m_bStopThreads =
true;
139 m_eThreadState = AutonomyThreadState::eStopping;
144 m_thMainThread.
pause();
145 m_thMainThread.
purge();
151 m_eThreadState = AutonomyThreadState::eStarting;
153 m_vPoolReturns.clear();
155 m_bStopThreads =
false;
158 std::future<void> fuMainReturn = m_thMainThread.
submit_task(
171 std::unique_lock<std::mutex> lkStartLock(m_muThreadRunningConditionMutex);
172 m_cdThreadRunningCondition.wait(lkStartLock,
174 {
return this->m_eThreadState == AutonomyThreadState::eRunning || this->m_eThreadState == AutonomyThreadState::eStopping; });
190 m_bStopThreads =
true;
192 m_eThreadState = AutonomyThreadState::eStopping;
208 m_thMainThread.
wait();
211 m_eThreadState = AutonomyThreadState::eStopped;
284 m_ePoolThreadPriority =
static_cast<BS::pr>(ePriority);
327 void RunPool(
const unsigned int nNumTasksToQueue,
const unsigned int nNumThreads = 2,
const bool bForceStopCurrentThreads =
false)
336 m_thPool.
reset(nNumThreads);
341 m_vPoolReturns.clear();
344 else if (bForceStopCurrentThreads)
356 for (
unsigned int nIter = 0; nIter < nNumTasksToQueue; ++nIter)
363 this->PooledLinearCode();
399 void RunDetachedPool(
const unsigned int nNumTasksToQueue,
const unsigned int nNumThreads = 2,
const bool bForceStopCurrentThreads =
false)
408 m_thPool.
reset(nNumThreads);
413 m_vPoolReturns.clear();
416 else if (bForceStopCurrentThreads)
428 for (
unsigned int nIter = 0; nIter < nNumTasksToQueue; ++nIter)
435 this->PooledLinearCode();
466 template<
typename N,
typename F>
467 void ParallelizeLoop(
const int nNumThreads,
const N tTotalIterations, F&& tLoopFunction)
474 [&tLoopFunction](
const int nStart,
const int nEnd)
477 tLoopFunction(nStart, nEnd);
533 m_nMainThreadMaxIterationPerSecond = nMaxIterationsPerSecond;
571 std::vector<T> vResults;
574 for (std::future<T> fResult : m_vPoolReturns)
577 vResults.emplace_back(fResult.get());
581 m_vPoolReturns.clear();
597 return m_nMainThreadMaxIterationPerSecond;
605 BS::pr m_eMainThreadPriority = BS::pr::normal;
606 BS::pr m_ePoolThreadPriority = BS::pr::normal;
612 std::vector<std::future<T>> m_vPoolReturns;
613 std::atomic_bool m_bStopThreads;
614 std::atomic<AutonomyThreadState> m_eThreadState;
615 std::mutex m_muThreadRunningConditionMutex;
616 std::condition_variable m_cdThreadRunningCondition;
617 int m_nMainThreadMaxIterationPerSecond;
618 std::string m_szThreadUUID;
625 virtual void ThreadedContinuousCode() = 0;
626 virtual T PooledLinearCode() = 0;
643 std::chrono::_V2::system_clock::time_point tmStartTime;
649 if (m_nMainThreadMaxIterationPerSecond > 0)
652 tmStartTime = std::chrono::high_resolution_clock::now();
656 this->ThreadedContinuousCode();
659 if (m_nMainThreadMaxIterationPerSecond > 0)
662 std::chrono::_V2::system_clock::time_point tmEndTime = std::chrono::high_resolution_clock::now();
664 std::chrono::microseconds tmElapsedTime = std::chrono::duration_cast<std::chrono::microseconds>(tmEndTime - tmStartTime);
666 if (tmElapsedTime.count() < (1.0 / m_nMainThreadMaxIterationPerSecond) * 1000000)
669 int nSleepTime = ((1.0 / m_nMainThreadMaxIterationPerSecond) * 1000000) - tmElapsedTime.count();
671 std::this_thread::sleep_for(std::chrono::microseconds(nSleepTime));
676 if (m_eThreadState != AutonomyThreadState::eRunning && m_eThreadState != AutonomyThreadState::eStopping)
679 m_eThreadState = AutonomyThreadState::eRunning;
681 m_cdThreadRunningCondition.notify_all();
689 m_cdThreadRunningCondition.notify_all();
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);
708 std::stringstream stdStream;
709 stdStream << std::hex;
710 for (
int nIter = 0; nIter < 8; nIter++)
712 stdStream << stdDist1(stdGen);
715 for (
int nIter = 0; nIter < 4; nIter++)
717 stdStream << stdDist1(stdGen);
720 for (
int nIter = 0; nIter < 3; nIter++)
722 stdStream << stdDist1(stdGen);
725 stdStream << stdDist2(stdGen);
726 for (
int nIter = 0; nIter < 3; nIter++)
728 stdStream << stdDist1(stdGen);
731 for (
int nIter = 0; nIter < 12; nIter++)
733 stdStream << stdDist1(stdGen);
735 return stdStream.str();
Interface class used to easily multithread a child class.
Definition AutonomyThread.hpp:40
void Join()
Waits for thread to finish executing and then closes thread. This method will block the calling code ...
Definition AutonomyThread.hpp:203
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...
Definition AutonomyThread.hpp:467
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 o...
Definition AutonomyThread.hpp:327
int GetMainThreadMaxIPS() const
Accessor for the Main Thread Max I P S private member.
Definition AutonomyThread.hpp:594
void SetMainThreadIPSLimit(int nMaxIterationsPerSecond=0)
Mutator for the Main Thread Max I P S private member.
Definition AutonomyThread.hpp:530
AutonomyThread()
Construct a new Autonomy Thread object.
Definition AutonomyThread.hpp:77
int GetPoolNumOfThreads()
Accessor for the Pool Num Of Threads private member.
Definition AutonomyThread.hpp:544
std::vector< T > GetPoolResults()
Accessor for the Pool Results private member. The action of getting results will destroy and remove t...
Definition AutonomyThread.hpp:568
std::string GetThreadUUID() const
Accessor for the Thread U U I D private member.
Definition AutonomyThread.hpp:247
void RequestStop()
Signals threads to stop executing user code, terminate. DOES NOT JOIN. This method will not force the...
Definition AutonomyThread.hpp:187
bool Joinable() const
Check if the code within the thread and all pools created by it are finished executing and the thread...
Definition AutonomyThread.hpp:224
IPS & GetIPS()
Accessor for the Frame I P S private member.
Definition AutonomyThread.hpp:257
int GetPoolQueueLength()
Accessor for the Pool Queue Size private member.
Definition AutonomyThread.hpp:554
void ClearPoolQueue()
Clears any tasks waiting to be ran in the queue, tasks currently running will remain running.
Definition AutonomyThread.hpp:492
void Start()
When this method is called, it starts a new thread that runs the code within the ThreadedContinuousCo...
Definition AutonomyThread.hpp:134
void SetMainThreadPriority(AutonomyThreadPriority ePriority)
Set the OS priority for the main continuous thread.
Definition AutonomyThread.hpp:269
std::string GenerateUUIDV4()
Generates a random UUID v4 string. This is useful for generating unique IDs for files,...
Definition AutonomyThread.hpp:701
void SetPoolThreadPriority(AutonomyThreadPriority ePriority)
Set the OS priority for the highly parallelized pool threads.
Definition AutonomyThread.hpp:281
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
virtual ~AutonomyThread()
Destroy the Autonomy Thread object. If the parent object or main thread is destroyed or exited while ...
Definition AutonomyThread.hpp:98
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 (l...
Definition AutonomyThread.hpp:399
bool PoolJoinable() const
Check if the internal pool threads are done executing code and the queue is empty.
Definition AutonomyThread.hpp:514
void JoinPool()
Waits for pool to finish executing tasks. This method will block the calling code until thread is fin...
Definition AutonomyThread.hpp:502
AutonomyThreadState GetThreadState() const
Accessor for the Threads State private member.
Definition AutonomyThread.hpp:237
A fast, lightweight, modern, and easy-to-use C++17/C++20/C++23 thread pool class.
Definition BS_thread_pool.hpp:1429
void detach_blocks(const T1 first_index, const T2 index_after_last, F &&block, const std::size_t num_blocks=0, const priority_t priority=0)
Parallelize a loop by automatically splitting it into blocks and submitting each block separately to ...
Definition BS_thread_pool.hpp:1531
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 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
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
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
std::size_t get_thread_count() const noexcept
Get the number of threads in the pool.
Definition BS_thread_pool.hpp:1692
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
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
void reset()
Reset the pool with the default number of threads (as if constructed with the default constructor)....
Definition BS_thread_pool.hpp:1744
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
This util class provides an easy way to keep track of iterations per second for any body of code.
Definition IPS.hpp:30
void Tick()
This method is used to update the iterations per second counter and recalculate all of the IPS metric...
Definition IPS.hpp:138
pr
An enum containing some pre-defined priorities for convenience.
Definition BS_thread_pool.hpp:398