ALib C++ Library
Library Version: 2511 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
dbgasserters.cpp
1//##################################################################################################
2// ALib C++ Library
3//
4// Copyright 2013-2025 A-Worx GmbH, Germany
5// Published under 'Boost Software License' (a free software license, see LICENSE.txt)
6//##################################################################################################
7#include "alib_precompile.hpp"
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"
10#endif
11#if ALIB_C20_MODULES
12 module;
13#endif
14//========================================= Global Fragment ========================================
15#include "alib/alib.inl"
16//============================================== Module ============================================
17#if ALIB_C20_MODULES
18 module ALib.Threads;
19 import ALib.Lang;
20#else
21# include "ALib.Lang.H"
22# include "ALib.Threads.H"
23# include "ALib.Strings.H"
24#endif
25//========================================== Implementation ========================================
26#if !ALIB_SINGLE_THREADED && ALIB_DEBUG
27
28namespace alib::threads {
29
30//##################################################################################################
31// Class DbgLockAsserter
32//##################################################################################################
34 if ( CntAcquirements.load() == 0 )
35 return nullptr;
36 return Thread::Get(AcqCI.ThreadID);
37}
38
40"Multi-Threading {} in Lock \"{}\"" "\n"
41" Message: {}" "\n"
42" In (Member-)Function: {}" "\n"
43" Is Owned: {} ({})" "\n"
44 "\n"
45" Called By: {}::{}" "\n"
46" At: {}:{}" "\n"
47" Thread: {}" "\n"
48 "\n"
49" Latest Acquisition By: {}::{}" "\n"
50" At: {}:{}" "\n"
51" Thread: {}" "\n"
52" Latest Release By: {}:{}" "\n"
53" At: {}:{}" "\n"
54" Thread: {}" "\n"
55;
56
58"Multi-Threading {} in Shared-Lock \"{}\"" "\n"
59" Message: {}" "\n"
60" In (Member-)Function: {}" "\n"
61" Is Owned: {} ({})" "\n"
62" Is Shared Owned: {} ({})" "\n"
63 "\n"
64" Called By: {}::{}" "\n"
65" At: {}:{}" "\n"
66" Thread: {}" "\n"
67 "\n"
68" Latest Acquisition By: {}::{}" "\n"
69" At: {}:{}" "\n"
70" Thread: {}" "\n"
71" Latest Release By: {}::{}" "\n"
72" At: {}:{}" "\n"
73" Thread: {}" "\n"
74 "\n"
75" Latest Shared Acquisition By: {}::{}" "\n"
76" At: {}:{}" "\n"
77" Thread: {}" "\n"
78" Latest SharedRelease By: {}::{}" "\n"
79" At: {}:{}" "\n"
80" Thread: {}" "\n"
81;
82
83
84void DbgLockAsserter::DoAssert( int type, const CallerInfo& ciAssert, const CallerInfo& ci,
85 const char* headline ) {
86 assert::Raise( ciAssert, type, "THREADS", ASSERTION_FORMAT,
87 (type== 0 ? "Assertion" : "Warning"), // 0
88 Name , headline, // 1 2
89 ciAssert.Func, // 3
90 (CntAcquirements.load() > 0 ? "true" : "false"), // 4
91 CntAcquirements .load(), // 5
92
93 ci.TypeInfo, ci.Func, ci.File, ci.Line, ci.ThreadID,
94 AcqCI.TypeInfo, AcqCI.Func, AcqCI.File, AcqCI.Line, AcqCI.ThreadID,
95 RelCI.TypeInfo, RelCI.Func, RelCI.File, RelCI.Line, RelCI.ThreadID );
96 }
97
98void DbgSharedLockAsserter::DoAssert( int type, const CallerInfo& ciAssert, const CallerInfo& ci,
99 const char* headline ) {
100 assert::Raise( ciAssert, type, "THREADS", ASSERTION_FORMAT_SHARED,
101 (type== 0 ? "Assertion" : "Warning"), // 0
102 Name , headline, // 1 2
103 ciAssert.Func, // 3
104 CntAcquirements .load() >0, CntAcquirements.load(), // 4, 5
105 CntSharedAcquirements.load() >0, CntSharedAcquirements.load(), // 6, 7
106
107 ci.TypeInfo, ci.Func, ci.File, ci.Line, ci.ThreadID,
108 AcqCI.TypeInfo, AcqCI.Func, AcqCI.File, AcqCI.Line, AcqCI.ThreadID,
109 RelCI.TypeInfo, RelCI.Func, RelCI.File, RelCI.Line, RelCI.ThreadID,
110 SAcqCI.TypeInfo, SAcqCI.Func, SAcqCI.File, SAcqCI.Line, SAcqCI.ThreadID,
111 SRelCI.TypeInfo, SRelCI.Func, SRelCI.File, SRelCI.Line, SRelCI.ThreadID
112 );
113}
114
116"Assertion failed in method TCondition::{}" "\n"
117" Message: {}" "\n"
118" Instance: {}" "\n"
119 "\n"
120" Called By: {}::{}" "\n"
121" At: {}:{}" "\n"
122" Thread: {}" "\n"
123 "\n"
124" Current Owner: {}" "\n"
125" #Of Waiters: {}" "\n"
126" Exclusive Waiter: {}" "\n"
127 "\n"
128" Latest Acquisition By: {}::{}" "\n"
129" At: {}:{}" "\n"
130" Thread: {}" "\n"
131" Latest Release By: {}::{}" "\n"
132" At: {}:{}" "\n"
133" Thread: {}" "\n"
134 "\n"
135" Latest Wait By: {}::{}" "\n"
136" At: {}:{}" "\n"
137" Thread: {}" "\n"
138" Latest Notify By: {}::{}" "\n"
139" At: {}:{}" "\n"
140" Thread: {}" "\n"
141;
142
143void DbgConditionAsserter::Assert( bool cond, const CallerInfo& ciAssert, const CallerInfo& ci,
144 const char* headline ) {
145 if (cond)
146 return;
147 assert::Raise( ciAssert, 0, "THREADS", ASSERTION_FORMAT,
148 ciAssert.Func, headline, Name,
149 ci.TypeInfo, ci.Func, ci.File, ci.Line, ci.ThreadID,
151
152 AcqCI.TypeInfo, AcqCI.Func, AcqCI.File, AcqCI.Line, AcqCI.ThreadID,
153 RelCI.TypeInfo, RelCI.Func, RelCI.File, RelCI.Line, RelCI.ThreadID,
154 WaitCI.TypeInfo, WaitCI.Func, WaitCI.File, WaitCI.Line, WaitCI.ThreadID,
155 NotifyCI.TypeInfo, NotifyCI.Func, NotifyCI.File, NotifyCI.Line, NotifyCI.ThreadID );
156
157}
158
159
160void DbgLockAsserter::SetRecursiveOwner (const CallerInfo& assertCI, const CallerInfo& requestCI ) {
161 if( CntAcquirements.load() > 0 && requestCI.ThreadID != AcqCI.ThreadID )
162 DoAssert( 0, assertCI, requestCI, "Already (still) owned." );
163 AcqCI= requestCI;
164 CntAcquirements.fetch_add(1);
165
166 if( RecursionLimit != 0
167 && (CntAcquirements.load() % RecursionLimit) == 0 ) {
168 #if ALIB_STRINGS
169 NAString msg; msg << CntAcquirements.load() << " recursive acquisitions."
170 " Warning limit can be adopted with field DbgRecursionWarningThreshold";
171 DoAssert( 1, ALIB_CALLER, requestCI, msg);
172 #else
173 std::string msg; msg+= std::format("{}", CntAcquirements.load());
174 msg+=" recursive acquisitions."
175 " Warning limit can be adopted with field DbgRecursionWarningThreshold";
176 DoAssert( 1, ALIB_CALLER, requestCI, msg.c_str());
177 #endif
178 }
179
180}
181
182} // namespace [alib::threads]
183
184#endif // !ALIB_SINGLE_THREADED && ALIB_DEBUG
static ALIB_DLL Thread * Get(std::thread::id nativeID)
Definition thread.cpp:314
#define ALIB_CALLER
Definition alib.inl:1018
void Raise(const lang::CallerInfo &ci, int type, std::string_view domain, TArgs &&... args)
Definition assert.inl:181
strings::TAString< nchar, lang::HeapAllocator > NAString
Type alias in namespace alib.
lang::CallerInfo CallerInfo
Type alias in namespace alib.
const char * File
The name of the source file as given by compiler.
const std::type_info * TypeInfo
The calling type.
int Line
The line number within File.
std::thread::id ThreadID
The ID of the calling thread.
ALIB_DLL void Assert(bool cond, const CallerInfo &assertCI, const CallerInfo &ci, const char *headline)
CallerInfo NotifyCI
The most recent call to ReleaseAndNotify or.
const character * Name
The name of this instance.
static ALIB_DLL const char * ASSERTION_FORMAT
CallerInfo RelCI
Source location of the most recent release.
Thread * Owner
Tracks the current owner.
std::atomic< int > CntWaiters
The number of currently waiting threads.
CallerInfo AcqCI
Source location of the most recent acquirement.
CallerInfo WaitCI
The most recent call to WaitForNotification.
static ALIB_DLL const char * ASSERTION_FORMAT
CallerInfo RelCI
Source location of the most recent release.
virtual ALIB_DLL void DoAssert(int type, const CallerInfo &assertCI, const CallerInfo &ci, const char *headline)
ALIB_DLL Thread * GetOwner() const
std::atomic< int > CntAcquirements
The number of shared acquirements.
ALIB_DLL void SetRecursiveOwner(const CallerInfo &assertCI, const CallerInfo &requestCI)
CallerInfo AcqCI
Source location of the most recent acquirement.
CallerInfo SAcqCI
The most recent shared acquirement's caller.
ALIB_DLL void DoAssert(int type, const CallerInfo &assertCI, const CallerInfo &ci, const char *headline) override
static ALIB_DLL const char * ASSERTION_FORMAT_SHARED
std::atomic< int > CntSharedAcquirements
The number of shared acquirements.
CallerInfo SRelCI
The most recent shared release caller.