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

Drop obsolete GaudiMT

parent 900d06d4
// Include files
#include "ApplicationMgr.h"
#include "AlgorithmManager.h"
#include "DLLClassManager.h"
#include "ServiceManager.h"
......@@ -15,7 +16,6 @@
#include "GaudiKernel/SmartIF.h"
#include "GaudiKernel/GaudiException.h"
#include "GaudiKernel/ThreadGaudi.h"
#include "GaudiKernel/StatusCode.h"
#include "GaudiKernel/System.h"
......@@ -262,20 +262,23 @@ StatusCode ApplicationMgr::configure()
return sc;
}
MsgStream log( m_messageSvc, name() );
// Get my own options using the Job options service
if ( log.level() <= MSG::DEBUG ) log << MSG::DEBUG << "Getting my own properties" << endmsg;
sc = m_jobOptionsSvc->setMyProperties( name(), this );
if ( !sc.isSuccess() ) {
log << MSG::WARNING << "Problems getting my properties from JobOptionsSvc" << endmsg;
return sc;
{
MsgStream log( m_messageSvc, name() );
// Get my own options using the Job options service
if ( log.level() <= MSG::DEBUG ) log << MSG::DEBUG << "Getting my own properties" << endmsg;
sc = m_jobOptionsSvc->setMyProperties( name(), this );
if ( !sc.isSuccess() ) {
log << MSG::WARNING << "Problems getting my properties from JobOptionsSvc" << endmsg;
return sc;
}
}
// Make sure that the OutputLevel is in sync
if ( m_outputLevel != MSG::NIL && m_messageSvc ) m_messageSvc->setOutputLevel( name(), m_outputLevel );
MsgStream log( m_messageSvc, name() );
// Check current outputLevel to eventually inform the MessageSvc
if ( m_outputLevel != MSG::NIL && !m_appName.empty() ) {
assert( m_messageSvc );
m_messageSvc->setOutputLevel( name(), m_outputLevel );
// Print a welcome message
log << MSG::ALWAYS << std::endl
<< "=================================================================="
......@@ -315,10 +318,13 @@ StatusCode ApplicationMgr::configure()
// Check if StatusCode need to be checked
if ( m_codeCheck ) {
StatusCode::enableChecking();
sc = addMultiSvc( "StatusCodeSvc", -9999 );
sc = svcManager()->addService( "StatusCodeSvc", -9999 );
if ( sc.isFailure() ) {
log << MSG::FATAL << "Error adding StatusCodeSvc for multiple threads" << endmsg;
log << MSG::FATAL << "Error adding StatusCodeSvc" << endmsg;
return StatusCode::FAILURE;
} else {
ON_VERBOSE
log << MSG::VERBOSE << "added service StatusCodeSvc" << endmsg;
}
} else {
StatusCode::disableChecking();
......@@ -337,15 +343,18 @@ StatusCode ApplicationMgr::configure()
// Declare Service Types
for ( auto& j : m_svcMapping ) {
Gaudi::Utils::TypeNameString itm( j );
if ( declareMultiSvcType( itm.name(), itm.type() ).isFailure() ) {
if ( svcManager()->declareSvcType( itm.name(), itm.type() ).isFailure() ) {
log << MSG::ERROR << "configure: declaring svc type:'" << j << "' failed." << endmsg;
return StatusCode::FAILURE;
} else {
ON_VERBOSE
log << MSG::VERBOSE << "declared service " << j << endmsg;
}
}
for ( auto& j : m_svcOptMapping ) {
Gaudi::Utils::TypeNameString itm( j );
if ( declareMultiSvcType( itm.name(), itm.type() ).isFailure() ) {
log << MSG::ERROR << "configure: declaring svc type:'" << j << "' failed." << endmsg;
if ( svcManager()->declareSvcType( itm.name(), itm.type() ).isFailure() ) {
log << MSG::ERROR << "declaring svc type:'" << j << "' failed." << endmsg;
return StatusCode::FAILURE;
}
}
......@@ -366,12 +375,6 @@ StatusCode ApplicationMgr::configure()
return sc;
}
sc = decodeMultiThreadSvcNameList();
if ( sc.isFailure() ) {
log << MSG::ERROR << "Failure during multi thread service creation" << endmsg;
return sc;
}
sc = decodeCreateSvcNameList();
if ( sc.isFailure() ) {
log << MSG::ERROR << "Failure during external service creation" << endmsg;
......@@ -382,31 +385,31 @@ StatusCode ApplicationMgr::configure()
// Retrieve intrinsic services. If needed configure them.
//--------------------------------------------------------------------------
const Gaudi::Utils::TypeNameString evtloop_item( m_eventLoopMgr );
sc = addMultiSvc( evtloop_item, ServiceManager::DEFAULT_SVC_PRIORITY * 10 );
sc = svcManager()->addService( evtloop_item, ServiceManager::DEFAULT_SVC_PRIORITY * 10 );
if ( !sc.isSuccess() ) {
log << MSG::FATAL << "Error adding :" << m_eventLoopMgr << endmsg;
return sc;
} else {
ON_VERBOSE
log << MSG::VERBOSE << "added service " << evtloop_item << endmsg;
}
if ( m_noOfEvtThreads == 0 ) {
m_runable = m_svcLocator->service( m_runableType );
if ( !m_runable ) {
log << MSG::FATAL << "Error retrieving Runable: " << m_runableType.value() << "\n Check option ApplicationMgr."
<< m_runableType.name() << endmsg;
return sc;
}
m_processingMgr = m_svcLocator->service( evtloop_item );
if ( !m_processingMgr ) {
log << MSG::FATAL << "Error retrieving Processing manager: " << m_eventLoopMgr.value()
<< "\n Check option ApplicationMgr." << m_eventLoopMgr.name() << "\n No events will be processed." << endmsg;
return sc;
}
m_runable = m_svcLocator->service( m_runableType );
if ( !m_runable ) {
log << MSG::FATAL << "Error retrieving Runable: " << m_runableType.value() << "\n Check option ApplicationMgr."
<< m_runableType.name() << endmsg;
return sc;
}
m_processingMgr = m_svcLocator->service( evtloop_item );
if ( !m_processingMgr ) {
log << MSG::FATAL << "Error retrieving Processing manager: " << m_eventLoopMgr.value()
<< "\n Check option ApplicationMgr." << m_eventLoopMgr.name() << "\n No events will be processed." << endmsg;
return sc;
}
// Establish Update Handlers for ExtSvc and DLLs Properties
m_extSvcNameList.declareUpdateHandler( &ApplicationMgr::extSvcNameListHandler, this );
m_createSvcNameList.declareUpdateHandler( &ApplicationMgr::createSvcNameListHandler, this );
m_multiThreadSvcNameList.declareUpdateHandler( &ApplicationMgr::multiThreadSvcNameListHandler, this );
m_dllNameList.declareUpdateHandler( &ApplicationMgr::dllNameListHandler, this );
if ( m_actHistory ) {
......@@ -416,14 +419,6 @@ StatusCode ApplicationMgr::configure()
log << MSG::FATAL << "Error adding HistorySvc" << endmsg;
return StatusCode::FAILURE;
}
if ( m_noOfEvtThreads > 0 ) {
sc = addMultiSvc( "HistorySvc", std::numeric_limits<int>::max() );
if ( sc.isFailure() ) {
log << MSG::FATAL << "Error adding HistorySvc for multiple threads" << endmsg;
return StatusCode::FAILURE;
}
}
}
log << MSG::INFO << "Application Manager Configured successfully" << endmsg;
......@@ -1023,107 +1018,6 @@ StatusCode ApplicationMgr::decodeExtSvcNameList()
return result;
}
//============================================================================
// External Service List handler
//============================================================================
void ApplicationMgr::multiThreadSvcNameListHandler( Gaudi::Details::PropertyBase& /* theProp */ )
{
if ( !( decodeMultiThreadSvcNameList() ).isSuccess() ) {
throw GaudiException( "Failed to create copies of mt services",
"MinimalEventLoopMgr::multiThreadSvcNameListHandler", StatusCode::FAILURE );
}
}
//============================================================================
// decodeMultiExtSvcNameList
//============================================================================
StatusCode ApplicationMgr::decodeMultiThreadSvcNameList()
{
StatusCode result = StatusCode::SUCCESS;
const auto& theNames = m_multiThreadSvcNameList.value();
for ( int iCopy = 0; iCopy < m_noOfEvtThreads; ++iCopy ) {
for ( const auto& it : theNames ) {
Gaudi::Utils::TypeNameString item( it );
result = addMultiSvc( item, ServiceManager::DEFAULT_SVC_PRIORITY );
// FIXME SHOULD CLONE?
if ( result.isFailure() ) {
MsgStream log( m_messageSvc, m_name );
log << MSG::ERROR << "decodeMultiThreadSvcNameList: Cannot create service " << item.type() << "/" << item.name()
<< endmsg;
} else {
ON_VERBOSE
{
MsgStream log( m_messageSvc, m_name );
log << MSG::VERBOSE << "decodeMultiThreadSvcNameList: created service " << item.type() << "/" << item.name()
<< endmsg;
}
}
}
}
return result;
}
//=============================================================================
// declareMultiSvcType
//=============================================================================
StatusCode ApplicationMgr::declareMultiSvcType( const std::string& name, const std::string& type )
{
StatusCode result = StatusCode::SUCCESS;
MsgStream log( m_messageSvc, m_name );
if ( 0 == m_noOfEvtThreads ) {
result = svcManager()->declareSvcType( name, type );
if ( result.isFailure() ) {
log << MSG::ERROR << "declareMultiSvcType: Cannot declare service " << type << "/" << name << endmsg;
} else {
ON_VERBOSE
log << MSG::VERBOSE << "declareMultiSvcType: declared service " << type << "/" << name << endmsg;
}
} else {
for ( int iCopy = 0; iCopy < m_noOfEvtThreads; ++iCopy ) {
std::string thrName( name + getGaudiThreadIDfromID( iCopy ) );
result = svcManager()->declareSvcType( thrName, type );
if ( result.isFailure() ) {
log << MSG::ERROR << "declareMultiSvcType: Cannot declare service " << type << "/" << thrName << endmsg;
} else {
ON_VERBOSE
log << MSG::VERBOSE << "declareMultiSvcType: declared service " << type << "/" << thrName << endmsg;
}
}
}
return result;
}
//=============================================================================
// addMultiSvc
//=============================================================================
StatusCode ApplicationMgr::addMultiSvc( const Gaudi::Utils::TypeNameString& typeName, int prio )
{
using Gaudi::Utils::TypeNameString;
StatusCode result = StatusCode::SUCCESS;
MsgStream log( m_messageSvc, m_name );
if ( 0 == m_noOfEvtThreads ) {
result = svcManager()->addService( typeName, prio );
// result = svcManager()->addService(name, type, prio); // CHECKME???
if ( result.isFailure() ) {
log << MSG::ERROR << "addMultiSvc: Cannot add service " << typeName.type() << "/" << typeName.name() << endmsg;
} else {
ON_VERBOSE
log << MSG::VERBOSE << "addMultiSvc: added service " << typeName.type() << "/" << typeName.name() << endmsg;
}
} else {
for ( int iCopy = 0; iCopy < m_noOfEvtThreads; ++iCopy ) {
const std::string& type = typeName.type();
std::string thrName( typeName.name() + getGaudiThreadIDfromID( iCopy ) );
result = svcManager()->addService( TypeNameString( thrName, type ), prio );
if ( result.isFailure() ) {
log << MSG::ERROR << "addMultiSvc: Cannot add service " << type << "/" << thrName << endmsg;
} else {
ON_VERBOSE
log << MSG::VERBOSE << "addMultiSvc: added service " << type << "/" << thrName << endmsg;
}
}
}
return result;
}
//============================================================================
// Dll List handler
//============================================================================
......
......@@ -113,8 +113,6 @@ public:
StatusCode decodeCreateSvcNameList();
void createSvcNameListHandler( Gaudi::Details::PropertyBase& );
void extSvcNameListHandler( Gaudi::Details::PropertyBase& theProp );
StatusCode decodeMultiThreadSvcNameList();
void multiThreadSvcNameListHandler( Gaudi::Details::PropertyBase& theProp );
StatusCode decodeDllNameList();
void dllNameListHandler( Gaudi::Details::PropertyBase& theProp );
void pluginDebugPropertyHandler( Gaudi::Details::PropertyBase& theProp );
......@@ -152,11 +150,6 @@ public:
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 );
/// add one or more copies of svc type/name as determined by NoOfThreads
StatusCode addMultiSvc( const Gaudi::Utils::TypeNameString& typeName, int prio );
// implementation of IService::setServiceManager
void setServiceManager( ISvcManager* ) override {}
......@@ -221,10 +214,6 @@ protected:
Gaudi::Property<bool> m_extSvcCreates{this, "ExtSvcCreates", true,
"LHCb (default) or ATLAS definition of \"ExtSvc\""};
/// List of external services names for which we want a copy per evt thread
Gaudi::Property<std::vector<std::string>> m_multiThreadSvcNameList{this, "MultiThreadExtSvc"};
Gaudi::Property<int> m_noOfEvtThreads{this, "NoOfThreads", 0, "MultiThreadSvc copies"};
Gaudi::Property<std::vector<std::string>> m_dllNameList{this, "Dlls", {}, "List of DDL's names"};
Gaudi::Property<std::string> m_jobOptionsType{this, "JobOptionsType", "FILE", "Source type (e.g. dbase, file...)"};
Gaudi::Property<std::string> m_jobOptionsPath{this, "JobOptionsPath", {}, "The \"file\" to look for properties"};
......
//##############################################################
// Job options file
//==============================================================
//AuditorSvc.Auditors = { "ChronoAuditor" };
ApplicationMgr.EventLoop = "MTEventLoopMgr";
ApplicationMgr.ExtSvc += { "NTupleSvc" };
ApplicationMgr.MultiThreadExtSvc += { "RndmGenSvc", "ParticlePropertySvc" };
ApplicationMgr.OutputLevel = 1;
//--------------------------------------------------------------
//--------------------------------------------------------------
// Private Application Configuration options
//--------------------------------------------------------------
ApplicationMgr.TopAlg = { "MTHelloWorld" };
// Set output level threshold (2=DEBUG, 3=INFO, 4=WARNING, 5=ERROR, 6=FATAL )
MessageSvc.OutputLevel = 1;
//--------------------------------------------------------------
// Event related parameters
//--------------------------------------------------------------
ApplicationMgr.EvtMax = 2;
ApplicationMgr.EvtSel = "NONE";
//--------------------------------------------------------------
// Algorithms Private Options
//--------------------------------------------------------------
// For the genuine HelloWorld algorithm
MTHelloWorld.MyInt = 42;
MTHelloWorld.MyBool = true;
MTHelloWorld.MyDouble = 3.14159;
MTHelloWorld.MyStringVec = { "Welcome", "to", "MT", "Gaudi" };
// For a special HelloWorld algorithm
MTHelloWorld__1.MyInt = 21;
MTHelloWorld__1.MyBool = false;
MTHelloWorld__1.MyDouble = 6.28;
MTHelloWorld__1.MyStringVec = { "Welcome", "to", "Thread", "1" };
// Include Files
#include "GaudiKernel/LoadFactoryEntries.h"
LOAD_FACTORY_ENTRIES( GaudiMTExample )
// Dear emacs, this is -*- c++ -*-
const int MAX_THREADS( 1023 ); // to check command line parameter
// Include files
#include "GaudiKernel/Bootstrap.h"
#include "GaudiKernel/IAppMgrUI.h"
#include "GaudiKernel/IClassManager.h"
#include "GaudiKernel/IProperty.h"
#include "GaudiKernel/SmartIF.h"
#include "GaudiKernel/IEventProcessor.h"
#include "GaudiKernel/IInterface.h"
#include "GaudiKernel/ISvcLocator.h"
#include "GaudiKernel/ThreadGaudi.h"
#include "boost/algorithm/string/predicate.hpp"
#include <cassert>
#include <iostream>
#include <pthread.h>
/**
* Defines a global locking mechanism so we can see when all worker threads
* are finished.
*/
int worker_done;
pthread_mutex_t mutex;
pthread_cond_t condition;
pthread_mutex_t coutmutex;
#include <sstream>
#define COUTTHREAD( _message_ ) \
{ \
pthread_mutex_lock( &coutmutex ); \
std::ostringstream _oss_; \
_oss_ << _message_; \
std::cout << _oss_.str() << std::endl; \
pthread_mutex_unlock( &coutmutex ); \
}
/**
* Defines the work that has to be done in each thread
*
* @param counter The number of times the same work has to be done.
*/
void* work( void* counter )
{
int id_thread = *( static_cast<int*>( counter ) );
assert( id_thread >= 0 );
std::string threadStrID( getGaudiThreadIDfromID( id_thread ) );
COUTTHREAD( "++++ Thread : " << id_thread << " string = " << threadStrID );
int m_evtMax = 0;
// Get an instance of the Pesa application manager
IInterface* m_pesaAppMgr = Gaudi::createApplicationMgr();
// Get the EventLoopMgr name from the Application Manager
std::string nameEventLoopMgr = "EventLoopMgr";
std::string value;
SmartIF<IProperty> propMgr( m_pesaAppMgr );
if ( !propMgr ) {
COUTTHREAD( " Fatal error while retrieving Gaudi PropertyHolder " )
} else {
StatusCode sc = propMgr->getProperty( "EventLoop", value );
if ( sc.isFailure() ) {
COUTTHREAD( " Fatal error while retrieving Property EventLoop " )
} else {
nameEventLoopMgr.assign( value, value.find_first_of( "\"" ) + 1,
value.find_last_of( "\"" ) - value.find_first_of( "\"" ) - 1 );
}
sc = propMgr->getProperty( "EvtMax", value );
if ( sc.isFailure() ) {
COUTTHREAD( " Fatal error while retrieving Property EvtMax " )
} else {
m_evtMax = std::stoi( value );
}
}
nameEventLoopMgr = nameEventLoopMgr + threadStrID;
COUTTHREAD( "---> Thread : " << id_thread << " - Name for EventLoopManager : " + nameEventLoopMgr )
StatusCode sc;
IEventProcessor* m_processingMgr = 0;
SmartIF<ISvcLocator> svcLoc( m_pesaAppMgr );
if ( svcLoc ) {
sc = svcLoc->service( nameEventLoopMgr, m_processingMgr );
if ( !sc.isSuccess() ) {
COUTTHREAD( "FATAL Error retrieving Processing manager:" )
m_processingMgr = 0;
}
}
for ( int i = 0; i < m_evtMax; i++ ) {
// ExecuteEvent from the application manager
if ( 0 != m_processingMgr ) {
SmartIF<IEventProcessor> processor( m_processingMgr );
if ( processor ) {
COUTTHREAD( " ---> Executing WorkerThread---> " << id_thread )
sc = processor->executeEvent( NULL );
if ( sc.isFailure() ) {
COUTTHREAD( "Fatal error for executeEvent in the ApplicationMgr " << id_thread )
}
} else {
COUTTHREAD( "---> executeEvent ApplicationMgr : no valid event processor " << id_thread );
}
}
}
pthread_mutex_lock( &mutex );
--worker_done;
if ( worker_done == 0 ) pthread_cond_signal( &condition );
pthread_mutex_unlock( &mutex );
return 0;
}
//--- Example main program
int main( int argc, char** argv )
{
// initialises the mutex and the condition
pthread_mutex_init( &mutex, 0 ); // fast mutex (or recursive?)
pthread_mutex_init( &coutmutex, 0 ); // fast mutex (or recursive?)
pthread_cond_init( &condition, 0 );
// Create an instance of an application manager
auto appMgr = SmartIF<IAppMgrUI>( Gaudi::createApplicationMgr() );
auto propMgr = appMgr.as<IProperty>();
auto dllMgr = appMgr.as<IClassManager>();
if ( !appMgr || !propMgr || !dllMgr ) {
std::cout << "Fatal error while creating the ApplicationMgr " << std::endl;
return 1;
}
// check the arguments
if ( argc < 2 ) {
std::cout << "usage: " << argv[0] << "<JobOptions file> <number-of-threads=4>" << std::endl;
return 1;
}
// Get the input configuration file from arguments
std::string opts = ( argc > 1 ) ? argv[1] : "jobOptions.txt";
// Get the number of worker threads from arguments
std::string s_nt = ( argc > 2 ) ? argv[2] : "4";
// Set properties
propMgr->setProperty( "JobOptionsPath", opts );
propMgr->setProperty( "NoOfThreads", s_nt );
propMgr->setProperty( "EvtSel", "NONE" );
propMgr->setProperty( "MessageSvcType", "MTMessageSvc" );
if ( boost::algorithm::ends_with( opts, ".py" ) ) {
std::cout << "Running with Python not supported" << std::endl;
return 1;
}
// load MTMessageSvc library
if ( !( dllMgr->loadModule( "GaudiMTExample" ) ).isSuccess() ) {
std::cerr << "Can not load MTMessageSvc module (GaudiMTExample)" << std::endl;
return 1;
}
dllMgr.reset();
StatusCode sc;
std::string v_nt;
int nt;
sc = propMgr->getProperty( "NoOfThreads", v_nt );
if ( sc.isFailure() ) {
std::cout << "Cannot get get number of worker threads" << std::endl;
return 1;
} else {
nt = std::stoi( v_nt );
if ( nt <= 0 || nt > MAX_THREADS ) {
std::cout << "Invalid number of worker threads =>> " << v_nt << std::endl;
return 1;
} else {
std::cout << "---> Use " << nt << " worker threads <---" << std::endl;
}
}
propMgr.reset();
// Configure the application manager
sc = appMgr->configure();
std::cout << "---> Configure ApplicationMgr : " << appMgr->stateName() << " Status : " << sc.getCode() << std::endl;
if ( sc.isFailure() ) {
std::cout << "---> Fatal error while configuring the ApplicationMgr " << std::endl;
return 1;
}
// Initialize the application manager
sc = appMgr->initialize();
std::cout << "---> Initialize ApplicationMgr : " << appMgr->stateName() << " Status : " << sc.getCode() << std::endl;
if ( sc.isFailure() ) {
std::cout << "---> Fatal error while initializing the ApplicationMgr " << std::endl;
return 1;
}
// Create threads and process events
worker_done = nt; // Initialized counter
pthread_t thread[nt];
int tID[nt];
for ( int i = 0; i < nt; ++i ) {
/**
* This will start the worker thread. It will stop by itself when the
* called non-member method exits.
*/
tID[i] = i;
pthread_create( &thread[i], 0, work, static_cast<void*>( &tID[i] ) );
}
pthread_mutex_lock( &mutex );
if ( worker_done != 0 ) pthread_cond_wait( &condition, &mutex );
pthread_mutex_unlock( &mutex );
// Finalize the application manager
sc = appMgr->finalize();
std::cout << "---> Finalize ApplicationMgr : " << appMgr->stateName() << " Status : " << sc.getCode() << std::endl;
if ( sc.isFailure() ) {
std::cout << "---> Fatal error while finalizing the ApplicationMgr " << std::endl;
return 1;
}
// Terminate the application manager
sc = appMgr->terminate();
std::cout << "---> Terminate ApplicationMgr : " << appMgr->stateName() << " Status : " << sc.getCode() << std::endl;
if ( sc.isFailure() ) {
std::cout << "---> Fatal error while terminating the ApplicationMgr " << std::endl;
return 1;
}