All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 // Initializer
27 //=============================================================================
29  StatusCode sc = base_class::initialize();
30  if (sc.isFailure()) return sc;
31 
32  // register to the incident service
33  static const std::string serviceName = "IncidentSvc";
34  m_incidentSvc = serviceLocator()->service(serviceName);
35  if ( ! m_incidentSvc ) {
36  error() << "Cannot retrieve " << serviceName << endmsg;
37  return StatusCode::FAILURE;
38  }
39 
40  debug() << "Register to the IncidentSvc" << endmsg;
41  m_incidentSvc->addListener(this, IncidentType::BeginEvent);
42  m_incidentSvc->addListener(this, IncidentType::EndEvent);
43  for (std::string incident: m_startFromIncidents)
44  {
45  m_incidentSvc->addListener(this, incident);
46  }
47  for (std::string incident: m_stopAtIncidents)
48  {
49  m_incidentSvc->addListener(this, incident);
50  }
51 
52  // Resetting the event counter
53  m_eventNumber = 0;
54  m_profiling = false;
55 
56  // Cache whether we have start/stop incidents
57  m_hasStartIncident = (m_startFromIncidents.size() > 0);
58  m_hasStopIncident = (m_stopAtIncidents.size() > 0);
59 
60  // Checking the consistency of the start/stop events
63  {
64  info() << "Stop profiling trigger was specified but no start. Defaulting to first events" << endmsg;
66  }
67 
68 
69 
70  return StatusCode::SUCCESS;
71 }
72 
73 // Finalization of the service.
75 
76  // unregistering from the IncidentSvc
77  m_incidentSvc->removeListener(this, IncidentType::BeginEvent);
78  m_incidentSvc->removeListener(this, IncidentType::EndEvent);
80  return base_class::finalize();
81 }
82 
83 //=============================================================================
84 // Event handling methods
85 
86 //=============================================================================
87 
88 // Handler for incidents
89 void JemallocProfileSvc::handle(const Incident& incident)
90 {
91  if (IncidentType::BeginEvent == incident.type())
92  {
93  handleBegin();
94  } else if (IncidentType::EndEvent == incident.type())
95  {
96  handleEnd();
97  }
98 
99  // If already processing we can ignore the incidents for start
101  {
102  for(std::string startincident: m_startFromIncidents)
103  {
104  if (startincident == incident.type())
105  {
106  info() << "Starting Jemalloc profile at incident "
107  << incident.type() << endmsg;
108  startProfiling();
109  break;
110  }
111  } // Loop on incidents
112  } // If checking incidents to start
113 
114  // If already processing we can ignore the incidents for start
116  {
117  for(std::string stopincident: m_stopAtIncidents)
118  {
119  if (stopincident == incident.type())
120  {
121  info() << "Stopping Jemalloc profile at incident "
122  << incident.type() << endmsg;
123  stopProfiling();
124  break;
125  }
126  } // Loop on incidents
127  } // If checking incidents to stop
128 
129 
130 }
131 
132 // Handler for incidents
133 // Called on at begin events
135 {
136  m_eventNumber += 1;
137 
139  {
140  startProfiling();
141  }
142 }
143 
144 // Handler for incidents
145 // Called on at End events
147 {
148  if (m_profiling
151  {
152  dumpProfile();
153  }
154 
156  {
157  stopProfiling();
158  }
159 }
160 
161 //=============================================================================
162 // Utilities calling mallctl
163 
164 //=============================================================================
165 
170 {
171  m_profiling = true;
172  info() << "Starting Jemalloc profile at event "
173  << m_eventNumber << endmsg;
174  mallctl("prof.dump", NULL, NULL, NULL, 0);
175 }
176 
181 {
182  m_profiling = false;
183  dumpProfile();
184 }
185 
190 {
191  info() << "Dumping Jemalloc profile at event "
192  << m_eventNumber << endmsg;
193  mallctl("prof.dump", NULL, NULL, NULL, 0);
194 
195 }
196 
197 //=============================================================================
198 // Declaration of the factory
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() override
Finalizer.
Gaudi::Property< int > m_dumpPeriod
Service that enables the Jemalloc profiler on demand.
void handle(const Incident &incident) override
Destructor.
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:84
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.
int m_eventNumber
Current event number.
StatusCode initialize() override
Initializer.
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
Gaudi::Property< int > m_nStopAtEvent
void stopProfiling()
Utility method to stop profiling with jemalloc.
Gaudi::Property< int > m_nStartFromEvent
Gaudi::Property< std::vector< std::string > > m_stopAtIncidents
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.
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator.
Definition: Service.cpp:292
Gaudi::Property< std::vector< std::string > > m_startFromIncidents
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.