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>
32 import ALib.Containers.HashTable;
44 import ALib.EnumRecords;
45 import ALib.EnumRecords.Bootstrap;
48 import ALib.Resources;
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 );
121using namespace detail;
126#if ALIB_DEBUG && !DOXYGEN
127namespace{
unsigned initFlag= 0; }
131 #if ALIB_MONOMEM && ALIB_CONTAINERS
134 THREAD_MAP.reserve(
size_t(qty) );
138 ALIB_ASSERT_ERROR( initFlag == 0,
"THREADS",
"This method must not be invoked twice." )
150 #if ALIB_MONOMEM && ALIB_CONTAINERS
151 THREAD_MAP.EmplaceUnique( std::this_thread::get_id(), mainThread );
153 THREAD_MAP.insert( std::make_pair( std::this_thread::get_id(), mainThread) );
156 MAIN_THREAD= mainThread;
161 ALIB_ASSERT_ERROR( initFlag == 0x92A3EF61,
"THREADS",
"Not initialized when calling shutdown." )
165 if( MAIN_THREAD ==
nullptr )
172 #if ALIB_MONOMEM && ALIB_CONTAINERS
173 auto qtyThreads= THREAD_MAP.Size();
175 auto qtyThreads= THREAD_MAP.size();
178 if( qtyThreads != 1 ) {
180 std::vector<std::any> msgs;
182 msgs.emplace_back(
"ALib Termination: Still {} threads running.\n" );
183 msgs.emplace_back( qtyThreads);
185 for(
auto& it : THREAD_MAP ) {
186 msgs.emplace_back(
" {}: {},\tState::{}\n");
187 msgs.emplace_back(++tNr);
188 msgs.emplace_back(it.second);
189 msgs.emplace_back(it.second->state);
195 MAIN_THREAD=
nullptr;
199 Thread* lastThread= THREAD_MAP.begin()->second;
201 "Last thread {} is not the main system thread detected in bootstrap.", lastThread->
id )
204 MAIN_THREAD=
nullptr;
205 #if ALIB_MONOMEM && ALIB_CONTAINERS
227 "Thread \"{}\" destructed, while it was never started.",
this )
231 "Thread \"{}\" was not terminated before destruction.\n"
232 "Use Thread::Join() to avoid this message. Joining now...",
this )
247 "Terminating thread \"{}\" which is not in state 'Done'. State: {}.",
254 ALIB_WARNING(
"THREADS",
"Thread \"{}\" not joinable. State is '{}'.",
this,
state )
260 #if ALIB_MONOMEM && ALIB_CONTAINERS
276 "Double invocation of Thread::Terminate for thread \"{}\".",
this )
279 "Terminating thread \"{}\" which is not started or not managed by ALIB.",
287 ALIB_ERROR(
"THREADS",
"Thread with ID {} was already started.",
GetID() )
292 ALIB_ERROR(
"THREADS",
"System threads cannot be started. (ID={}).",
GetID() )
302 #if ALIB_MONOMEM && ALIB_CONTAINERS
303 THREAD_MAP.EmplaceUnique(
nativeID,
this );
305 THREAD_MAP.insert( std::make_pair(
nativeID,
this) );
324 #if ALIB_MONOMEM && ALIB_CONTAINERS
325 auto search= THREAD_MAP.Find(
nativeID );
327 auto search= THREAD_MAP.find(
nativeID );
331 if ( search != THREAD_MAP.end() )
332 result= search->second;
337 result->
id = nextSystemThreadId--;
340 #if ALIB_MONOMEM && ALIB_CONTAINERS
341 THREAD_MAP.EmplaceUnique(
nativeID, result );
343 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.