ALib C++ Library
Library Version: 2412 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
dbgcriticalsections.cpp
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header file is part of module \alib_threads of the \aliblong.
4///
5/// \emoji :copyright: 2013-2024 A-Worx GmbH, Germany.
6/// Published under \ref mainpage_license "Boost Software License".
7//==================================================================================================
9#include "alib/alib.hpp"
10
11#if ALIB_DEBUG_CRITICAL_SECTIONS
14#include "alib/threads/lock.hpp"
21
22#if ALIB_CAMP
24#endif
25
26#if ALIB_ALOX
27# include "alib/alox.hpp"
29#endif
30
31namespace alib::lang {
32
33
34#if ALIB_CAMP && !DOXYGEN // otherwise doxygen will write a bad version of the initial value
36"Assertion in Critical Section {!Q}" "\n"
37" Message: {}" "\n"
38" In (Member-)Function: {2:ya}" "\n"
39" Is Owned: {6}" "\n"
40" Is Shared Owned: {9}" "\n"
41 "\n"
42" Called By: {3:ya}" "\n"
43" At: {3:sf:sl}" "\n"
44" Thread: {3:ta}" "\n"
45 "\n"
46" Latest Acquisition By: {4:ya}" "\n"
47" At: {4:sf:sl}" "\n"
48" Thread: {4:ta}" "\n"
49" Latest Release By: {5:ya}" "\n"
50" At: {5:sf:sl}" "\n"
51" Thread: {5:ta}" "\n"
52 "\n"
53" Latest Shared Acquisition By: {7:ya}" "\n"
54" At: {7:sf:sl}" "\n"
55" Thread: {7:ta}" "\n"
56" Latest SharedRelease By: {8:ya}" "\n"
57" At: {8:sf:sl}" "\n"
58" Thread: {8:ta}" "\n"
59;
60#endif // ALIB_CAMP && !DOXYGEN
61
62void DbgCriticalSections::doAssert( bool cond, const CallerInfo& ciAssert, const CallerInfo& ci,
63 const char* headline ) const
64{
65 if (cond) return;
66
67 String4K msg;
68 #if !ALIB_CAMP
69 msg << "Assertion in Critical Section " << DCSName << "\n"
70 " Message: " << headline << "\n"
71 " Caller: " << ci << "\n"
72 " Is Owned: " << (DCSWriterCnt.load()>0 ? "true " : "false") << " (" << DCSWriterCnt.load() << ")\n"
73 " Is Shared-Owned: " << (DCSReaderCnt.load()>0 ? "true " : "false") << " (" << DCSReaderCnt.load() << ")\n\n"
74 " Latest Acquirement: " << DCSAcq << "\n"
75 " Latest Release: " << DCSRel << "\n\n"
76 " Latest Shared Acquirement: " << DCSSAcq << "\n"
77 " Latest Shared Release: " << DCSSRel << "\n\n"
78 "Note: Include ALib module BaseCamp in the ALib-Distribution to get nicer assertion output.\n";
79 #else
80 String256 acquirementInfo;
81 acquirementInfo << (DCSWriterCnt.load()>0 ? "true " : "false") << " (" <<DCSWriterCnt.load()<< ')';
82 String256 sharedAcquirementInfo;
83 sharedAcquirementInfo << (DCSReaderCnt.load()>0 ? "true " : "false") << " (" <<DCSReaderCnt.load()<< ')';
84
86 fmt.Format( msg, ASSERTION_FORMAT,
87 DCSName, headline,
88 ciAssert, ci,
89 DCSAcq , DCSRel , acquirementInfo,
90 DCSSAcq , DCSSRel, sharedAcquirementInfo);
91
92 #endif
93 #if ALIB_ALOX
94 int oldMode= 1;
95 if ( Log::DebugLogger )
96 {
99 }
100 #endif
101
102 ALIB_STRINGS_TO_NARROW(msg, nmsg, 16*1024) // needed due to MB_CUR_MAX in conversion
103 DbgSimpleALibMsg( ciAssert, 0, "THREADS", nmsg );
104
105 #if ALIB_ALOX
106 if ( Log::DebugLogger )
108 #endif
109}
110
112{
113 doAssert( !DCSLock || DCSLock->DCSIsAcquired(), ALIB_CALLER, ci, "Acquire: Associated Lock not acquired." );
114 doAssert( DCSWriterCnt.load() == 0
115 || DCSAcq.ThreadID == std::this_thread::get_id(), ALIB_CALLER, ci, "Acquired by other thread.");
116 doAssert( DCSReaderCnt.load() == 0, ALIB_CALLER, ci, "Acquired by reader.");
117
118 DCSWriterCnt.fetch_add(1);
119 DCSAcq= ci;
120 yieldOrSleep();
121}
122
124{
125 doAssert(!DCSLock || DCSLock->DCSIsAcquired() , ALIB_CALLER, ci, "Release: Associated lock not acquired." );
126 doAssert(DCSAcq.ThreadID == std::this_thread::get_id(), ALIB_CALLER, ci, "Release: Acquired by other thread.");
127 yieldOrSleep();
128 DCSRel= ci;
129 DCSWriterCnt.fetch_sub(1);
130}
131
133{
135 "AcquireShared: Associated lock not shared-acquired." );
136
137 yieldOrSleep();
138 int wCnt = DCSWriterCnt.load();
139 doAssert(wCnt <= 0 || DCSAcq.ThreadID == std::this_thread::get_id(), ALIB_CALLER, ci,
140 "AcquireShared: Acquired by different thread.");
141 DCSReaderCnt.fetch_add(1);
142 DCSSAcq= ci;
143}
144
146{
147 yieldOrSleep();
149 "ReleaseShared: Associated lock not shared-acquired." );
150
151 doAssert(DCSWriterCnt.load() <= 0 || DCSAcq.ThreadID == std::this_thread::get_id(), ALIB_CALLER, ci,
152 "ReleaseShared: Internal error. Acquired by different thread while shared release.");
153 int prevRCnt= DCSReaderCnt.fetch_sub(1);
154 doAssert(prevRCnt > 0, ALIB_CALLER, ci, "ReleaseShared: No shared acquirement.");
155 DCSSRel= ci;
156}
157
158} // namespace [alib::lang]
159
160#endif // HPP_ALIB_LANG_DBGCRITICALSECTIONS
161
Formatter & Format(AString &target, TArgs &&... args)
static ALIB_API textlogger::TextLogger * DebugLogger
The debug logger created by AddDebugLogger.
Definition log.inl:43
FormatMultiLine & GetFormatMultiLine()
#define ALIB_CALLER
Definition alib.hpp:1164
#define ALIB_STRINGS_TO_NARROW( src, dest, bufSize)
ALIB_API void DbgSimpleALibMsg(const CallerInfo &ci, int type, const char *topic, const char *msg1=nullptr, const char *msg2=nullptr, const char *msg3=nullptr, const char *msg4=nullptr, const char *msg5=nullptr)
std::thread::id ThreadID
The ID of the calling thread.
Definition alib.hpp:1136
static ALIB_API const char * ASSERTION_FORMAT
ALIB_API void doAssert(bool cond, const CallerInfo &ciAssert, const CallerInfo &ci, const char *headline) const
std::atomic< int > DCSReaderCnt
Tracks enter/exit calls of readers.
CallerInfo DCSAcq
Source location of acquirement.
ALIB_API void ReleaseShared(const CallerInfo &ci) const
CallerInfo DCSRel
Source location of the last "reader" seen.
ALIB_API void Release(const CallerInfo &ci) const
CallerInfo DCSSAcq
Source location of acquirement.
CallerInfo DCSSRel
Source location of the last "reader" seen.
const char * DCSName
The name of this DCS. Used for debug-output.
ALIB_API void AcquireShared(const CallerInfo &ci) const
ALIB_FORCE_INLINE void yieldOrSleep() const
ALIB_API void Acquire(const CallerInfo &ci) const
std::atomic< int > DCSWriterCnt
Tracks enter/exit calls (including readers)