ATLAS Offline Software
AlgorithmTimer.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
12 
13 // Gaudi includes
14 #include "GaudiKernel/ServiceHandle.h"
15 
16 // Athena includes
19 
20 // #include "Utils.h"
21 #include <dlfcn.h>
22 #include <stdint.h>
23 #include <sys/types.h>
24 #include <unistd.h>
25 
26 // STL includes
27 #include <iostream>
28 #include <sstream>
29 #include <algorithm>
30 #include <string>
31 
32 using namespace Athena;
33 
34 
35 namespace Athena {
36  namespace AlgorithmTimerHandler
37  {
38 
42  void onAlarmThread(sigval_t sv)
43  {
44  AlgorithmTimer* me = static_cast<AlgorithmTimer*>(sv.sival_ptr);
45  if (me != nullptr && me->m_active)
46  me->m_onAlarm();
47  }
48  }
49 }
50 
51 //--------------------------------------------------------------------------------
52 // AlgorithmTimer
53 //--------------------------------------------------------------------------------
54 
55 AlgorithmTimer::AlgorithmTimer(unsigned int milliseconds,
58  m_timeout (0),
59  m_timerid(),
60  m_onAlarm(callback),
61  m_gdb_details (0)
62 {
63  // prevent valgrind warning
64  // new warning popped up, needs new glibc for this, see http://bugs.kde.org/show_bug.cgi?id=124478
65  // possibly valgrind will be fixed, eventually.
66  std::memset (&m_sigevent, 0, sizeof (m_sigevent));
67 
68  m_sigevent.sigev_value.sival_ptr = this;
69 
70  if (m_onAlarm == NULL)
71  m_onAlarm = std::bind(&AlgorithmTimer::abortJob,this);
72 
73  m_sigevent.sigev_notify = SIGEV_THREAD;
74  m_sigevent.sigev_signo = 0;
75  m_sigevent.sigev_notify_function = AlgorithmTimerHandler::onAlarmThread;
76  m_sigevent.sigev_notify_attributes = NULL;
77 
78  // Create the timer
79  if ( conf & USEREALTIME )
80  {
81 #ifndef __APPLE__
82  timer_create(CLOCK_REALTIME, &m_sigevent, &m_timerid);
83 #endif
84  }
85  else
86  {
87  /*
88  * can use virtual time only, if defined on this system
89  */
90 #ifndef __APPLE__
91 #ifdef _POSIX_CPUTIME
92  timer_create(_POSIX_CPUTIME, &m_sigevent, &m_timerid);
93 #else
94  timer_create(CLOCK_REALTIME, &m_sigevent, &m_timerid);
95  std::cerr << "\nNo _POSIX_CPUTIME defined on this system !\n\n";
96  // we could also disable this timer in this case !
97  // seconds = 0;
98 #endif
99 #endif
100  }
101  // Start the timer if requested
102  if(milliseconds)
103  start(milliseconds);
104 }
105 
107 {
108 #ifndef __APPLE__
109  m_active = false;
110  timer_delete(m_timerid);
111 #endif
112 }
113 
114 void AlgorithmTimer::start(unsigned int milliseconds)
115 {
116  // Set the timer
117  m_timeout = milliseconds;
118 #ifndef __APPLE__
119  itimerspec spec;
120  spec.it_value.tv_sec = int(m_timeout/1000);
121  spec.it_value.tv_nsec = 1000000*(m_timeout%1000);
122  spec.it_interval.tv_sec = 0;
123  spec.it_interval.tv_nsec = 0;
124 
125  m_active = true;
126  timer_settime(m_timerid, 0, &spec, NULL);
127 #endif
128 }
129 
131 {
132  scope.m_timer = this;
133  start(scope.m_timeout);
134 }
135 
136 unsigned int AlgorithmTimer::stop()
137 {
138  // stop the timer, and retrieve remaining time
139 #ifndef __APPLE__
140  itimerspec spec;
141  spec.it_value.tv_sec = 0;
142  spec.it_value.tv_nsec = 0;
143  spec.it_interval.tv_sec = 0;
144  spec.it_interval.tv_nsec = 0;
145 
146  itimerspec ovalue;
147  m_active = false;
148  timer_settime(m_timerid, 0, &spec, &ovalue);
149  return 1000*ovalue.it_value.tv_sec + int(ovalue.it_value.tv_nsec/1000000);
150 #else
151  return 0;
152 #endif
153 }
154 
155 unsigned int AlgorithmTimer::timeLeft() const
156 {
157 #ifndef __APPLE__
158  itimerspec spec;
159  timer_gettime( m_timerid, &spec );
160  return 1000*spec.it_value.tv_sec + int(spec.it_value.tv_nsec/1000000);
161 #else
162  return 0;
163 #endif
164 }
165 
167 {
168  /*
169  * Print stack trace and abort the job.
170  */
171  std::ostringstream os;
172  os << "Timeout ";
173  os << " (" << this->timeout() << " msec) reached";
174 
175  ServiceHandle<ICoreDumpSvc> coreDumpSvc("CoreDumpSvc", "AlgorithmTimer");
176  if ( coreDumpSvc.retrieve().isSuccess() )
177  {
178  coreDumpSvc->setCoreDumpInfo("Reason", os.str());
179  std::cerr << coreDumpSvc->dump() << std::endl;
180  }
181  else
182  {
183  std::cerr << os.str() << std::endl;
184  }
185  abort();
186 }
Athena::AlgorithmTimer::abortJob
callbackFct_t abortJob()
Definition: AlgorithmTimer.cxx:166
Athena::AlgorithmTimer::AlgorithmTimerConfig
AlgorithmTimerConfig
Configuration flags for AlgorithmTimer.
Definition: AlgorithmTimer.h:96
getMessageSvc.h
singleton-like access to IMessageSvc via open function and helper
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
02DownloadFromGrid.scope
string scope
Definition: 02DownloadFromGrid.py:6
Athena::ScopedTimer
Helper class to create a "scoped cook timer" without having to declare the CookTimer itself within th...
Definition: AlgorithmTimer.h:182
CaloCondBlobAlgs_fillNoiseFromASCII.spec
spec
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:47
Athena::AlgorithmTimer::m_timeout
unsigned int m_timeout
timeout in milliseconds
Definition: AlgorithmTimer.h:154
Athena::AlgorithmTimer::m_timerid
timer_t m_timerid
timer ID
Definition: AlgorithmTimer.h:160
runLayerRecalibration.callback
callback
Definition: runLayerRecalibration.py:64
Athena::AlgorithmTimer::timeLeft
unsigned int timeLeft() const
Returns the time left in milliseconds.
Definition: AlgorithmTimer.cxx:155
CoreDumpSvc::setCoreDumpInfo
virtual void setCoreDumpInfo(const std::string &name, const std::string &value) override
Set a name/value pair in the core dump record.
Definition: CoreDumpSvc.cxx:364
Athena::AlgorithmTimer::start
void start(ScopedTimer &scope)
Start the timer.
Definition: AlgorithmTimer.cxx:130
Athena::AlgorithmTimer::USEREALTIME
@ USEREALTIME
use real time instead of system time
Definition: AlgorithmTimer.h:98
python.ConfigurableDb.conf
def conf
Definition: ConfigurableDb.py:282
AlgorithmTimer.h
Efficient realtime timers.
Athena::AlgorithmTimer::stop
unsigned int stop()
Stop the timer and return the time left in [ms].
Definition: AlgorithmTimer.cxx:136
Athena::AlgorithmTimerHandler::onAlarmThread
void onAlarmThread(sigval_t sv)
Function called by signals delivered via threads.
Definition: AlgorithmTimer.cxx:42
Athena::AlgorithmTimer::timeout
unsigned int timeout() const
Returns the currently set timeout (in milliseconds)
Definition: AlgorithmTimer.h:148
Athena
Some weak symbol referencing magic...
Definition: AthLegacySequence.h:21
CoreDumpSvcHandler::coreDumpSvc
CoreDumpSvc * coreDumpSvc(nullptr)
pointer to CoreDumpSvc
Athena::AlgorithmTimer::AlgorithmTimer
AlgorithmTimer()
no default constructor
CoreDumpSvc::dump
virtual std::string dump() const override
Print all core dump records.
Definition: CoreDumpSvc.cxx:392
Athena::AlgorithmTimer::start
void start()
(Re)start the timer with the last timeout used
Definition: AlgorithmTimer.h:121
ReadFromCoolCompare.os
os
Definition: ReadFromCoolCompare.py:231
Athena::AlgorithmTimer::callbackFct_t
std::function< void()> callbackFct_t
Definition: AlgorithmTimer.h:101
Athena::AlgorithmTimer::m_active
std::atomic_bool m_active
flag protecting race condition at stop
Definition: AlgorithmTimer.h:162
Athena::AlgorithmTimer::m_onAlarm
callbackFct_t m_onAlarm
user callback
Definition: AlgorithmTimer.h:161
LArCellConditions.sv
bool sv
Definition: LArCellConditions.py:45
ICoreDumpSvc.h
Interface of a core dump service.
Athena::AlgorithmTimer::~AlgorithmTimer
~AlgorithmTimer()
Destroy and disable the timer.
Definition: AlgorithmTimer.cxx:106
Athena::AlgorithmTimer::m_sigevent
struct sigevent m_sigevent
for signal handler
Definition: AlgorithmTimer.h:159
Athena::AlgorithmTimer
Timer that invokes a user callback once the time is reached.
Definition: AlgorithmTimer.h:87