8#if !defined(ALIB_C20_MODULES) || ((ALIB_C20_MODULES != 0) && (ALIB_C20_MODULES != 1))
9# error "Symbol ALIB_C20_MODULES has to be given to the compiler as either 0 or 1"
16#if !ALIB_SINGLE_THREADED
17# include <condition_variable>
21#include <unordered_map>
62#if !ALIB_SINGLE_THREADED
89 std::atomic<ThreadID> nextThreadIdx(1);
90 Thread* MAIN_THREAD =
nullptr;
92 #if ALIB_MONOMEM && ALIB_CONTAINERS
94 #define LOCK_THREADS ALIB_LOCK_RECURSIVE_WITH( monomem::GLOBAL_ALLOCATOR_LOCK )
96 std::unordered_map< std::thread::id, Thread*> THREAD_MAP;
98 #define LOCK_THREADS ALIB_LOCK_WITH( MODULE_LOCK );
122using namespace detail;
127#if ALIB_DEBUG && !DOXYGEN
128 namespace{
unsigned int initFlag= 0; }
132 #if ALIB_MONOMEM && ALIB_CONTAINERS
135 THREAD_MAP.reserve(
size_t(qty) );
139 ALIB_ASSERT_ERROR( initFlag == 0,
"THREADS",
"This method must not be invoked twice." )
151 #if ALIB_MONOMEM && ALIB_CONTAINERS
152 THREAD_MAP.EmplaceUnique( std::this_thread::get_id(), mainThread );
154 THREAD_MAP.insert( std::make_pair( std::this_thread::get_id(), mainThread) );
157 MAIN_THREAD= mainThread;
163 ALIB_ASSERT_ERROR( initFlag == 0x92A3EF61,
"THREADS",
"Not initialized when calling shutdown." )
167 if( MAIN_THREAD ==
nullptr )
174 #if ALIB_MONOMEM && ALIB_CONTAINERS
175 auto qtyThreads= THREAD_MAP.Size();
177 auto qtyThreads= THREAD_MAP.size();
180 if( qtyThreads != 1 )
183 std::vector<std::any> msgs;
185 msgs.emplace_back(
"ALib Termination: Still {} threads running.\n" );
186 msgs.emplace_back( qtyThreads);
188 for(
auto& it : THREAD_MAP ) {
189 msgs.emplace_back(
" {}: {},\tState::{}\n");
190 msgs.emplace_back(++tNr);
191 msgs.emplace_back(it.second);
192 msgs.emplace_back(it.second->state);
198 MAIN_THREAD=
nullptr;
202 Thread* lastThread= THREAD_MAP.begin()->second;
204 "Last thread {} is not the main system thread detected in bootstrap.", lastThread->
id )
207 MAIN_THREAD=
nullptr;
208 #if ALIB_MONOMEM && ALIB_CONTAINERS
232 "Thread \"{}\" destructed, while it was never started.",
this )
237 "Thread \"{}\" was not terminated before destruction.\n"
238 "Use Thread::Join() to avoid this message. Joining now...",
this )
256 "Terminating thread \"{}\" which is not in state 'Done'. State: {}.",
263 ALIB_WARNING(
"THREADS",
"Thread \"{}\" not joinable. State is '{}'.",
this,
state )
269 #if ALIB_MONOMEM && ALIB_CONTAINERS
286 "Double invocation of Thread::Terminate for thread \"{}\".",
this )
289 "Terminating thread \"{}\" which is not started or not managed by ALIB.",
300 ALIB_ERROR(
"THREADS",
"Thread with ID {} was already started.",
GetID() )
306 ALIB_ERROR(
"THREADS",
"System threads cannot be started. (ID={}).",
GetID() )
316 #if ALIB_MONOMEM && ALIB_CONTAINERS
317 THREAD_MAP.EmplaceUnique(
nativeID,
this );
319 THREAD_MAP.insert( std::make_pair(
nativeID,
this) );
340 #if ALIB_MONOMEM && ALIB_CONTAINERS
341 auto search= THREAD_MAP.Find(
nativeID );
343 auto search= THREAD_MAP.find(
nativeID );
347 if ( search != THREAD_MAP.end() )
348 result= search->second;
354 result->
id = nextSystemThreadId--;
357 #if ALIB_MONOMEM && ALIB_CONTAINERS
358 THREAD_MAP.EmplaceUnique(
nativeID, result );
360 THREAD_MAP.insert( std::make_pair(
nativeID, result) );
@ Running
The thread's Run method is currently processed.
@ Started
Method Start was invoked but not running, yet.
@ Terminated
The thread is terminated.
static Thread * GetCurrent()
std::thread::id nativeID
The internal C++ thread id.
const character * name
The name of the thread.
Thread(const character *pName=A_CHAR(""))
virtual ALIB_DLL void Start()
virtual void SetName(const character *newName)
virtual void Run() override
std::thread * c11Thread
The internal C++ thread object.
virtual ALIB_DLL void Join()
State state
Internal flag to indicate if the thread is alive.
Runnable * runnable
The runnable to execute.
ThreadID id
The id of the thread.
static ALIB_DLL Thread * GetMain()
static ALIB_DLL Thread * Get(std::thread::id nativeID)
#define ALIB_ASSERT_RESULT_EQUALS( func, value)
#define ALIB_WARNING(domain,...)
#define ALIB_ASSERT_WARNING(cond, domain,...)
#define ALIB_ERROR(domain,...)
#define ALIB_ASSERT_ERROR(cond, domain,...)
#define ALIB_CALLER_PRUNED
void raise(const CallerInfo &ci, int type, std::string_view domain, const std::span< std::any > &args)
constexpr bool IsNull(const T &t)
@ Absolute
Referring to an absolute value.
ALIB_DLL TMonoAllocator< lang::HeapAllocator > GLOBAL_ALLOCATOR
Details of namespace alib::threads.
void threadStart(Thread *thread)
void BootstrapThreadMap(integer qty)
integer ThreadID
The ALib thread identifier type.
thread_local Thread * THIS_THREAD
A thread-local pointer to the ALib representation of the actual thread.
lang::integer integer
Type alias in namespace alib.
containers::HashMap< TAllocator, TKey, TMapped, THash, TEqual, THashCaching, TRecycling > HashMap
Type alias in namespace alib.
threads::Thread Thread
Type alias in namespace alib.
characters::character character
Type alias in namespace alib.