7#if !defined(HPP_AWORX_ALIB_THREADS_MODEL_THREADMANAGER)
12# if !defined(HPP_ALIB_ENUMS_SERIALIZATION)
20namespace alib::threads::model {
22ThreadManager::ThreadManager()
28ThreadManager::~ThreadManager()
30 if( state <= State::Started )
32 ALIB_WARNING(
"ATHR",
"ThreadManager destroyed without having run" )
34 else if( state != State::Terminated )
36 ALIB_ERROR(
"ATHR",
"ThreadManager destroyed without being terminated" )
41void ThreadManager::Add(MThread& thread)
43 std::unique_lock<std::mutex> lock(mutex);
44 threadMap.emplace( thread.GetId() , &thread );
49void ThreadManager::StopAndTerminateAll()
51 ALIB_MESSAGE(
"ATHR",
"ThreadManager::StopAndTerminateAll" )
54 if( state < State::Stopped)
60 ALIB_DBG( Ticks waitCheck= Ticks::Now();
61 int nextWarnSecond= 1; )
62 while( state > State::Unstarted && state < State::Stopped )
64 Thread::SleepMicros( 50 );
65 ALIB_DBG(
if( waitCheck.Age().InAbsoluteSeconds() == nextWarnSecond )
66 ALIB_WARNING(
"ATHR",
"Waiting for ThreadManager to stop") )
74 if( !it.second->IsStopped() )
77 ALIB_DBG( waitCheck= Ticks::Now(); nextWarnSecond= 1; )
84 if( it.second->GetState() <
Thread::State::Stopped )
89 Thread::SleepMicros( 50 );
91 if( waitCheck.Age().InAbsoluteSeconds() == nextWarnSecond )
93 NString4K dbgThreadList(
"ThreadManager Termination: Waiting on " );
94 dbgThreadList << static_cast<integer>(cntRunning) <<
" Threads to stop. Threadlist: " <<
NewLine();
98 dbgThreadList << ++tNr <<
": " << it.second->GetName() <<
",\tState::"
100 << it.second->state <<
NewLine();
102 <<
static_cast<int>( it.second->state) <<
NewLine();
105 ALIB_WARNING(
"ATHR", dbgThreadList.NewLine().Terminate() )
113 it.second->Terminate();
122void ThreadManager::Run()
125 Ticks nextWakeup= Ticks::Now();
126 ALIB_DBG( Ticks::Duration dbgSleepTime; )
129 Ticks now= Ticks::Now();
132 auto diff= (nextWakeup - now).InAbsoluteMicroseconds();
133 NString256 msg(
"ThreadManager woke up. Scheduled wakeup " );
136 msg <<
"was " << -diff <<
"\u00B5s ago ("
137 <<
static_cast<double>( -100 * diff / dbgSleepTime.InAbsoluteMicroseconds())
143 msg <<
"is in " << diff <<
"\u00B5s ("
144 <<
static_cast<double>( 100 * diff / dbgSleepTime.InAbsoluteMicroseconds())
153 for(
auto it : triggerList )
155 if( it.nextWakeup <= now )
157 it.triggered->trigger();
159 it.nextWakeup= now + Ticks::Duration::FromAbsoluteMilliseconds(it.triggered->triggerPeriodInMilliseconds());
162 if( nextWakeup < it.nextWakeup)
163 nextWakeup= it.nextWakeup;
175 ALIB_DBG( dbgSleepTime= nextWakeup - now; )
176 SleepUntil( nextWakeup );
182void ThreadManager::AddTriggered(Triggered& triggered)
187 auto it= triggerList.begin();
188 while(it != triggerList.end() && it->triggered != &triggered);
190 if( it == triggerList.end() )
191 triggerList.push_back( { &triggered,
192 Ticks::Now() + Ticks::Duration::FromAbsoluteMilliseconds(
193 triggered.triggerPeriodInMilliseconds() )
196 it->nextWakeup= Ticks::Now();
202void ThreadManager::RemoveTriggered(Triggered &triggered)
207 for(
auto it= triggerList.begin() ; it != triggerList.end() ; it++)
209 if(it->triggered == &triggered)
212 triggerList.erase(it);
223 <<
"\" not found for de-registering with trigger list" )
#define ALIB_WARNING(...)
#define ALIB_MESSAGE(...)
ALIB_API HashMap< std::thread::id, Thread * > threadMap
constexpr CString NewLine()
threads::Thread Thread
Type alias in namespace alib.
time::Ticks Ticks
Type alias in namespace alib.
NLocalString< 256 > NString256
Type alias name for TLocalString<nchar,256> .
NLocalString< 4096 > NString4K
Type alias name for TLocalString<nchar,4096> .