ATLAS Offline Software
ProfilerService.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 
6 // GPT include(s):
7 #ifdef ATLAS_CMAKE
8 #include <google/profiler.h>
9 #else
10 #include <gperftools/profiler.h>
11 #endif
12 
13 // Gaudi/Athena include(s):
15 
16 // Local include(s):
17 #include "ProfilerService.h"
18 
19 namespace GPT {
20 
21  //
22  // Convenience variable(s):
23  //
24  static const std::string BEGINEVENT_INCIDENT_NAME = "BeginEvent";
25  static const std::string ENDEVTLOOP_INCIDENT_NAME = "EndEvtLoop";
26 
27  ProfilerService::ProfilerService( const std::string& name, ISvcLocator* svcloc )
28  : AthService( name, svcloc ),
29  m_incidentSvc( "IncidentSvc", name ),
30  m_running( false ), m_fileName( "" ), m_processedEvents( 0 ) {
31 
32  declareProperty( "ControlledProfiling", m_controlledProfiling = false,
33  "Will the service be controlled by another component?" );
34  declareProperty( "InitEvent", m_initEvent = -1,
35  "Event in which to start the profiling. Negative number "
36  "profiles the entire job." );
37  declareProperty( "ProfileFileName", m_profFileName = "gpt.profile",
38  "Profile file name in con-controlled mode." );
39  }
40 
42 
43  // Stop the CPU profiling at this point if it's still running:
44  if( m_running ) {
45  stop().ignore();
46  }
47  }
48 
49  StatusCode ProfilerService::queryInterface( const InterfaceID& riid,
50  void** ppvIF ) {
51 
52  if( ! ppvIF ) {
53  return StatusCode::FAILURE;
54  }
55 
56  if( riid == IProfilerSvc::interfaceID() ) {
57  *ppvIF = static_cast< IProfilerSvc* >( this );
58  return StatusCode::SUCCESS;
59  }
60 
61  return AthService::queryInterface( riid, ppvIF );
62  }
63 
65 
66  ATH_MSG_INFO( "Initializing GPT::ProfilerService" );
67 
68  // Don't do anything fancy if the profiling is under user control, just
69  // remind the user of it:
70  if( m_controlledProfiling ) {
71  ATH_MSG_INFO( " Profiling is under user control" );
72  return StatusCode::SUCCESS;
73  }
74 
75  // Start the profiling at this point if full-job profiling is requested:
76  if( m_initEvent < 0 ) {
77 
79 
80  } else {
81 
82  // Set up listening to the incidents only if we are profiling the
83  // event loop with this service:
84  CHECK( m_incidentSvc.retrieve() );
85  m_incidentSvc->addListener( this, BEGINEVENT_INCIDENT_NAME );
86  m_incidentSvc->addListener( this, ENDEVTLOOP_INCIDENT_NAME );
87 
88  }
89 
90  // Reset the event counter:
92 
93  return StatusCode::SUCCESS;
94  }
95 
97 
98  ATH_MSG_INFO( "Finalizing GPT::ProfilerService" );
99 
100  // The profiling should only be stopped in the destructor even if we
101  // are not under user control...
102 
103  return StatusCode::SUCCESS;
104  }
105 
115 
116  // Check whether the CPU profiling is already running:
117  if( m_running ) {
118  CHECK( stopCPUProfiling() );
119  }
120 
121  // Tell the user what's happening:
122  ATH_MSG_INFO( "Starting CPU profiling using output file: " << filename );
123 
124  // Remember the profile file name:
126 
127  // Start the Google profiler:
128  ProfilerStart( m_fileName.c_str() );
129 
130  // Remember that we are in a running state:
131  m_running = true;
132 
133  return StatusCode::SUCCESS;
134  }
135 
143 
144  // This should not be called when we are not running:
145  if( ! m_running ) {
146  REPORT_MESSAGE( MSG::ERROR )
147  << "CPU profiling not running at the time of call";
148  return StatusCode::RECOVERABLE;
149  }
150 
151  // Stop the profiler:
152  ProfilerStop();
153 
154  // Tell the user what happened:
155  ATH_MSG_INFO( "Stopped CPU profiling using output file: " << m_fileName );
156 
157  // Remember that we are not running anymore:
158  m_running = false;
159 
160  return StatusCode::SUCCESS;
161  }
162 
171 
172  return m_running;
173  }
174 
182  void ProfilerService::handle( const Incident& inc ) {
183 
184  //
185  // Stop the profiling after the last event, if we are only profiling
186  // the event loop:
187  //
188  if( ( inc.type() == ENDEVTLOOP_INCIDENT_NAME ) &&
189  ( ! m_controlledProfiling ) &&
190  ( m_initEvent >= 0 ) ) {
191  if( stopCPUProfiling().isFailure() ) {
192  REPORT_MESSAGE( MSG::ERROR )
193  << "Could not stop the CPU profiling";
194  }
195  return;
196  }
197 
198  //
199  // Start the profiling if we only profile the event loop,
200  // and we're in the correct event:
201  //
202  if( ( inc.type() == BEGINEVENT_INCIDENT_NAME ) &&
203  ( ! m_controlledProfiling ) ) {
204  if( m_initEvent == m_processedEvents ) {
205  if( startCPUProfiling( m_profFileName ).isFailure() ) {
206  REPORT_MESSAGE( MSG::ERROR )
207  << "Could not start the CPU profiling";
208  }
209  }
211  return;
212  }
213 
214  // Complain if we received an incident that we didn't expect:
215  ATH_MSG_WARNING( "Wrong incident type received: " << inc.type() );
216  return;
217  }
218 
219 } // namespace GPT
GPT::ProfilerService::finalize
virtual StatusCode finalize()
Standard Gaudi finalization function.
Definition: ProfilerService.cxx:96
GPT::ProfilerService::stopCPUProfiling
virtual StatusCode stopCPUProfiling()
Stop the GPT profiling.
Definition: ProfilerService.cxx:142
ProfilerService.h
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
GPT::ProfilerService::initialize
virtual StatusCode initialize()
Standard Gaudi initialization function.
Definition: ProfilerService.cxx:64
GPT::ProfilerService::queryInterface
virtual StatusCode queryInterface(const InterfaceID &riid, void **ppvIF)
Function declaring the interface(s) implemented by the service.
Definition: ProfilerService.cxx:49
GPT::ProfilerService::m_processedEvents
int m_processedEvents
Number of events processed so far.
Definition: ProfilerService.h:83
GPT::ProfilerService::m_fileName
std::string m_fileName
Name of the current profile file.
Definition: ProfilerService.h:80
GPT::IProfilerSvc
Simple interface for the profiler service.
Definition: IProfilerSvc.h:34
GPT::ProfilerService::m_controlledProfiling
bool m_controlledProfiling
Property: Is profiling controlled from the outside?
Definition: ProfilerService.h:71
PixelModuleFeMask_create_db.stop
int stop
Definition: PixelModuleFeMask_create_db.py:76
GPT
Definition: IProfilerSvc.h:17
GPT::ProfilerService::m_running
bool m_running
Is the CPU profiling running at the moment?
Definition: ProfilerService.h:78
GPT::ProfilerService::~ProfilerService
virtual ~ProfilerService()
Destructor.
Definition: ProfilerService.cxx:41
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
AthService
Definition: AthService.h:32
GPT::ProfilerService::handle
virtual void handle(const Incident &inc)
Function handling incoming incidents.
Definition: ProfilerService.cxx:182
GPT::ProfilerService::ProfilerService
ProfilerService(const std::string &name, ISvcLocator *svcloc)
Standard Gaudi service constructor.
Definition: ProfilerService.cxx:27
CHECK
#define CHECK(...)
Evaluate an expression and check for errors.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:422
GPT::ProfilerService::m_initEvent
int m_initEvent
Property: Event in which non-controlled profiling should start.
Definition: ProfilerService.h:73
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
errorcheck.h
Helpers for checking error return status codes and reporting errors.
GPT::IProfilerSvc::interfaceID
static const InterfaceID & interfaceID()
Interface ID definition.
Definition: IProfilerSvc.h:38
REPORT_MESSAGE
#define REPORT_MESSAGE(LVL)
Report a message.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:365
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
GPT::ProfilerService::startCPUProfiling
virtual StatusCode startCPUProfiling(const std::string &filename)
Start GPT profiling.
Definition: ProfilerService.cxx:114
GPT::ProfilerService::isCPUProfilingRunning
virtual bool isCPUProfilingRunning() const
Is the GPT profiling running at the moment?
Definition: ProfilerService.cxx:170
GPT::ProfilerService::m_incidentSvc
ServiceHandle< IIncidentSvc > m_incidentSvc
Handle to the incident service.
Definition: ProfilerService.h:68
GPT::ProfilerService::m_profFileName
std::string m_profFileName
Property: Profile file name in non-controlled profiling.
Definition: ProfilerService.h:75
CaloCellTimeCorrFiller.filename
filename
Definition: CaloCellTimeCorrFiller.py:24