Commit ab3d10e9 authored by Marco Clemencic's avatar Marco Clemencic
Browse files

Speed up CommonMessaging::msgLevel check

preserve thread safety and fix the regression reported in GAUDI-1319
parent f3731fea
......@@ -228,7 +228,8 @@ StatusCode HistogramPersistencySvc::createRep( DataObject* pObj, IOpaqueAddress*
HistogramPersistencySvc::HistogramPersistencySvc( const std::string& name, ISvcLocator* svc )
: PersistencySvc( name, svc )
{
m_svcNames = std::vector<std::string>{{"RootHistSvc"}};
// bypass update handler
m_svcNames.value() = std::vector<std::string>{{"RootHistSvc"}};
}
// ============================================================================
......
......@@ -216,3 +216,12 @@ StatusCode AlgorithmManager::restart()
}
return rc;
}
void AlgorithmManager::outputLevelUpdate()
{
resetMessaging();
for ( auto& algItem : m_algs ) {
const auto alg = dynamic_cast<Algorithm*>( algItem.algorithm.get() );
if ( alg ) alg->resetMessaging();
}
}
......@@ -86,6 +86,9 @@ public:
AlgTypeAliasesMap& typeAliases() { return m_algTypeAliases; }
const AlgTypeAliasesMap& typeAliases() const { return m_algTypeAliases; }
/// Function to call to update the outputLevel of the components (after a change in MessageSvc).
void outputLevelUpdate() override;
private:
std::vector<AlgorithmItem> m_algs; ///< algorithms maintained by AlgorithmManager
......
......@@ -135,18 +135,33 @@ StatusCode ApplicationMgr::i_startup()
// declare factories in current module
m_classManager->loadModule( "" ).ignore();
#pragma message "warning: cannot use CommonMessaging here yet!"
// Create the Message service
auto msgsvc = svcManager()->createService( Gaudi::Utils::TypeNameString( "MessageSvc", m_messageSvcType ) );
if ( !msgsvc ) {
fatal() << "Error creating MessageSvc of type " << m_messageSvcType << endmsg;
return StatusCode::FAILURE;
}
// Create the Job Options service
// Get the useful interface from Message services
m_messageSvc = m_svcLocator->service( "MessageSvc" );
if ( !m_messageSvc ) {
fatal() << "Error retrieving MessageSvc." << endmsg;
return StatusCode::FAILURE;
}
auto jobsvc = svcManager()->createService( Gaudi::Utils::TypeNameString( "JobOptionsSvc", m_jobOptionsSvcType ) );
// Create the Job Options service
if ( !jobsvc ) {
fatal() << "Error creating JobOptionsSvc" << endmsg;
return StatusCode::FAILURE;
}
// Get the useful interface from Message services
m_jobOptionsSvc = m_svcLocator->service( "JobOptionsSvc" );
if ( !m_jobOptionsSvc ) {
fatal() << "Error retrieving JobOptionsSvc." << endmsg;
return StatusCode::FAILURE;
}
auto jobOptsIProp = jobsvc.as<IProperty>();
if ( !jobOptsIProp ) {
......@@ -213,17 +228,8 @@ StatusCode ApplicationMgr::i_startup()
return sc;
}
// Get the useful interface from Message and JobOptions services
m_messageSvc = m_svcLocator->service( "MessageSvc" );
if ( !m_messageSvc ) {
fatal() << "Error retrieving MessageSvc." << endmsg;
return StatusCode::FAILURE;
}
m_jobOptionsSvc = m_svcLocator->service( "JobOptionsSvc" );
if ( !m_jobOptionsSvc ) {
fatal() << "Error retrieving JobOptionsSvc." << endmsg;
return StatusCode::FAILURE;
}
// Make sure output level caches are up to date.
outputLevelUpdate();
return sc;
}
......@@ -429,9 +435,12 @@ StatusCode ApplicationMgr::configure()
//============================================================================
StatusCode ApplicationMgr::initialize()
{
StatusCode sc;
MsgStream log( m_messageSvc, name() );
StatusCode sc;
// Make sure output level caches are up to date.
outputLevelUpdate();
// I cannot add these services in configure() because they are coming from GaudiUtils
// and it messes up genconf when rebuilding it.
......@@ -1221,3 +1230,11 @@ void ApplicationMgr::initLoopCheckHndlr( Gaudi::Details::PropertyBase& )
{
svcManager()->setLoopCheckEnabled( m_loopCheck );
}
void ApplicationMgr::outputLevelUpdate()
{
resetMessaging();
for ( auto& mgrItem : m_managers ) {
mgrItem.second->outputLevelUpdate();
}
}
......@@ -150,6 +150,9 @@ public:
/// Needed to locate the message service
SmartIF<ISvcLocator>& serviceLocator() const override { return m_svcLocator; }
/// Function to call to update the outputLevel of the components (after a change in MessageSvc).
void outputLevelUpdate() override;
protected:
/// declare one or more copies of svc type/name as determined by NoOfThreads
StatusCode declareMultiSvcType( const std::string& name, const std::string& type );
......
......@@ -535,4 +535,13 @@ void ServiceManager::dump() const
log << endmsg;
}
void ServiceManager::outputLevelUpdate()
{
resetMessaging();
for ( auto& svcItem : m_listsvc ) {
const auto svc = dynamic_cast<Service*>( svcItem.service.get() );
if ( svc ) svc->resetMessaging();
}
}
DECLARE_OBJECT_FACTORY( ServiceManager )
......@@ -129,6 +129,9 @@ public:
using ISvcManager::addService;
#endif
/// Function to call to update the outputLevel of the components (after a change in MessageSvc).
void outputLevelUpdate() override;
private:
inline ListSvc::iterator find( const std::string& name )
{
......
......@@ -5,6 +5,7 @@
#endif
#include "MessageSvc.h"
#include "GaudiKernel/IAppMgrUI.h"
#include "GaudiKernel/Kernel.h"
#include "GaudiKernel/Message.h"
#include "GaudiKernel/StatusCode.h"
......@@ -83,6 +84,11 @@ MessageSvc::MessageSvc( const std::string& name, ISvcLocator* svcloc ) : base_cl
{
m_inactCount.declareUpdateHandler( &MessageSvc::setupInactCount, this );
m_outputLevel.declareUpdateHandler( [svcloc]( Gaudi::Details::PropertyBase& ) {
SmartIF<IAppMgrUI> app = svcloc;
if ( app ) app->outputLevelUpdate();
} );
#ifndef NDEBUG
// initialize the MsgStream static flag.
MsgStream::enableCountInactive( m_inactCount );
......
......@@ -15,11 +15,12 @@ JobOptionsSvc INFO # (23,1): MessageSvc.verboseColorCode = ["[95;4m"]
JobOptionsSvc INFO # (31,1): ApplicationMgr.EvtMax = 2
JobOptionsSvc INFO # (32,1): ApplicationMgr.EvtSel = "NONE"
JobOptionsSvc INFO Job options successfully read in from /home/marco/Devel/LHCb/workspace/Gaudi/GaudiExamples/options/ColorMsg.opts
MessageSvc DEBUG Service base class initialized successfully
ApplicationMgr DEBUG Getting my own properties
ApplicationMgr SUCCESS
====================================================================================================================================
Welcome to ApplicationMgr (GaudiCoreSvc v28r1)
running on pcphlbc16 on Tue Mar 7 10:58:03 2017
Welcome to ApplicationMgr (GaudiCoreSvc v29r0)
running on pcphlbc16 on Sat Oct 7 10:17:01 2017
====================================================================================================================================
ApplicationMgr INFO Application Manager Configured successfully
ServiceManager DEBUG Initializing service StatusCodeSvc
......@@ -50,7 +51,6 @@ ApplicationMgr SUCCESS
EventLoopMgr WARNING No events will be processed from external input.
HistogramDataSvc DEBUG Service base class initialized successfully
HistogramDataSvc VERBOSE ServiceLocatorHelper::service: found service IncidentSvc
HistogramPersis... DEBUG 'CnvServices':[ 'RootHistSvc' ]
HistogramPersis... DEBUG Service base class initialized successfully
HistogramPersis...WARNING Histograms saving not required.
HistogramDataSvc VERBOSE ServiceLocatorHelper::service: found service HistogramPersistencySvc
......@@ -128,7 +128,7 @@ Algs: 1
StatusCodeSvc DEBUG all StatusCode instances where checked
ServiceManager DEBUG Looping over all active services...
ServiceManager DEBUG ---- StatusCodeSvc (refCount = 2)
ServiceManager DEBUG ---- MessageSvc (refCount = 14)
ServiceManager DEBUG ---- MessageSvc (refCount = 18)
ServiceManager DEBUG ---- JobOptionsSvc (refCount = 3)
ServiceManager DEBUG ---- AppMgrRunable (refCount = 3)
ServiceManager DEBUG ---- IncidentSvc (refCount = 2)
......
......@@ -52,7 +52,6 @@ ApplicationMgr INFO Application Manager Configured successfully
EventLoopMgr WARNING No events will be processed from external input.
HistogramDataSvc DEBUG Service base class initialized successfully
HistogramDataSvc VERBOSE ServiceLocatorHelper::service: found service IncidentSvc
HistogramPersis... DEBUG 'CnvServices':[ 'RootHistSvc' ]
HistogramPersis... DEBUG Service base class initialized successfully
HistogramPersis...WARNING Histograms saving not required.
HistogramDataSvc VERBOSE ServiceLocatorHelper::service: found service HistogramPersistencySvc
......@@ -130,7 +129,7 @@ Algs: 1
StatusCodeSvc DEBUG all StatusCode instances where checked
ServiceManager DEBUG Looping over all active services...
ServiceManager DEBUG ---- StatusCodeSvc (refCount = 2)
ServiceManager DEBUG ---- MessageSvc (refCount = 14)
ServiceManager DEBUG ---- MessageSvc (refCount = 18)
ServiceManager DEBUG ---- JobOptionsSvc (refCount = 3)
ServiceManager DEBUG ---- AppMgrRunable (refCount = 3)
ServiceManager DEBUG ---- IncidentSvc (refCount = 2)
......
......@@ -18,11 +18,12 @@ JobOptionsSvc INFO # (28,1): FastHistorySvc.OutputFile = "history.dat"
JobOptionsSvc INFO # (35,1): ApplicationMgr.EvtMax = 2
JobOptionsSvc INFO # (36,1): ApplicationMgr.EvtSel = "NONE"
JobOptionsSvc INFO Job options successfully read in from /build1/leggett/git/leggett/Gaudi/GaudiExamples/options/History.opts
MessageSvc DEBUG Service base class initialized successfully
ApplicationMgr DEBUG Getting my own properties
ApplicationMgr SUCCESS
====================================================================================================================================
Welcome to ApplicationMgr (GaudiCoreSvc v28r1)
running on p05614910w96644.cern.ch on Fri Jan 27 19:47:03 2017
Welcome to ApplicationMgr (GaudiCoreSvc v29r0)
running on pcphlbc16 on Sat Oct 7 10:18:11 2017
====================================================================================================================================
ApplicationMgr INFO Application Manager Configured successfully
ServiceManager DEBUG Initializing service StatusCodeSvc
......@@ -55,7 +56,6 @@ History DEBUG Data Deps for History
EventLoopMgr WARNING No events will be processed from external input.
HistogramDataSvc DEBUG Service base class initialized successfully
HistogramDataSvc VERBOSE ServiceLocatorHelper::service: found service IncidentSvc
HistogramPersis... DEBUG 'CnvServices':[ 'RootHistSvc' ]
HistogramPersis... DEBUG Service base class initialized successfully
HistogramPersis...WARNING Histograms saving not required.
HistogramDataSvc VERBOSE ServiceLocatorHelper::service: found service HistogramPersistencySvc
......@@ -156,8 +156,8 @@ ToolSvc INFO Removing all tools created by ToolSvc
ToolSvc DEBUG Tool List : 
ToolSvc DEBUG Deleting 0 finalized tools
ServiceManager DEBUG Finalizing service AlgContextSvc
IncidentSvc DEBUG Removing [BeginEvent] listener 'AlgContextSvc'
IncidentSvc DEBUG Removing [EndEvent] listener 'AlgContextSvc'
IncidentSvc DEBUG Removing [BeginEvent] listener 'AlgContextSvc'
ServiceManager DEBUG Finalizing service AlgExecStateSvc
ServiceManager DEBUG Finalizing service TimelineSvc
ServiceManager DEBUG Finalizing service EventDataSvc
......@@ -174,7 +174,7 @@ ServiceManager DEBUG Finalizing service StatusCodeSvc
StatusCodeSvc DEBUG all StatusCode instances where checked
ServiceManager DEBUG Looping over all active services...
ServiceManager DEBUG ---- StatusCodeSvc (refCount = 3)
ServiceManager DEBUG ---- MessageSvc (refCount = 18)
ServiceManager DEBUG ---- MessageSvc (refCount = 22)
ServiceManager DEBUG ---- JobOptionsSvc (refCount = 5)
ServiceManager DEBUG ---- HistorySvc (refCount = 3)
ServiceManager DEBUG ---- HistogramPersistencySvc (refCount = 3)
......
......@@ -69,7 +69,7 @@ JobOptionsSvc.AuditServices:False
JobOptionsSvc.AuditStart:False
JobOptionsSvc.AuditStop:False
JobOptionsSvc.DUMPFILE:
JobOptionsSvc.OutputLevel:0
JobOptionsSvc.OutputLevel:3
JobOptionsSvc.PATH:../options/job.opts
JobOptionsSvc.PYTHONACTION:
JobOptionsSvc.PYTHONPARAMS:
......
......@@ -130,7 +130,6 @@ EventLoopMgr WARNING Unable to locate service "EventSelector"
EventLoopMgr WARNING No events will be processed from external input.
HistogramDataSvc DEBUG Service base class initialized successfully
HistogramDataSvc VERBOSE ServiceLocatorHelper::service: found service IncidentSvc
HistogramPersis... DEBUG 'CnvServices':[ 'RootHistSvc' ]
HistogramPersis... DEBUG Service base class initialized successfully
HistogramPersis...WARNING Histograms saving not required.
HistogramDataSvc VERBOSE ServiceLocatorHelper::service: found service HistogramPersistencySvc
......@@ -1359,7 +1358,7 @@ ServiceManager DEBUG Finalizing service FileRecordDataSvc
IncidentSvc DEBUG Removing [SAVE_FILE_RECORD] listener 'FileRecordDataSvc'
IncidentSvc DEBUG Removing [FILE_OPEN_READ] listener 'FileRecordDataSvc'
ServiceManager DEBUG Looping over all active services...
ServiceManager DEBUG ---- MessageSvc (refCount = 23)
ServiceManager DEBUG ---- MessageSvc (refCount = 27)
ServiceManager DEBUG ---- JobOptionsSvc (refCount = 3)
ServiceManager DEBUG ---- RndmGenSvc.Engine (refCount = 2)
ServiceManager DEBUG ---- FileRecordDataSvc (refCount = 3)
......
......@@ -41,7 +41,6 @@ RndmGenSvc.Engine INFO Current Seed:1234567 Luxury:3
RndmGenSvc INFO Using Random engine:HepRndm::Engine<CLHEP::RanluxEngine>
HistogramDataSvc DEBUG Property update for OutputLevel : new value = 2
HistogramDataSvc DEBUG Service base class initialized successfully
HistogramPersis... DEBUG 'CnvServices':[ 'RootHistSvc' ]
HistogramPersis... DEBUG Service base class initialized successfully
RootHistSvc DEBUG Property update for OutputLevel : new value = 2
RootHistSvc DEBUG Service base class initialized successfully
......@@ -149,7 +148,7 @@ ServiceManager DEBUG Finalizing service IncidentSvc
IncidentSvc DEBUG Incident timing: Mean(+-rms)/Min/Max:0.0005(+-0.0223551)/0/1[ms] Total:0.002[s]
ServiceManager DEBUG Finalizing service AppMgrRunable
ServiceManager DEBUG Looping over all active services...
ServiceManager DEBUG ---- MessageSvc (refCount = 17)
ServiceManager DEBUG ---- MessageSvc (refCount = 21)
ServiceManager DEBUG ---- JobOptionsSvc (refCount = 3)
ServiceManager DEBUG ---- RndmGenSvc.Engine (refCount = 2)
ServiceManager DEBUG ---- AppMgrRunable (refCount = 3)
......
......@@ -242,7 +242,6 @@ EventLoopMgr WARNING Unable to locate service "EventSelector"
EventLoopMgr WARNING No events will be processed from external input.
HistogramDataSvc DEBUG Service base class initialized successfully
HistogramDataSvc VERBOSE ServiceLocatorHelper::service: found service IncidentSvc
HistogramPersis... DEBUG 'CnvServices':[ 'RootHistSvc' ]
HistogramPersis... DEBUG Service base class initialized successfully
HistogramPersis...WARNING Histograms saving not required.
HistogramDataSvc VERBOSE ServiceLocatorHelper::service: found service HistogramPersistencySvc
......@@ -401,7 +400,7 @@ ServiceManager DEBUG Finalizing service FileRecordDataSvc
IncidentSvc DEBUG Removing [SAVE_FILE_RECORD] listener 'FileRecordDataSvc'
IncidentSvc DEBUG Removing [FILE_OPEN_READ] listener 'FileRecordDataSvc'
ServiceManager DEBUG Looping over all active services...
ServiceManager DEBUG ---- MessageSvc (refCount = 20)
ServiceManager DEBUG ---- MessageSvc (refCount = 24)
ServiceManager DEBUG ---- JobOptionsSvc (refCount = 3)
ServiceManager DEBUG ---- FileRecordDataSvc (refCount = 3)
ServiceManager DEBUG ---- AppMgrRunable (refCount = 3)
......
......@@ -583,6 +583,8 @@ public:
svc->setProperty( m_rootName ).ignore();
svc->setProperty( m_forceLeaves ).ignore();
svc->setProperty( m_enableFaultHdlr ).ignore();
// make sure that CommonMessaging is initialized
svc->setProperty( m_outputLevel ).ignore();
sc = svc->initialize();
if ( !sc.isSuccess() ) {
......
......@@ -141,7 +141,6 @@ namespace concurrency
//---------------------------------------------------------------------------
StatusCode PrecedenceRulesGraph::initialize()
{
if ( serviceLocator()->existsService( "CondSvc" ) ) {
SmartIF<ICondSvc> condSvc{serviceLocator()->service( "CondSvc" )};
if ( condSvc.isValid() ) {
......
......@@ -582,6 +582,8 @@ namespace concurrency
, m_name( name )
, m_initTime( std::chrono::system_clock::now() )
{
// make sure that CommonMessaging is initialized
setUpMessaging();
}
/// Destructor
~PrecedenceRulesGraph() override
......
......@@ -45,6 +45,7 @@
class IAlgTool;
class ToolHandleInfo;
class AlgorithmManager;
#ifndef PACKAGE_VERSION
#define PACKAGE_VERSION "unknown"
......@@ -83,6 +84,7 @@ public:
#ifndef __REFLEX__
typedef Gaudi::PluginService::Factory<IAlgorithm*, const std::string&, ISvcLocator*> Factory;
#endif
friend AlgorithmManager;
/** Constructor
* @param name The algorithm object's name
......
......@@ -67,17 +67,12 @@ public:
/// Virtual destructor
virtual ~CommonMessagingBase() = default;
/// cold functionality
virtual void create_msgSvc() const = 0;
virtual void create_msgStream() const = 0;
/** The standard message service.
* Returns a pointer to the standard message service.
*/
inline SmartIF<IMessageSvc>& msgSvc() const
{
if ( UNLIKELY( !m_msgsvc ) ) create_msgSvc();
return m_msgsvc;
}
inline const SmartIF<IMessageSvc>& msgSvc() const { return m_msgsvc; }
/// Return an uninitialized MsgStream.
inline MsgStream& msgStream() const
......@@ -125,14 +120,11 @@ public:
/// shortcut for the method msgStream(MSG::INFO)
inline MsgStream& msg() const { return msgStream( MSG::INFO ); }
/// get the output level from the embedded MsgStream
/// get the cached level (originally extracted from the embedded MsgStream)
inline MSG::Level msgLevel() const
{
if ( UNLIKELY( ( !m_msgStream.get() ) ) ) create_msgStream();
if ( UNLIKELY( ( !m_level.get() ) ) ) {
return MSG::NIL;
}
return *m_level;
assert( m_commonMessagingReady );
return m_level;
}
/// Backward compatibility function for getting the output level
......@@ -145,14 +137,15 @@ private:
template <typename Base>
friend class CommonMessaging;
bool m_commonMessagingReady = false;
/// The predefined message stream
mutable boost::thread_specific_ptr<MsgStream> m_msgStream;
// mutable MSG::Level m_level = MSG::NIL;
mutable boost::thread_specific_ptr<MSG::Level> m_level;
MSG::Level m_level = MSG::NIL;
/// Pointer to the message service;
mutable SmartIF<IMessageSvc> m_msgsvc;
SmartIF<IMessageSvc> m_msgsvc;
};
template <typename BASE>
......@@ -166,34 +159,43 @@ public:
private:
// out-of-line 'cold' functions -- put here so as to not blow up the inline 'hot' functions
void create_msgSvc() const override final
void create_msgStream() const override final { m_msgStream.reset( new MsgStream( msgSvc(), this->name() ) ); }
protected:
/// Set up local caches
MSG::Level setUpMessaging()
{
// Get default implementation of the message service.
m_msgsvc = this->serviceLocator();
if ( !m_commonMessagingReady ) {
if ( !m_msgsvc ) {
// Get default implementation of the message service.
m_msgsvc = this->serviceLocator();
}
create_msgStream();
m_level = MSG::Level( m_msgStream.get() ? m_msgStream->level() : MSG::NIL );
// if we could not get a MessageSvc, we should try again the initial set up
m_commonMessagingReady = m_msgsvc;
}
return m_level;
}
void create_msgStream() const override final
/// Reinitialize internal states.
MSG::Level resetMessaging()
{
auto& ms = msgSvc();
m_msgStream.reset( new MsgStream( ms, this->name() ) );
m_level.reset( new MSG::Level( m_msgStream.get() ? m_msgStream->level() : MSG::NIL ) );
m_commonMessagingReady = false;
return setUpMessaging();
}
protected:
/// Update the output level of the cached MsgStream.
/// This function is meant to be called by the update handler of the OutputLevel property.
void updateMsgStreamOutputLevel( int level )
{
if ( !m_msgStream.get() ) {
create_msgStream();
}
if ( level != MSG::NIL && level != *m_level ) {
setUpMessaging();
if ( level != MSG::NIL && level != m_level ) {
if ( msgSvc() ) {
msgSvc()->setOutputLevel( this->name(), level );
}
if ( m_msgStream.get() ) m_msgStream->setLevel( level );
if ( UNLIKELY( MSG::Level( level ) <= MSG::DEBUG ) )
debug() << "Property update for OutputLevel : new value = " << level << endmsg;
*m_level = MSG::Level( level );
m_level = MSG::Level( level );
}
}
};
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment