58 {
59 using namespace std::chrono_literals;
60
63 const bool doStackTrace;
64 const bool abortOnTimeout;
65 const unsigned int timeout;
66 const EventContext
ctx;
67
68 const std::vector<IScheduler*> schedulers;
69
71
72 const std::chrono::steady_clock::time_point eventStart{ std::chrono::steady_clock::now() };
73
74 void operator()() {
76 if ( counter == 1 ) {
77 log <<
MSG::WARNING << std::format(
"More than {}s since the beginning of the event ({})", timeout, ctx )
79 } else {
80 log <<
MSG::WARNING << std::format(
"Another {}s passed since last timeout ({})", timeout, ctx ) <<
endmsg;
81 }
84 << std::format( "Current memory usage is virtual size = {} MB, resident set size = {} MB",
87 }
88
89 std::scoped_lock protectReport( s_watchdogReportMutex );
90 if ( doStackTrace ) {
91 for (
auto scheduler : schedulers ) {
scheduler->dumpState(); }
92 if ( gSystem ) {
93
94 std::cerr << std::format( "=== Stalled event: current stack trace ({}) ===\n", ctx );
95 gSystem->StackTrace();
96 }
97 }
98 if ( abortOnTimeout ) {
99 log <<
MSG::FATAL << std::format(
"too much time on a single event ({}): aborting process", ctx ) <<
endmsg;
100 std::raise( SIGQUIT );
101 }
102 }
103
104 ~Action() {
105 if ( counter ) {
106 const std::chrono::duration<float, std::chrono::seconds::period> duration =
107 std::chrono::steady_clock::now() - eventStart;
108 log <<
MSG::INFO << std::format(
"An event ({}) took {:.3f}s", ctx, duration.count() ) <<
endmsg;
109 }
110 }
111 };
112
113 std::vector<IScheduler*> schedulers;
115
116 std::ranges::copy( svcLoc()->getServices() |
118 std::views::filter( []( auto* p ) { return p != nullptr; } ),
119 std::back_inserter( schedulers ) );
120 }
121
123
124 EventContext{
ctx.evt(),
ctx.slot(),
ctx.subSlot() }, std::move( schedulers ) };
125 return PeriodicAction( std::move( action ), std::chrono::seconds{
m_eventTimeout } );
126 }
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.