JemallocProfileSvc.cpp
Go to the documentation of this file.
1 // Include files
2 #include "GaudiKernel/Service.h"
5 #include <iostream>
6 #include <climits>
7 
8 // local
9 #include "JemallocProfileSvc.h"
10 
11 // including jemmalloc.h is difficult as the malloc signature is not exactly identical
12 // to the system one (issue with throw).
13 // We therefore declare mallctl here.
14 extern "C"
15 {
16  int mallctl(const char *name, void *oldp, size_t *oldlenp, void *newp, size_t newlen);
17 }
18 
19 //-----------------------------------------------------------------------------
20 // Implementation file for class : JemallocProfileSvc
21 //
22 // 2016-01-11 : Ben Couturier
23 //-----------------------------------------------------------------------------
24 
25 //=============================================================================
26 // Standard constructor, initializes variables
27 //=============================================================================
29  base_class(name, svcLoc), m_eventNumber(0), m_startFromIncidents({}),
30  m_stopAtIncidents({}), m_hasStartIncident(false), m_hasStopIncident(false),
31  m_profiling(false) {
32 
33  declareProperty("StartFromEventN", m_nStartFromEvent = 0,
34  "After what event we start profiling. "
35  );
36 
37  declareProperty("StartFromIncidents", m_startFromIncidents = {},
38  "Incidents that trigger profiling start"
39  );
40 
41  declareProperty("StopAtEventN", m_nStopAtEvent = 0,
42  "After what event we stop profiling. "
43  "If 0 than we also profile finalization stage. Default = 0."
44  );
45 
46  declareProperty("StopAtIncidents", m_stopAtIncidents = {},
47  "Incidents that trigger profiling start"
48  );
49 
50  declareProperty("DumpPeriod", m_dumpPeriod = 100,
51  "Period for dumping head to a file. Default=100"
52  );
53 
54 }
55 
56 //=============================================================================
57 // Initializer
58 //=============================================================================
61  if (sc.isFailure()) return sc;
62 
63  // register to the incident service
64  static const std::string serviceName = "IncidentSvc";
65  m_incidentSvc = serviceLocator()->service(serviceName);
66  if ( ! m_incidentSvc ) {
67  error() << "Cannot retrieve " << serviceName << endmsg;
68  return StatusCode::FAILURE;
69  }
70 
71  debug() << "Register to the IncidentSvc" << endmsg;
72  m_incidentSvc->addListener(this, IncidentType::BeginEvent);
73  m_incidentSvc->addListener(this, IncidentType::EndEvent);
74  for (std::string incident: m_startFromIncidents)
75  {
76  m_incidentSvc->addListener(this, incident);
77  }
78  for (std::string incident: m_stopAtIncidents)
79  {
80  m_incidentSvc->addListener(this, incident);
81  }
82 
83  // Resetting the event counter
84  m_eventNumber = 0;
85  m_profiling = false;
86 
87  // Cache whether we have start/stop incidents
88  m_hasStartIncident = (m_startFromIncidents.size() > 0);
89  m_hasStopIncident = (m_stopAtIncidents.size() > 0);
90 
91  // Checking the consistency of the start/stop events
94  {
95  info() << "Stop profiling trigger was specified but no start. Defaulting to first events" << endmsg;
97  }
98 
99 
100 
101  return StatusCode::SUCCESS;
102 }
103 
104 // Finalization of the service.
106 
107  // unregistering from the IncidentSvc
108  m_incidentSvc->removeListener(this, IncidentType::BeginEvent);
109  m_incidentSvc->removeListener(this, IncidentType::EndEvent);
111  return base_class::finalize();
112 }
113 
114 //=============================================================================
115 // Event handling methods
116 
117 //=============================================================================
118 
119 // Handler for incidents
120 void JemallocProfileSvc::handle(const Incident& incident)
121 {
122  if (IncidentType::BeginEvent == incident.type())
123  {
124  handleBegin();
125  } else if (IncidentType::EndEvent == incident.type())
126  {
127  handleEnd();
128  }
129 
130  // If already processing we can ignore the incidents for start
132  {
133  for(std::string startincident: m_startFromIncidents)
134  {
135  if (startincident == incident.type())
136  {
137  info() << "Starting Jemalloc profile at incident "
138  << incident.type() << endmsg;
139  startProfiling();
140  break;
141  }
142  } // Loop on incidents
143  } // If checking incidents to start
144 
145  // If already processing we can ignore the incidents for start
147  {
148  for(std::string stopincident: m_stopAtIncidents)
149  {
150  if (stopincident == incident.type())
151  {
152  info() << "Stopping Jemalloc profile at incident "
153  << incident.type() << endmsg;
154  stopProfiling();
155  break;
156  }
157  } // Loop on incidents
158  } // If checking incidents to stop
159 
160 
161 }
162 
163 // Handler for incidents
164 // Called on at begin events
166 {
167  m_eventNumber += 1;
168 
170  {
171  startProfiling();
172  }
173 }
174 
175 // Handler for incidents
176 // Called on at End events
178 {
179  if (m_profiling
182  {
183  dumpProfile();
184  }
185 
187  {
188  stopProfiling();
189  }
190 }
191 
192 //=============================================================================
193 // Utilities calling mallctl
194 
195 //=============================================================================
196 
201 {
202  m_profiling = true;
203  info() << "Starting Jemalloc profile at event "
204  << m_eventNumber << endmsg;
205  mallctl("prof.dump", NULL, NULL, NULL, 0);
206 }
207 
212 {
213  m_profiling = false;
214  dumpProfile();
215 }
216 
221 {
222  info() << "Dumping Jemalloc profile at event "
223  << m_eventNumber << endmsg;
224  mallctl("prof.dump", NULL, NULL, NULL, 0);
225 
226 }
227 
228 
229 //=============================================================================
230 // Destructor
231 
232 //=============================================================================
234 
235 //=============================================================================
236 // Declaration of the factory
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator.
Definition: Service.cpp:324
StatusCode initialize()
Initializer.
def initialize()
Definition: AnalysisTest.py:12
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:25
const std::string & type() const
Access to the incident type.
Definition: Incident.h:41
void startProfiling()
Utility method to start profiling with jemalloc.
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
StatusCode finalize()
Finalizer.
Service that enables the Jemalloc profiler on demand.
std::vector< std::string > m_stopAtIncidents
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:86
int mallctl(const char *name, void *oldp, size_t *oldlenp, void *newp, size_t newlen)
#define DECLARE_COMPONENT(type)
Definition: PluginService.h:36
STL class.
StatusCode service(const Gaudi::Utils::TypeNameString &name, T *&svc, bool createIf=true)
Templated method to access a service by name.
Definition: ISvcLocator.h:78
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
void stopProfiling()
Utility method to stop profiling with jemalloc.
std::vector< std::string > m_startFromIncidents
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
Base class for all Incidents (computing events).
Definition: Incident.h:17
virtual void addListener(IIncidentListener *lis, const std::string &type="", long priority=0, bool rethrow=false, bool singleShot=false)=0
Add listener.
void dumpProfile()
Utility method to dump profile with jemalloc.
SmartIF< IIncidentSvc > m_incidentSvc
Pointer to the incident service.
void reset(TYPE *ptr=nullptr)
Set the internal pointer to the passed one disposing of the old one.
Definition: SmartIF.h:88
virtual void removeListener(IIncidentListener *lis, const std::string &type="")=0
Remove listener.
JemallocProfileSvc(const std::string &name, ISvcLocator *svcLoc)
Standard constructor.
int m_nStartFromEvent
Start, End event and counter.
void handle(const Incident &incident)
Destructor.
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
bool m_profiling
Status of the profiling.