| The Gaudi Framework v32r1 (f65d50dc)

JemallocProfileSvc.cpp
Go to the documentation of this file.
1 // Include files
2 #include "GaudiKernel/IIncidentListener.h"
3 #include "GaudiKernel/IIncidentSvc.h"
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 //=============================================================================
27 StatusCode JemallocProfileSvc::initialize() {
28 StatusCode sc = base_class::initialize();
29 if ( sc.isFailure() ) return sc;
30
31 // register to the incident service
32 static const std::string serviceName = "IncidentSvc";
33 m_incidentSvc = serviceLocator()->service( serviceName );
34 if ( !m_incidentSvc ) {
35 error() << "Cannot retrieve " << serviceName << endmsg;
36 return StatusCode::FAILURE;
37 }
38
39 debug() << "Register to the IncidentSvc" << endmsg;
40 m_incidentSvc->addListener( this, IncidentType::BeginEvent );
41 m_incidentSvc->addListener( this, IncidentType::EndEvent );
42 for ( std::string incident : m_startFromIncidents ) { m_incidentSvc->addListener( this, incident ); }
43 for ( std::string incident : m_stopAtIncidents ) { m_incidentSvc->addListener( this, incident ); }
44
45 // Resetting the event counter
46 m_eventNumber = 0;
47 m_profiling = false;
48
49 // Cache whether we have start/stop incidents
50 m_hasStartIncident = ( m_startFromIncidents.size() > 0 );
51 m_hasStopIncident = ( m_stopAtIncidents.size() > 0 );
52
53 // Checking the consistency of the start/stop events
54 if ( m_nStartFromEvent == 0 && !m_hasStartIncident && ( m_hasStopIncident || m_nStopAtEvent > 0 ) ) {
55 info() << "Stop profiling trigger was specified but no start. Defaulting to first events" << endmsg;
56 m_nStartFromEvent = 1;
57 }
58
59 return StatusCode::SUCCESS;
60 }
61
62 // Finalization of the service.
63 StatusCode JemallocProfileSvc::finalize() {
64 if ( m_profiling ) { stopProfiling(); }
65 // unregistering from the IncidentSvc
66 m_incidentSvc->removeListener( this, IncidentType::BeginEvent );
67 m_incidentSvc->removeListener( this, IncidentType::EndEvent );
68 m_incidentSvc.reset();
69 return base_class::finalize();
70 }
71
72 //=============================================================================
73 // Event handling methods
74
75 //=============================================================================
76
77 // Handler for incidents
78 void JemallocProfileSvc::handle( const Incident& incident ) {
79 if ( IncidentType::BeginEvent == incident.type() ) {
80 handleBegin();
81 } else if ( IncidentType::EndEvent == incident.type() ) {
82 handleEnd();
83 }
84
85 // If already processing we can ignore the incidents for start
86 if ( !m_profiling && m_hasStartIncident ) {
87 for ( std::string startincident : m_startFromIncidents ) {
88 if ( startincident == incident.type() ) {
89 info() << "Starting Jemalloc profile at incident " << incident.type() << endmsg;
90 startProfiling();
91 break;
92 }
93 } // Loop on incidents
94 } // If checking incidents to start
95
96 // If already processing we can ignore the incidents for start
97 if ( m_profiling && m_hasStopIncident ) {
98 for ( std::string stopincident : m_stopAtIncidents ) {
99 if ( stopincident == incident.type() ) {
100 info() << "Stopping Jemalloc profile at incident " << incident.type() << endmsg;
101 stopProfiling();
102 break;
103 }
104 } // Loop on incidents
105 } // If checking incidents to stop
106 }
107
108 // Handler for incidents
109 // Called on at begin events
110 inline void JemallocProfileSvc::handleBegin() {
111 m_eventNumber += 1;
112
113 if ( m_eventNumber == m_nStartFromEvent ) { startProfiling(); }
114 }
115
116 // Handler for incidents
117 // Called on at End events
118 inline void JemallocProfileSvc::handleEnd() {
119 if ( m_profiling && m_eventNumber != m_nStartFromEvent &&
120 ( ( m_eventNumber - m_nStartFromEvent ) % m_dumpPeriod == 0 ) ) {
121 dumpProfile();
122 }
123
124 if ( m_eventNumber == m_nStopAtEvent ) { stopProfiling(); }
125 }
126
127 //=============================================================================
128 // Utilities calling mallctl
129
130 //=============================================================================
131
135 inline void JemallocProfileSvc::startProfiling() {
136 m_profiling = true;
137 info() << "Starting Jemalloc profile at event " << m_eventNumber << endmsg;
138 mallctl( "prof.dump", NULL, NULL, NULL, 0 );
139 }
140
144 inline void JemallocProfileSvc::stopProfiling() {
145 m_profiling = false;
146 dumpProfile();
147 }
148
152 inline void JemallocProfileSvc::dumpProfile() {
153 info() << "Dumping Jemalloc profile at event " << m_eventNumber << endmsg;
154 mallctl( "prof.dump", NULL, NULL, NULL, 0 );
155 }
156
157 //=============================================================================
158 // Declaration of the factory
159 DECLARE_COMPONENT( JemallocProfileSvc )
Service::serviceLocator
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator.
Definition: Service.cpp:277
JemallocProfileSvc::startProfiling
void startProfiling()
Utility method to start profiling with jemalloc.
Definition: JemallocProfileSvc.cpp:135
gaudiComponentHelp.name
name
Definition: gaudiComponentHelp.py:41
Incident::type
const std::string & type() const
Access to the incident type.
Definition: Incident.h:38
JemallocProfileSvc::finalize
StatusCode finalize() override
Finalizer.
Definition: JemallocProfileSvc.cpp:63
JemallocProfileSvc::m_dumpPeriod
Gaudi::Property< int > m_dumpPeriod
Definition: JemallocProfileSvc.h:49
JemallocProfileSvc
Service that enables the Jemalloc profiler on demand.
Definition: JemallocProfileSvc.h:18
JemallocProfileSvc::m_hasStopIncident
bool m_hasStopIncident
Definition: JemallocProfileSvc.h:55
StatusCode::SUCCESS
constexpr static const auto SUCCESS
Definition: StatusCode.h:85
JemallocProfileSvc::handle
void handle(const Incident &incident) override
Definition: JemallocProfileSvc.cpp:78
CommonMessagingBase::info
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
Definition: CommonMessaging.h:104
JemallocProfileSvc::handleBegin
void handleBegin()
Definition: JemallocProfileSvc.cpp:110
mallctl
int mallctl(const char *name, void *oldp, size_t *oldlenp, void *newp, size_t newlen)
std::string
STL class.
DECLARE_COMPONENT
#define DECLARE_COMPONENT(type)
Definition: PluginServiceV1.h:46
JemallocProfileSvc::m_eventNumber
int m_eventNumber
Current event number.
Definition: JemallocProfileSvc.h:52
Service.h
JemallocProfileSvc::initialize
StatusCode initialize() override
Initializer.
Definition: JemallocProfileSvc.cpp:27
ISvcLocator::service
StatusCode service(const Gaudi::Utils::TypeNameString &name, T *&svc, bool createIf=true)
Templated method to access a service by name.
Definition: ISvcLocator.h:76
CommonMessagingBase::error
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
Definition: CommonMessaging.h:98
IIncidentSvc.h
StatusCode
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:50
CommonMessagingBase::debug
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
Definition: CommonMessaging.h:107
JemallocProfileSvc::m_nStopAtEvent
Gaudi::Property< int > m_nStopAtEvent
Definition: JemallocProfileSvc.h:44
JemallocProfileSvc::stopProfiling
void stopProfiling()
Utility method to stop profiling with jemalloc.
Definition: JemallocProfileSvc.cpp:144
JemallocProfileSvc::m_hasStartIncident
bool m_hasStartIncident
Definition: JemallocProfileSvc.h:54
JemallocProfileSvc::m_nStartFromEvent
Gaudi::Property< int > m_nStartFromEvent
Definition: JemallocProfileSvc.h:41
JemallocProfileSvc::m_stopAtIncidents
Gaudi::Property< std::vector< std::string > > m_stopAtIncidents
Definition: JemallocProfileSvc.h:47
Incident
Base class for all Incidents (computing events).
Definition: Incident.h:17
IIncidentSvc::addListener
virtual void addListener(IIncidentListener *lis, const std::string &type="", long priority=0, bool rethrow=false, bool singleShot=false)=0
Add listener.
JemallocProfileSvc::dumpProfile
void dumpProfile()
Utility method to dump profile with jemalloc.
Definition: JemallocProfileSvc.cpp:152
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:86
JemallocProfileSvc::handleEnd
void handleEnd()
Definition: JemallocProfileSvc.cpp:118
JemallocProfileSvc::m_incidentSvc
SmartIF< IIncidentSvc > m_incidentSvc
Pointer to the incident service.
Definition: JemallocProfileSvc.h:61
IIncidentListener.h
JemallocProfileSvc.h
SmartIF::reset
void reset(TYPE *ptr=nullptr)
Set the internal pointer to the passed one disposing of the old one.
Definition: SmartIF.h:86
IIncidentSvc::removeListener
virtual void removeListener(IIncidentListener *lis, const std::string &type="")=0
Remove listener.
StatusCode::isFailure
bool isFailure() const
Definition: StatusCode.h:130
JemallocProfileSvc::m_startFromIncidents
Gaudi::Property< std::vector< std::string > > m_startFromIncidents
Definition: JemallocProfileSvc.h:42
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:192
JemallocProfileSvc::m_profiling
bool m_profiling
Status of the profiling.
Definition: JemallocProfileSvc.h:58