00001 #ifdef _WIN32
00002 #pragma warning( disable : 4786 )
00003 #endif
00004
00005 #include <iostream>
00006 #include <iomanip>
00007 #include <string>
00008 #include <algorithm>
00009 #include <functional>
00010
00011
00012 #include "GaudiKernel/Kernel.h"
00013 #include "GaudiKernel/StatusCode.h"
00014
00015 #include "GaudiKernel/ISvcFactory.h"
00016 #include "GaudiKernel/SvcFactory.h"
00017
00018 #include "GaudiKernel/IChronoStatSvc.h"
00019
00020 #include "GaudiKernel/MsgStream.h"
00024 #include "ChronoEntity.h"
00025 #include "StatEntity.h"
00026
00027 #include "ChronoStatSvc.h"
00028
00036
00037
00040 static const SvcFactory<ChronoStatSvc> s_factory ;
00041 extern const ISvcFactory& ChronoStatSvcFactory = s_factory ;
00042
00043
00047 ChronoStatSvc::ChronoStatSvc( const std::string& name, ISvcLocator* svcloc )
00048 : Service( name , svcloc )
00049 , m_chronoEntities ()
00050 , m_chronoPrintLevel ( MSG::INFO )
00051 , m_statEntities ()
00052 , m_statPrintLevel ( MSG::INFO )
00053 {
00056 declareProperty("ChronoPrintOutTable" , m_chronoTableFlag = true );
00058 declareProperty("ChronoDestinationCout" , m_chronoCoutFlag = false );
00060 declareProperty("ChronoPrintLevel" , m_intChronoPrintLevel = MSG::INFO );
00062 declareProperty("ChronoTableToBeOrdered" , m_chronoOrderFlag = true );
00064 declareProperty("PrintUserTime" , m_printUserTime = true );
00066 declareProperty("PrintSystemTime" , m_printSystemTime = false );
00068 declareProperty("PrintEllapsedTime" , m_printEllapsedTime = false );
00071 declareProperty("StatPrintOutTable" , m_statTableFlag = true );
00073 declareProperty("StatDestinationCout" , m_statCoutFlag = false );
00075 declareProperty("StatPrintLevel" , m_intStatPrintLevel = MSG::INFO );
00077 declareProperty("StatTableToBeOrdered" , m_statOrderFlag = true );
00078 };
00079
00080
00084 ChronoStatSvc::~ChronoStatSvc()
00085 {
00086
00087 m_chronoEntities.clear();
00088
00089 m_statEntities.clear();
00090 };
00091
00095 StatusCode ChronoStatSvc::initialize()
00096 {
00097 StatusCode sc = Service::initialize();
00098 if( sc.isFailure() ) return sc;
00100
00101 setProperties();
00105 m_statPrintLevel =
00106 ( MSG::FATAL < m_intStatPrintLevel ) ? MSG::FATAL :
00107 ( MSG::NIL > m_intStatPrintLevel ) ? MSG::NIL : ( MSG::Level ) m_intStatPrintLevel ;
00109 m_chronoPrintLevel =
00110 ( MSG::FATAL < m_intChronoPrintLevel ) ? MSG::FATAL :
00111 ( MSG::NIL > m_intChronoPrintLevel ) ? MSG::NIL : ( MSG::Level ) m_intChronoPrintLevel ;
00113 if( m_chronoTableFlag &&
00114 !m_printUserTime && !m_printSystemTime && !m_printEllapsedTime ) { m_printUserTime = true ; }
00116 if( m_printUserTime || m_printSystemTime || m_printEllapsedTime ) { m_chronoTableFlag = true ; }
00119 chronoStart( name() );
00121 return StatusCode::SUCCESS;
00122 };
00123
00124
00128 StatusCode ChronoStatSvc::finalize()
00129 {
00130 std::string local = name()+".finalize()";
00132 MsgStream log( msgSvc() , local );
00135 chronoStop( name() );
00136
00139 if( m_chronoTableFlag && !m_chronoEntities.empty() && ( m_printUserTime || m_printSystemTime ) )
00140 {
00142 MsgStream log( msgSvc() , "*****Chrono*****" );
00143 const std::string stars( ( m_chronoCoutFlag ) ? 126 : 100 , '*' );
00144 if( m_chronoCoutFlag )
00145 {
00146 std::cout << stars << std::endl;
00147 std::cout << local << " The Final CPU consumption (Chrono) Table "
00148 << ( m_chronoOrderFlag ? "(ordered)" : "(not ordered)" ) << std::endl;
00149 std::cout << stars << std::endl;
00150 }
00151 else
00152 {
00153 log << (MSG::Level) m_chronoPrintLevel << stars << endreq;
00154 log << (MSG::Level) m_chronoPrintLevel << " The Final CPU consumption ( Chrono ) Table "
00155 << ( m_chronoOrderFlag ? "(ordered)" : "(not ordered)" ) << endreq;
00156 log << (MSG::Level) m_chronoPrintLevel << stars << endreq;
00157 }
00159 {
00160 typedef std::pair<ChronoEntity*,const ChronoTag*> MPair;
00161 typedef std::vector<MPair> MCont;
00162 MCont tmpCont;
00163 for( ChronoMap::iterator it = m_chronoEntities.begin() ; m_chronoEntities.end() != it ; ++it )
00164 { tmpCont.push_back( MPair( &(it->second) , &(it->first) ) ) ; }
00165
00166 if( m_chronoOrderFlag )
00167 { std::sort( tmpCont.begin(), tmpCont.end() , ChronoEntity::ComparePairOfChronoEntityAndChronoTag() ); }
00168
00169 if( m_printUserTime )
00170 {
00171 for( MCont::iterator iter = tmpCont.begin() ; tmpCont.end() != iter ; ++iter )
00172 {
00173
00174 ChronoEntity* entity = iter->first ; if( 0 == entity ) { continue ; }
00175 const ChronoTag* tag = iter->second ; if( 0 == tag ) { continue ; }
00176
00177 entity->stop();
00178
00179 if ( m_chronoCoutFlag )
00180 { std::cout << *tag << "\t" << entity->outputUserTime () << std::endl ; }
00181 else
00182 {
00183 MsgStream log( msgSvc() , *tag ) ;
00184 log << m_chronoPrintLevel << entity->outputUserTime () << endreq ;
00185 }
00186
00187 }
00188 }
00190 if( m_printSystemTime )
00191 {
00194 if ( m_printUserTime && m_chronoCoutFlag )
00195 { std::cout << stars << std::endl; }
00196 else if ( m_printUserTime && !m_chronoCoutFlag )
00197 { log << (MSG::Level) m_chronoPrintLevel << stars << endreq; }
00199 for( MCont::iterator iter = tmpCont.begin() ; tmpCont.end() != iter ; ++iter )
00200 {
00202 ChronoEntity* entity = iter->first ; if( 0 == entity ) { continue ; }
00203 const ChronoTag* tag = iter->second ; if( 0 == tag ) { continue ; }
00204
00205 entity->stop();
00206
00207 if ( m_chronoCoutFlag )
00208 { std::cout << *tag << "\t" << entity->outputSystemTime() << std::endl ; }
00209 else
00210 {
00211 MsgStream log( msgSvc() , *tag ) ;
00212 log << m_chronoPrintLevel << entity->outputSystemTime() << endreq ;
00213 }
00214
00215 }
00216 }
00218 if( m_printEllapsedTime )
00219 {
00222 if ( ( m_printUserTime || m_printSystemTime ) && m_chronoCoutFlag )
00223 { std::cout << stars << std::endl; }
00224 else if ( ( m_printUserTime || m_printSystemTime ) && !m_chronoCoutFlag )
00225 { log << (MSG::Level) m_chronoPrintLevel << stars << endreq; }
00227 for( MCont::iterator iter = tmpCont.begin() ; tmpCont.end() != iter ; ++iter )
00228 {
00230 ChronoEntity* entity = iter->first ; if( 0 == entity ) { continue ; }
00231 const ChronoTag* tag = iter->second ; if( 0 == tag ) { continue ; }
00232
00233 entity->stop();
00234
00235 if ( m_chronoCoutFlag )
00236 { std::cout << *tag << "\t" << entity->outputEllapsedTime() << std::endl ; }
00237 else
00238 {
00239 MsgStream log( msgSvc() , *tag ) ;
00240 log << m_chronoPrintLevel << entity->outputEllapsedTime() << endreq ;
00241 }
00242
00243 }
00244 }
00246 tmpCont.clear();
00247 }
00249 if( m_chronoCoutFlag ) { std::cout << stars << std::endl; }
00250 else { log << m_chronoPrintLevel << stars << endreq; }
00251 }
00252
00255 if( m_statTableFlag && !m_statEntities.empty() )
00256 {
00258 MsgStream log( msgSvc() , "******Stat******" );
00260 const std::string stars( ( m_statCoutFlag ) ? 126 : 100 , '*' ) ;
00262 if( m_statCoutFlag )
00263 {
00264 std::cout << stars << std::endl;
00265 std::cout << local << " The Final stat Table "
00266 << ( m_statOrderFlag ? "(ordered)" : "(not ordered)" ) << std::endl;
00267 std::cout << stars << std::endl;
00268 }
00269 else
00270 {
00271 log << m_statPrintLevel << stars << endreq;
00272 log << m_statPrintLevel << " The Final stat Table "
00273 << ( m_statOrderFlag ? "(ordered)" : "(not ordered)" ) << endreq;
00274 log << m_statPrintLevel << stars << endreq;
00275 }
00277 {
00278 typedef std::pair<const StatEntity*,const StatTag*> SPair;
00279 typedef std::vector<SPair> SCont;
00280 SCont tmpCont;
00281 for( StatMap::const_iterator it = m_statEntities.begin(); it != m_statEntities.end(); it++ )
00282 { tmpCont.push_back( SPair( &(it->second) , &(it->first) ) ) ; }
00283
00284 if( m_statOrderFlag )
00285 { std::sort( tmpCont.begin(), tmpCont.end() , StatEntity::ComparePairOfStatEntityAndStatTag() ); }
00287 for( SCont::iterator iter = tmpCont.begin() ; tmpCont.end() != iter ; ++iter )
00288 {
00290 const StatEntity* entity = iter->first ; if( 0 == entity ) { continue ; }
00291 const StatTag* tag = iter->second ; if( 0 == tag ) { continue ; }
00292
00293 if ( m_statCoutFlag ) { std::cout << *tag << "\t" << entity->stringOutPut() << std::endl; }
00294 else
00295 {
00296 MsgStream log( msgSvc() , *tag ) ;
00297 log << m_statPrintLevel << entity->stringOutPut() << endreq ;
00298 }
00299 }
00300 tmpCont.clear();
00301 }
00303 if( m_statCoutFlag ) { std::cout << stars << std::endl; }
00304 else { log << m_statPrintLevel << stars << endreq; }
00305 }
00306
00307 log << MSG::INFO << " Service finalized succesfully " << endreq;
00308
00309 return StatusCode::SUCCESS;
00310 };
00311
00315 StatusCode ChronoStatSvc::queryInterface(const IID& riid, void** ppvInterface)
00316 {
00317 if ( IID_IChronoStatSvc == riid ) { *ppvInterface = (IChronoStatSvc*) this ; }
00318 else { return Service::queryInterface(riid, ppvInterface) ; }
00319 addRef();
00320 return StatusCode::SUCCESS;
00321 };
00322
00326 StatusCode ChronoStatSvc::chronoStart( const ChronoTag& chronoTag )
00327 {
00328 m_chronoEntities[ chronoTag ].start();
00329 return StatusCode::SUCCESS;
00330 };
00331
00335 StatusCode ChronoStatSvc::chronoStop ( const IChronoStatSvc::ChronoTag& chronoTag )
00336 { m_chronoEntities[ chronoTag ].stop(); return StatusCode::SUCCESS; };
00337
00341 StatusCode ChronoStatSvc::chronoPrint( const IChronoStatSvc::ChronoTag& chronoTag )
00342 {
00343 MsgStream log ( msgSvc() , chronoTag );
00344 if( m_printUserTime ) { log << (MSG::Level) m_chronoPrintLevel
00345 << m_chronoEntities[ chronoTag ].outputUserTime () << endreq; }
00346 if( m_printSystemTime ) { log << (MSG::Level) m_chronoPrintLevel
00347 << m_chronoEntities[ chronoTag ].outputSystemTime() << endreq; }
00348 return StatusCode::SUCCESS;
00349 };
00350
00354 IChronoStatSvc::ChronoStatus ChronoStatSvc::chronoStatus( const IChronoStatSvc::ChronoTag& chronoTag )
00355 { return m_chronoEntities[ chronoTag ].status(); };
00356
00360
00364 StatusCode ChronoStatSvc::stat( const IChronoStatSvc::StatTag & statTag ,
00365 const IChronoStatSvc::StatFlag & statFlag ,
00366 const IChronoStatSvc::StatWeight & statWeight )
00367 {
00368 StatEntity& se = m_statEntities[ statTag ];
00369 se.addFlagAndWeight( statFlag, statWeight ) ;
00370 return StatusCode::SUCCESS;
00371 };
00372
00376 StatusCode ChronoStatSvc::statPrint( const IChronoStatSvc::StatTag& statTag )
00377 {
00378 MsgStream log ( msgSvc() , statTag ) ;
00379 log << (MSG::Level) m_statPrintLevel << m_statEntities[ statTag ].stringOutPut() << endreq;
00380 return StatusCode::SUCCESS;
00381 };
00382