ATLAS Offline Software
Loading...
Searching...
No Matches
ProfilerService.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 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
19namespace 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 : base_class( 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
50
51 ATH_MSG_INFO( "Initializing GPT::ProfilerService" );
52
53 // Don't do anything fancy if the profiling is under user control, just
54 // remind the user of it:
56 ATH_MSG_INFO( " Profiling is under user control" );
57 return StatusCode::SUCCESS;
58 }
59
60 // Start the profiling at this point if full-job profiling is requested:
61 if( m_initEvent < 0 ) {
62
64
65 } else {
66
67 // Set up listening to the incidents only if we are profiling the
68 // event loop with this service:
69 CHECK( m_incidentSvc.retrieve() );
70 m_incidentSvc->addListener( this, BEGINEVENT_INCIDENT_NAME );
71 m_incidentSvc->addListener( this, ENDEVTLOOP_INCIDENT_NAME );
72
73 }
74
75 // Reset the event counter:
77
78 return StatusCode::SUCCESS;
79 }
80
82
83 ATH_MSG_INFO( "Finalizing GPT::ProfilerService" );
84
85 // The profiling should only be stopped in the destructor even if we
86 // are not under user control...
87
88 return StatusCode::SUCCESS;
89 }
90
99 StatusCode ProfilerService::startCPUProfiling( const std::string& filename ) {
100
101 // Check whether the CPU profiling is already running:
102 if( m_running ) {
104 }
105
106 // Tell the user what's happening:
107 ATH_MSG_INFO( "Starting CPU profiling using output file: " << filename );
108
109 // Remember the profile file name:
110 m_fileName = filename;
111
112 // Start the Google profiler:
113 ProfilerStart( m_fileName.c_str() );
114
115 // Remember that we are in a running state:
116 m_running = true;
117
118 return StatusCode::SUCCESS;
119 }
120
128
129 // This should not be called when we are not running:
130 if( ! m_running ) {
131 REPORT_MESSAGE( MSG::ERROR )
132 << "CPU profiling not running at the time of call";
133 return StatusCode::RECOVERABLE;
134 }
135
136 // Stop the profiler:
137 ProfilerStop();
138
139 // Tell the user what happened:
140 ATH_MSG_INFO( "Stopped CPU profiling using output file: " << m_fileName );
141
142 // Remember that we are not running anymore:
143 m_running = false;
144
145 return StatusCode::SUCCESS;
146 }
147
156
157 return m_running;
158 }
159
167 void ProfilerService::handle( const Incident& inc ) {
168
169 //
170 // Stop the profiling after the last event, if we are only profiling
171 // the event loop:
172 //
173 if( ( inc.type() == ENDEVTLOOP_INCIDENT_NAME ) &&
174 ( ! m_controlledProfiling ) &&
175 ( m_initEvent >= 0 ) ) {
176 if( stopCPUProfiling().isFailure() ) {
177 REPORT_MESSAGE( MSG::ERROR )
178 << "Could not stop the CPU profiling";
179 }
180 return;
181 }
182
183 //
184 // Start the profiling if we only profile the event loop,
185 // and we're in the correct event:
186 //
187 if( ( inc.type() == BEGINEVENT_INCIDENT_NAME ) &&
188 ( ! m_controlledProfiling ) ) {
190 if( startCPUProfiling( m_profFileName ).isFailure() ) {
191 REPORT_MESSAGE( MSG::ERROR )
192 << "Could not start the CPU profiling";
193 }
194 }
196 return;
197 }
198
199 // Complain if we received an incident that we didn't expect:
200 ATH_MSG_WARNING( "Wrong incident type received: " << inc.type() );
201 return;
202 }
203
204} // namespace GPT
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
Helpers for checking error return status codes and reporting errors.
#define REPORT_MESSAGE(LVL)
Report a message.
#define CHECK(...)
Evaluate an expression and check for errors.
virtual ~ProfilerService()
Destructor.
bool m_running
Is the CPU profiling running at the moment?
virtual StatusCode stopCPUProfiling() override
Stop the GPT profiling.
virtual StatusCode finalize() override
Standard Gaudi finalization function.
virtual bool isCPUProfilingRunning() const override
Is the GPT profiling running at the moment?
ServiceHandle< IIncidentSvc > m_incidentSvc
Handle to the incident service.
int m_initEvent
Property: Event in which non-controlled profiling should start.
std::string m_fileName
Name of the current profile file.
ProfilerService(const std::string &name, ISvcLocator *svcloc)
Standard Gaudi service constructor.
virtual StatusCode startCPUProfiling(const std::string &filename) override
Start GPT profiling.
virtual void handle(const Incident &inc) override
Function handling incoming incidents.
int m_processedEvents
Number of events processed so far.
bool m_controlledProfiling
Property: Is profiling controlled from the outside?
virtual StatusCode initialize() override
Standard Gaudi initialization function.
std::string m_profFileName
Property: Profile file name in non-controlled profiling.
static const std::string ENDEVTLOOP_INCIDENT_NAME
static const std::string BEGINEVENT_INCIDENT_NAME