The Gaudi Framework  v30r4 (9b837755)
JemallocProfileSvc.cpp
Go to the documentation of this file.
1 // Include files
4 #include "GaudiKernel/Service.h"
5 #include <climits>
6 #include <iostream>
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 int mallctl( const char* name, void* oldp, size_t* oldlenp, void* newp, size_t newlen );
16 }
17 
18 //-----------------------------------------------------------------------------
19 // Implementation file for class : JemallocProfileSvc
20 //
21 // 2016-01-11 : Ben Couturier
22 //-----------------------------------------------------------------------------
23 
24 //=============================================================================
25 // Initializer
26 //=============================================================================
28 {
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  m_incidentSvc->addListener( this, incident );
45  }
46  for ( std::string incident : m_stopAtIncidents ) {
47  m_incidentSvc->addListener( this, incident );
48  }
49 
50  // Resetting the event counter
51  m_eventNumber = 0;
52  m_profiling = false;
53 
54  // Cache whether we have start/stop incidents
55  m_hasStartIncident = ( m_startFromIncidents.size() > 0 );
56  m_hasStopIncident = ( m_stopAtIncidents.size() > 0 );
57 
58  // Checking the consistency of the start/stop events
60  info() << "Stop profiling trigger was specified but no start. Defaulting to first events" << endmsg;
62  }
63 
64  return StatusCode::SUCCESS;
65 }
66 
67 // Finalization of the service.
69 {
70  if ( m_profiling ) {
71  stopProfiling();
72  }
73  // unregistering from the IncidentSvc
74  m_incidentSvc->removeListener( this, IncidentType::BeginEvent );
75  m_incidentSvc->removeListener( this, IncidentType::EndEvent );
77  return base_class::finalize();
78 }
79 
80 //=============================================================================
81 // Event handling methods
82 
83 //=============================================================================
84 
85 // Handler for incidents
86 void JemallocProfileSvc::handle( const Incident& incident )
87 {
88  if ( IncidentType::BeginEvent == incident.type() ) {
89  handleBegin();
90  } else if ( IncidentType::EndEvent == incident.type() ) {
91  handleEnd();
92  }
93 
94  // If already processing we can ignore the incidents for start
95  if ( !m_profiling && m_hasStartIncident ) {
96  for ( std::string startincident : m_startFromIncidents ) {
97  if ( startincident == incident.type() ) {
98  info() << "Starting Jemalloc profile at incident " << incident.type() << endmsg;
100  break;
101  }
102  } // Loop on incidents
103  } // If checking incidents to start
104 
105  // If already processing we can ignore the incidents for start
106  if ( m_profiling && m_hasStopIncident ) {
107  for ( std::string stopincident : m_stopAtIncidents ) {
108  if ( stopincident == incident.type() ) {
109  info() << "Stopping Jemalloc profile at incident " << incident.type() << endmsg;
110  stopProfiling();
111  break;
112  }
113  } // Loop on incidents
114  } // If checking incidents to stop
115 }
116 
117 // Handler for incidents
118 // Called on at begin events
120 {
121  m_eventNumber += 1;
122 
123  if ( m_eventNumber == m_nStartFromEvent ) {
124  startProfiling();
125  }
126 }
127 
128 // Handler for incidents
129 // Called on at End events
131 {
133  ( ( m_eventNumber - m_nStartFromEvent ) % m_dumpPeriod == 0 ) ) {
134  dumpProfile();
135  }
136 
137  if ( m_eventNumber == m_nStopAtEvent ) {
138  stopProfiling();
139  }
140 }
141 
142 //=============================================================================
143 // Utilities calling mallctl
144 
145 //=============================================================================
146 
151 {
152  m_profiling = true;
153  info() << "Starting Jemalloc profile at event " << m_eventNumber << endmsg;
154  mallctl( "prof.dump", NULL, NULL, NULL, 0 );
155 }
156 
161 {
162  m_profiling = false;
163  dumpProfile();
164 }
165 
170 {
171  info() << "Dumping Jemalloc profile at event " << m_eventNumber << endmsg;
172  mallctl( "prof.dump", NULL, NULL, NULL, 0 );
173 }
174 
175 //=============================================================================
176 // Declaration of the factory
constexpr static const auto FAILURE
Definition: StatusCode.h:88
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
bool isFailure() const
Definition: StatusCode.h:139
int mallctl(const char *name, void *oldp, size_t *oldlenp, void *newp, size_t newlen)
STL class.
#define DECLARE_COMPONENT(type)
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:79
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:51
Gaudi::Property< int > m_nStopAtEvent
void stopProfiling()
Utility method to stop profiling with jemalloc.
constexpr static const auto SUCCESS
Definition: StatusCode.h:87
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:92
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:291
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:209
bool m_profiling
Status of the profiling.