ALib C++ Framework
by
Library Version: 2605 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
dbgasserters.cpp
1#if !ALIB_SINGLE_THREADED && ALIB_DEBUG
2
3namespace alib::threads {
4
5//##################################################################################################
6// Class DbgLockAsserter
7//##################################################################################################
9 if ( CntAcquirements.load() == 0 )
10 return nullptr;
11 return Thread::Get(Acq.CI.ThreadID);
12}
13
15"Multi-Threading {} in Lock \"{}\"" "\n"
16" Message: {}" "\n"
17" In (Member-)Function: {}" "\n"
18" Is Owned: {} ({})" "\n"
19 "\n"
20" Called By: {}::{}" "\n"
21" At: {}:{}" "\n"
22" Thread: {}" "\n"
23 "\n"
24" Latest Acquisition By: {}::{}" "\n"
25" At: {}:{}" "\n"
26" Seq / Thread: {} / {}" "\n"
27" Latest Release By: {}:{}" "\n"
28" At: {}:{}" "\n"
29" Seq / Thread: {} / {}" "\n"
30;
31
33"Multi-Threading {} in Shared-Lock \"{}\"" "\n"
34" Message: {}" "\n"
35" In (Member-)Function: {}" "\n"
36" Is Owned: {} ({})" "\n"
37" Is Shared Owned: {} ({})" "\n"
38 "\n"
39" Called By: {}::{}" "\n"
40" At: {}:{}" "\n"
41" Thread: {}" "\n"
42 "\n"
43" Latest Acquisition By: {}::{}" "\n"
44" At: {}:{}" "\n"
45" Seq / Thread: {} / {}" "\n"
46" Latest Release By: {}::{}" "\n"
47" At: {}:{}" "\n"
48" Seq / Thread: {} / {}" "\n"
49 "\n"
50" Latest Shared Acquisition By: {}::{}" "\n"
51" At: {}:{}" "\n"
52" Seq / Thread: {} / {}" "\n"
53" Latest SharedRelease By: {}::{}" "\n"
54" At: {}:{}" "\n"
55" Seq / Thread: {} / {}" "\n"
56;
57
58
59void DbgLockAsserter::DoAssert( int type, const CallerInfo& ciAssert, const CallerInfo& ci,
60 const char* headline ) {
61 assert::Raise( ciAssert, type, "THREADS", ASSERTION_FORMAT,
62 (type== 0 ? "Assertion" : "Warning"), // 0
63 Name , headline, // 1 2
64 ciAssert.Func, // 3
65 (CntAcquirements.load() > 0 ? "true" : "false"), // 4
66 CntAcquirements .load(), // 5
67
68 ci.TypeInfo, ci.Func, ci.File, ci.Line, ci.ThreadID,
69 Acq.CI.TypeInfo, Acq.CI.Func, Acq.CI.File, Acq.CI.Line, Acq.ActionNo, Acq.CI.ThreadID,
70 Rel.CI.TypeInfo, Rel.CI.Func, Rel.CI.File, Rel.CI.Line, Rel.ActionNo, Rel.CI.ThreadID );
71 }
72
73void DbgSharedLockAsserter::DoAssert( int type, const CallerInfo& ciAssert, const CallerInfo& ci,
74 const char* headline ) {
75 assert::Raise( ciAssert, type, "THREADS", ASSERTION_FORMAT_SHARED,
76 (type== 0 ? "Assertion" : "Warning"), // 0
77 Name , headline, // 1 2
78 ciAssert.Func, // 3
79 CntAcquirements .load() >0, CntAcquirements.load(), // 4, 5
80 CntSharedAcquirements.load() >0, CntSharedAcquirements.load(), // 6, 7
81
82 ci.TypeInfo, ci.Func, ci.File, ci.Line, ci.ThreadID,
83 Acq.CI.TypeInfo, Acq.CI.Func, Acq.CI.File, Acq.CI.Line, Acq.ActionNo, Acq.CI.ThreadID,
84 Rel.CI.TypeInfo, Rel.CI.Func, Rel.CI.File, Rel.CI.Line, Rel.ActionNo, Rel.CI.ThreadID,
85 SAcq.CI.TypeInfo, SAcq.CI.Func, SAcq.CI.File, SAcq.CI.Line, SAcq.ActionNo, SAcq.CI.ThreadID,
86 SRel.CI.TypeInfo, SRel.CI.Func, SRel.CI.File, SRel.CI.Line, SRel.ActionNo, SRel.CI.ThreadID
87 );
88}
89
91"Assertion failed in method TCondition::{}" "\n"
92" Message: {}" "\n"
93" Instance: {}" "\n"
94 "\n"
95" Called By: {}::{}" "\n"
96" At: {}:{}" "\n"
97" Thread: {}" "\n"
98 "\n"
99" Current Owner: {}" "\n"
100" #Of Waiters: {}" "\n"
101" Exclusive Waiter: {}" "\n"
102 "\n"
103" Latest Acquisition By: {}::{}" "\n"
104" At: {}:{}" "\n"
105" Seq / Thread: {} / {}" "\n"
106" Latest Release By: {}::{}" "\n"
107" At: {}:{}" "\n"
108" Seq / Thread: {} / {}" "\n"
109 "\n"
110" Latest Wait By: {}::{}" "\n"
111" At: {}:{}" "\n"
112" Seq / Thread: {} / {}" "\n"
113" Latest Notify By: {}::{}" "\n"
114" At: {}:{}" "\n"
115" Seq / Thread: {} / {}" "\n"
116;
117
118void DbgConditionAsserter::Assert( bool cond, const CallerInfo& ciAssert, const CallerInfo& ci,
119 const char* headline ) {
120 if (cond)
121 return;
122 assert::Raise( ciAssert, 0, "THREADS", ASSERTION_FORMAT,
123 ciAssert.Func, headline, Name,
124 ci.TypeInfo, ci.Func, ci.File, ci.Line, ci.ThreadID,
126
127 Acq.CI.TypeInfo, Acq.CI.Func, Acq.CI.File, Acq.CI.Line, Acq.ActionNo, Acq.CI.ThreadID,
128 Rel.CI.TypeInfo, Rel.CI.Func, Rel.CI.File, Rel.CI.Line, Rel.ActionNo, Rel.CI.ThreadID,
129 Wait.CI.TypeInfo, Wait.CI.Func, Wait.CI.File, Wait.CI.Line, Wait.ActionNo, Wait.CI.ThreadID,
130 Notify.CI.TypeInfo, Notify.CI.Func, Notify.CI.File, Notify.CI.Line, Notify.ActionNo, Notify.CI.ThreadID );
131
132}
133
134
135void DbgLockAsserter::SetRecursiveOwner (const CallerInfo& assertCI, const CallerInfo& requestCI ) {
136 if( CntAcquirements.load() > 0 && requestCI.ThreadID != Acq.CI.ThreadID )
137 DoAssert( 0, assertCI, requestCI, "Already (still) owned." );
138 Acq.CI= requestCI;
139 CntAcquirements.fetch_add(1);
140
141 if( RecursionLimit != 0
142 && (CntAcquirements.load() % RecursionLimit) == 0 ) {
143 #if ALIB_STRINGS
144 NAString msg; msg << CntAcquirements.load() << " recursive acquisitions."
145 " Warning limit can be adopted with field DbgRecursionWarningThreshold";
146 DoAssert( 1, ALIB_CALLER, requestCI, msg);
147 #else
148 std::string msg; msg+= std::format("{}", CntAcquirements.load());
149 msg+=" recursive acquisitions."
150 " Warning limit can be adopted with field DbgRecursionWarningThreshold";
151 DoAssert( 1, ALIB_CALLER, requestCI, msg.c_str());
152 #endif
153 }
154
155}
156
157} // namespace [alib::threads]
158
159#endif // !ALIB_SINGLE_THREADED && ALIB_DEBUG
#define ALIB_CALLER
static Thread * Get(std::thread::id nativeID)
Definition thread.cpp:253
void Raise(const lang::CallerInfo &ci, int type, std::string_view domain, TArgs &&... args)
Definition assert.hpp:178
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.
ActionInfo Rel
Source location of the most recent release.
void Assert(bool cond, const CallerInfo &assertCI, const CallerInfo &ci, const char *headline)
const character * Name
The name of this instance.
ActionInfo Acq
Source location of the most recent acquirement.
Thread * Owner
Tracks the current owner.
ActionInfo Notify
The most recent call to #"%ReleaseAndNotify".
std::atomic< int > CntWaiters
The number of currently waiting threads.
static const char * ASSERTION_FORMAT
ActionInfo Rel
Source location of the most recent release.
virtual void DoAssert(int type, const CallerInfo &assertCI, const CallerInfo &ci, const char *headline)
ActionInfo Acq
Source location of the most recent acquirement.
std::atomic< int > CntAcquirements
The number of shared acquirements.
void SetRecursiveOwner(const CallerInfo &assertCI, const CallerInfo &requestCI)
ActionInfo SAcq
The most recent shared acquirement's caller.
void DoAssert(int type, const CallerInfo &assertCI, const CallerInfo &ci, const char *headline) override
static const char * ASSERTION_FORMAT_SHARED
std::atomic< int > CntSharedAcquirements
The number of shared acquirements.
ActionInfo SRel
The most recent shared release caller.