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