54 {
55 using namespace std::chrono_literals;
56
59 const bool doStackTrace;
60 const bool abortOnTimeout;
61 const unsigned int timeout;
62 const EventContext
ctx;
63
64 const std::vector<IScheduler*> schedulers;
65
67
68 const std::chrono::steady_clock::time_point eventStart{ std::chrono::steady_clock::now() };
69
70 void operator()() {
72 if ( counter == 1 ) {
73 log <<
MSG::WARNING << std::format(
"More than {}s since the beginning of the event ({})", timeout, ctx )
75 } else {
76 log <<
MSG::WARNING << std::format(
"Another {}s passed since last timeout ({})", timeout, ctx ) <<
endmsg;
77 }
80 << std::format( "Current memory usage is virtual size = {} MB, resident set size = {} MB",
83 }
84
85 std::scoped_lock protectReport( s_watchdogReportMutex );
86 if ( doStackTrace ) {
87 for (
auto scheduler : schedulers ) {
scheduler->dumpState(); }
88 if ( gSystem ) {
89
90 std::cerr << std::format( "=== Stalled event: current stack trace ({}) ===\n", ctx );
91 gSystem->StackTrace();
92 }
93 }
94 if ( abortOnTimeout ) {
95 log <<
MSG::FATAL << std::format(
"too much time on a single event ({}): aborting process", ctx ) <<
endmsg;
96 std::raise( SIGQUIT );
97 }
98 }
99
100 ~Action() {
101 if ( counter ) {
102 const std::chrono::duration<float, std::chrono::seconds::period> duration =
103 std::chrono::steady_clock::now() - eventStart;
104 log <<
MSG::INFO << std::format(
"An event ({}) took {:.3f}s", ctx, duration.count() ) <<
endmsg;
105 }
106 }
107 };
108
109 std::vector<IScheduler*> schedulers;
111
112 std::ranges::copy( svcLoc()->getServices() |
114 std::views::filter( []( auto* p ) { return p != nullptr; } ),
115 std::back_inserter( schedulers ) );
116 }
117
119
120 EventContext{
ctx.evt(),
ctx.slot(),
ctx.subSlot() }, std::move( schedulers ) };
121 return PeriodicAction( std::move( action ), std::chrono::seconds{
m_eventTimeout } );
122 }
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Gaudi::Property< bool > m_abortOnTimeout
Gaudi::Property< bool > m_stackTrace
TARGET * Cast(IInterface *i)
GAUDI_API long pagedMemory(MemoryUnit unit=kByte, InfoType fetch=Memory, long pid=-1)
Basic Process Information: Amount of paged memory currently occupied by the process 'pid'.
GAUDI_API long virtualMemory(MemoryUnit unit=kByte, InfoType fetch=Memory, long pid=-1)
Basic Process Information: priority boost.