Loading [MathJax]/extensions/tex2jax.js
Go to the documentation of this file.
29 #include <string_view>
31 #include <unordered_set>
34 #include "boost/algorithm/string.hpp"
35 #include "boost/thread.hpp"
36 #include "boost/tokenizer.hpp"
41 #define ON_DEBUG if ( msgLevel( MSG::DEBUG ) )
42 #define ON_VERBOSE if ( msgLevel( MSG::VERBOSE ) )
45 struct DataObjIDSorter {
53 v.reserve( coll.
size() );
54 for (
const DataObjID&
id : coll )
v.push_back( &
id );
61 [testStates](
const EventSlot& ss ) { return ss.algsStates.containsAny( testStates ); } );
77 if ( sc.
isFailure() ) warning() <<
"Base class could not be initialized" <<
endmsg;
82 fatal() <<
"Error retrieving ThreadPoolSvc" <<
endmsg;
87 fatal() <<
"Cannot cast ThreadPoolSvc" <<
endmsg;
92 fatal() <<
"Cannot find valid TBB task_arena" <<
endmsg;
97 info() <<
"Activating scheduler in a separate thread" <<
endmsg;
102 fatal() <<
"Terminating initialization" <<
endmsg;
105 ON_DEBUG debug() <<
"Waiting for AvalancheSchedulerSvc to activate" <<
endmsg;
114 warning() <<
"No CondSvc found, or not enabled. "
115 <<
"Will not manage CondAlgorithms" <<
endmsg;
123 fatal() <<
"Error retrieving AlgoResourcePool" <<
endmsg;
129 fatal() <<
"Error retrieving AlgExecStateSvc" <<
endmsg;
136 fatal() <<
"Error retrieving EventDataSvc interface IHiveWhiteBoard." <<
endmsg;
148 const unsigned int algsNumber = algos.
size();
149 if ( algsNumber != 0 ) {
150 info() <<
"Found " << algsNumber <<
" algorithms" <<
endmsg;
152 error() <<
"No algorithms found" <<
endmsg;
168 fatal() <<
"Could not convert IAlgorithm into Gaudi::Algorithm: this will result in a crash." <<
endmsg;
177 algosOutputDependenciesMap[algoPtr->
name()] = algoOutputs;
181 ostdd <<
"Data Dependencies for Algorithms:";
186 if (
nullptr == algoPtr ) {
187 fatal() <<
"Could not convert IAlgorithm into Gaudi::Algorithm for " << ialgoPtr->
name()
188 <<
": this will result in a crash." <<
endmsg;
196 ostdd <<
"\n " << algoPtr->
name();
198 auto write_owners = [&avis, &ostdd](
const DataObjID id ) {
207 ostdd <<
"\n o INPUT " <<
id;
209 algoDependencies.
insert(
id );
213 ostdd <<
"\n o OUTPUT " << *
id;
215 if (
id->key().find(
":" ) != std::string::npos ) {
216 error() <<
" in Alg " << algoPtr->
name() <<
" alternatives are NOT allowed for outputs! id: " << *
id
224 algosInputDependenciesMap[algoPtr->
name()] = algoDependencies;
234 for (
auto o : globalInp ) {
237 requiredInputKeys.
insert( o.key() );
238 if ( globalOutp.
find( o ) == globalOutp.
end() ) unmetDepInp.
insert( o );
241 for (
auto o : globalOutp ) {
242 if ( globalInp.find( o ) == globalInp.end() && requiredInputKeys.
find( o.key() ) == requiredInputKeys.
end() ) {
246 auto it = algosOutputDependenciesMap.
find( algoName );
247 if ( it != algosOutputDependenciesMap.
end() ) {
248 if ( it->second.find( o ) != it->second.end() ) {
254 if ( !ignored ) { unusedOutp.
insert( o ); }
261 if ( unmetDepInp.
size() > 0 ) {
263 auto printUnmet = [&](
auto msg ) {
264 for (
const DataObjID* o : sortedDataObjIDColl( unmetDepInp ) ) {
265 msg <<
" o " << *o <<
" required by Algorithm: " <<
endmsg;
267 for (
const auto& p : algosInputDependenciesMap )
268 if ( p.second.find( *o ) != p.second.end() )
msg <<
" * " << p.first <<
endmsg;
278 dataLoaderAlg = algo;
282 if ( dataLoaderAlg ==
nullptr ) {
284 <<
"\" found, and unmet INPUT dependencies "
286 printUnmet( fatal() );
290 info() <<
"Will attribute the following unmet INPUT dependencies to \"" << dataLoaderAlg->
type() <<
"/"
291 << dataLoaderAlg->name() <<
"\" Algorithm" <<
endmsg;
292 printUnmet( info() );
297 fatal() <<
"Unable to dcast DataLoader \"" <<
m_useDataLoader.
value() <<
"\" IAlg to Gaudi::Algorithm"
302 for (
auto&
id : unmetDepInp ) {
303 ON_DEBUG debug() <<
"adding OUTPUT dep \"" <<
id <<
"\" to " << dataLoaderAlg->
type() <<
"/"
304 << dataLoaderAlg->name() <<
endmsg;
309 fatal() <<
"Auto DataLoading not requested, "
310 <<
"and the following unmet INPUT dependencies were found:" <<
endmsg;
311 printUnmet( fatal() );
316 info() <<
"No unmet INPUT data dependencies were found" <<
endmsg;
321 if ( unusedOutp.
size() > 0 ) {
323 auto printUnusedOutp = [&](
auto msg ) {
324 for (
const DataObjID* o : sortedDataObjIDColl( unusedOutp ) ) {
325 msg <<
" o " << *o <<
" produced by Algorithm: " <<
endmsg;
327 for (
const auto& p : algosOutputDependenciesMap )
328 if ( p.second.find( *o ) != p.second.end() )
msg <<
" * " << p.first <<
endmsg;
332 fatal() <<
"The following unused OUTPUT items were found:" <<
endmsg;
333 printUnusedOutp( fatal() );
336 info() <<
"No unused OUTPUT items were found" <<
endmsg;
343 fatal() <<
"Error retrieving PrecedenceSvc" <<
endmsg;
348 fatal() <<
"Unable to dcast PrecedenceSvc" <<
endmsg;
363 if ( !messageSvc.
isValid() ) error() <<
"Error retrieving MessageSvc interface IMessageSvc." <<
endmsg;
374 info() <<
"Concurrency level information:" <<
endmsg;
379 info() <<
"Task scheduling settings:" <<
endmsg;
380 info() <<
" o Avalanche generation mode: "
382 info() <<
" o Preemptive scheduling of CPU-blocking tasks: "
387 info() <<
" o Scheduling of condition tasks: " << (
m_enableCondSvc ?
"enabled" :
"disabled" ) <<
endmsg;
406 if ( sc.
isFailure() ) warning() <<
"Base class could not be finalized" <<
endmsg;
409 if ( sc.
isFailure() ) warning() <<
"Scheduler could not be deactivated" <<
endmsg;
411 info() <<
"Joining Scheduler thread" <<
endmsg;
416 error() <<
"problems in scheduler thread" <<
endmsg;
436 ON_DEBUG debug() <<
"AvalancheSchedulerSvc::activate()" <<
endmsg;
439 error() <<
"problems initializing ThreadPoolSvc" <<
endmsg;
457 verbose() <<
"Action did not succeed (which is not bad per se)." <<
endmsg;
468 verbose() <<
"Iteration did not succeed (which is not bad per se)." <<
endmsg;
476 ON_DEBUG debug() <<
"Terminating thread-pool resources" <<
endmsg;
478 error() <<
"Problems terminating thread pool" <<
endmsg;
524 if ( !eventContext ) {
525 fatal() <<
"Event context is nullptr" <<
endmsg;
530 ON_DEBUG debug() <<
"A free processing slot could not be found." <<
endmsg;
539 const unsigned int thisSlotNum = eventContext->
slot();
542 fatal() <<
"The slot " << thisSlotNum <<
" is supposed to be a finished event but it's not" <<
endmsg;
546 ON_DEBUG debug() <<
"Executing event " << eventContext->
evt() <<
" on slot " << thisSlotNum <<
endmsg;
547 thisSlot.
reset( eventContext );
554 if (
m_precSvc->iterate( thisSlot, cs ).isFailure() ) {
555 error() <<
"Failed to call IPrecedenceSvc::iterate for slot " << thisSlotNum <<
endmsg;
559 if ( this->
iterate().isFailure() ) {
560 error() <<
"Failed to call AvalancheSchedulerSvc::updateStates for slot " << thisSlotNum <<
endmsg;
569 verbose() <<
"Pushing the action to update the scheduler for slot " << eventContext->
slot() <<
endmsg;
582 for (
auto context : eventContexts ) {
609 ON_DEBUG debug() <<
"Popped slot " << eventContext->
slot() <<
" (event " << eventContext->
evt() <<
")" <<
endmsg;
621 ON_DEBUG debug() <<
"Try Pop successful slot " << eventContext->
slot() <<
"(event " << eventContext->
evt() <<
")"
644 for (
unsigned int retryIndex = 0; retryIndex < retries; ++retryIndex ) {
651 OccupancySnapshot nextSnap;
656 if ( !thisSlot.eventContext )
continue;
658 int iSlot = thisSlot.eventContext->slot();
670 if ( nextSnap.states.empty() ) {
677 slotStateTotals.
resize( AState::MAXVALUE );
679 slotStateTotals[
state] = thisSlot.algsStates.sizeOfSubset(
AState(
state ) );
683 for (
auto& subslot : thisSlot.allSubSlots ) {
685 slotStateTotals[
state] += subslot.algsStates.sizeOfSubset(
AState(
state ) );
691 auto& drAlgs = thisAlgsStates.
algsInState( AState::DATAREADY );
692 for ( uint algIndex : drAlgs ) {
698 schedule(
TaskSpec(
nullptr, algIndex, algName, rank, blocking, iSlot, thisSlot.eventContext.get() ) );
701 <<
"Could not apply transition from " << AState::DATAREADY <<
" for algorithm " << algName
702 <<
" on processing slot " << iSlot <<
endmsg;
706 for (
auto& subslot : thisSlot.allSubSlots ) {
707 auto& drAlgsSubSlot = subslot.algsStates.algsInState( AState::DATAREADY );
708 for ( uint algIndex : drAlgsSubSlot ) {
713 schedule(
TaskSpec(
nullptr, algIndex, algName, rank, blocking, iSlot, subslot.eventContext.get() ) );
719 s <<
"START, " << thisAlgsStates.
sizeOfSubset( AState::CONTROLREADY ) <<
", "
731 if (
m_precSvc->CFRulesResolved( thisSlot ) &&
732 !thisSlot.algsStates.containsAny(
733 { AState::CONTROLREADY, AState::DATAREADY, AState::SCHEDULED, AState::RESOURCELESS } ) &&
734 !subSlotAlgsInStates( thisSlot,
735 { AState::CONTROLREADY, AState::DATAREADY, AState::SCHEDULED, AState::RESOURCELESS } ) &&
736 !thisSlot.complete ) {
738 thisSlot.complete =
true;
742 ON_DEBUG debug() <<
"Event " << thisSlot.eventContext->evt() <<
" finished (slot "
743 << thisSlot.eventContext->slot() <<
")." <<
endmsg;
750 thisSlot.eventContext.reset(
nullptr );
760 if ( !nextSnap.states.empty() ) {
774 auto slotIndex = contextPtr->
slot();
780 auto subSlotIndex = contextPtr->
subSlot();
787 <<
", subslot:" << subSlotIndex <<
", event:" << contextPtr->
evt() <<
"]" <<
endmsg;
797 <<
", event:" << contextPtr->
evt() <<
"]" <<
endmsg;
815 if ( !slot.
algsStates.
containsAny( { AState::DATAREADY, AState::SCHEDULED, AState::RESOURCELESS } ) &&
816 !subSlotAlgsInStates( slot, { AState::DATAREADY, AState::SCHEDULED, AState::RESOURCELESS } ) ) {
832 const uint slotIdx = eventContext->
slot();
834 error() <<
"Event " << eventContext->
evt() <<
" on slot " << slotIdx <<
" failed" <<
endmsg;
857 outputMS <<
"Dumping scheduler state\n"
858 <<
"=========================================================================================\n"
859 <<
"++++++++++++++++++++++++++++++++++++ SCHEDULER STATE ++++++++++++++++++++++++++++++++++++\n"
860 <<
"=========================================================================================\n\n";
864 outputMS <<
"------------------ Last schedule: Task/Event/Slot/Thread/State Mapping "
865 <<
"------------------\n\n";
869 if ( !timelineSvc.isValid() || !timelineSvc->isEnabled() ) {
870 outputMS <<
"WARNING Enable TimelineSvc in record mode (RecordTimeline = True) to trace the mapping\n";
877 auto& schedAlgs = slot.algsStates.algsInState( AState::SCHEDULED );
878 for ( uint algIndex : schedAlgs ) {
886 auto& schedAlgs = slot.algsStates.algsInState( AState::SCHEDULED );
887 for ( uint algIndex : schedAlgs ) {
891 outputMS <<
" task: " <<
std::setw( indt ) << algoName <<
" evt/slot: " << slot.eventContext->evt() <<
"/"
892 << slot.eventContext->slot();
895 if ( timelineSvc.isValid() ) {
898 te.slot = slot.eventContext->slot();
899 te.event = slot.eventContext->evt();
901 if ( timelineSvc->getTimelineEvent( te ) )
904 outputMS <<
" thread.id: [unknown]";
909 outputMS <<
" state: [" <<
m_algExecStateSvc->algExecState( algoName, *( slot.eventContext ) ) <<
"]\n";
916 outputMS <<
"\n---------------------------- Task/CF/FSM Mapping "
917 << ( 0 > iSlot ?
"[all slots] --" :
"[target slot] " ) <<
"--------------------------\n\n";
921 subSlotAlgsInStates( m_eventSlots[iSlot], {
AState::ERROR } )
924 for (
auto& slot : m_eventSlots ) {
926 if ( slot.complete )
continue;
928 outputMS <<
"[ slot: "
929 << ( slot.eventContext->valid() ?
std::to_string( slot.eventContext->slot() ) :
"[ctx invalid]" )
931 << ( slot.eventContext->
valid() ?
std::
to_string( slot.eventContext->
evt() ) :
"[ctx invalid]" )
934 if ( 0 > iSlot || iSlot == slotCount ) {
938 outputMS <<
"ERROR alg(s):";
940 auto& errorAlgs = slot.algsStates.algsInState(
AState::ERROR );
941 for ( uint algIndex : errorAlgs ) {
942 outputMS <<
" " << index2algname( algIndex );
945 if ( errorCount == 0 ) outputMS <<
" in subslot(s)";
949 outputMS << m_precSvc->printState( slot ) <<
"\n";
953 if ( m_verboseSubSlots && !slot.allSubSlots.empty() ) {
954 outputMS <<
"\nNumber of sub-slots: " << slot.allSubSlots.size() <<
"\n\n";
955 auto slotID = slot.eventContext->valid() ?
std::to_string( slot.eventContext->slot() ) :
"[ctx invalid]";
956 for (
auto& ss : slot.allSubSlots ) {
957 outputMS <<
"[ slot: " << slotID <<
", sub-slot: "
958 << ( ss.eventContext->valid() ?
std::to_string( ss.eventContext->subSlot() ) :
"[ctx invalid]" )
959 <<
", entry: " << ss.entryPoint <<
", event: "
963 outputMS <<
"ERROR alg(s):";
964 auto& errorAlgs = ss.algsStates.algsInState(
AState::ERROR );
965 for ( uint algIndex : errorAlgs ) { outputMS <<
" " << index2algname( algIndex ); }
969 outputMS << m_precSvc->printState( ss ) <<
"\n";
978 if ( 0 <= iSlot && !wasAlgError ) {
979 outputMS <<
"\n------------------------------ Algorithm Execution States -----------------------------\n\n";
980 m_algExecStateSvc->dump( outputMS, *( m_eventSlots[iSlot].eventContext ) );
983 outputMS <<
"\n=========================================================================================\n"
984 <<
"++++++++++++++++++++++++++++++++++++++ END OF DUMP ++++++++++++++++++++++++++++++++++++++\n"
985 <<
"=========================================================================================\n\n";
987 info() << outputMS.str() <<
endmsg;
1010 unsigned int algIndex{
ts.algIndex };
1011 std::string_view algName(
ts.algName );
1012 unsigned int algRank{
ts.algRank };
1013 bool blocking{
ts.blocking };
1014 int slotIndex{
ts.slotIndex };
1035 sc =
revise( algIndex, contextPtr, AState::SCHEDULED );
1037 ON_DEBUG debug() <<
"Scheduled " << algName <<
" [slot:" << slotIndex <<
", event:" << contextPtr->evt()
1038 <<
", rank:" << algRank <<
", blocking:" << ( blocking ?
"yes" :
"no" )
1047 sc =
revise(
ts.algIndex,
ts.contextPtr, AState::SCHEDULED );
1053 sc =
revise(
ts.algIndex,
ts.contextPtr, AState::RESOURCELESS );
1079 ? ( algstate.
filterPassed() ? AState::EVTACCEPTED : AState::EVTREJECTED )
1085 ON_DEBUG debug() <<
"Executed " <<
ts.algName <<
" [slot:" <<
ts.slotIndex <<
", event:" <<
ts.contextPtr->evt()
1086 <<
", rank:" <<
ts.algRank <<
", blocking:" << (
ts.blocking ?
"yes" :
"no" )
1106 fatal() <<
"Attempted to nest EventViews at node " << nodeName <<
": this is not supported" <<
endmsg;
1114 auto action = [
this, slotIndex = sourceContext->
slot(), viewContextPtr = viewContext.
release(),
1117 EventSlot& topSlot = this->m_eventSlots[slotIndex];
1119 if ( viewContextPtr ) {
1145 if ( samplePeriod < 0 ) {
std::unique_ptr< EventContext > eventContext
Cache for the eventContext.
SmartIF< IHiveWhiteBoard > m_whiteboard
A shortcut to the whiteboard.
GAUDI_API void setCurrentContext(const EventContext *ctx)
A service to resolve the task execution precedence.
const std::string name() const
property name
StatusCode initialize() override
Gaudi::Property< std::string > m_useDataLoader
Struct to hold entries in the alg queues.
StatusCode finalize() override
Finalise.
void acceptDHVisitor(IDataHandleVisitor *) const override
const std::string & name() const override
The identifying name of the algorithm object.
Gaudi::Property< std::string > m_optimizationMode
unsigned int getControlFlowNodeCounter() const
Get total number of control flow graph nodes.
StatusCode iterate()
Loop on all slots to schedule DATAREADY algorithms and sign off ready events.
Class representing an event slot.
void addDependency(const DataObjID &id, const Gaudi::DataHandle::Mode &mode) override
std::chrono::system_clock::time_point m_lastSnapshot
const concurrency::PrecedenceRulesGraph * getRules() const
Precedence rules accessor.
virtual const std::string & type() const =0
The type of the algorithm.
tbb::concurrent_priority_queue< TaskSpec, AlgQueueSort > m_scheduledQueue
Queues for scheduled algorithms.
StatusCode schedule(TaskSpec &&)
Gaudi::Property< bool > m_showControlFlow
std::atomic< bool > m_needsUpdate
Gaudi::Property< bool > m_enableCondSvc
StatusCode deactivate()
Deactivate scheduler.
MSG::Level msgLevel() const
get the cached level (originally extracted from the embedded MsgStream)
StatusCode finalize() override
std::vector< EventSlot > m_eventSlots
Vector of events slots.
tbb::task_arena * m_arena
SmartIF< IAlgExecStateSvc > m_algExecStateSvc
Algorithm execution state manager.
bool complete
Flags completion of the event.
std::string fullKey() const
combination of the key and the ClassName, mostly for debugging
SmartIF< ICondSvc > m_condSvc
A shortcut to service for Conditions handling.
void eventFailed(EventContext *eventContext)
Method to execute if an event failed.
Gaudi::Property< int > m_threadPoolSize
std::vector< std::string > owners_names_of(const DataObjID &id, bool with_main=false) const
void addSubSlot(std::unique_ptr< EventContext > viewContext, const std::string &nodeName)
Add a subslot to the slot (this constructs a new slot and registers it with the parent one)
size_t m_maxEventsInFlight
bool isValid() const
Allow for check if smart pointer is valid.
Gaudi::Property< unsigned int > m_maxBlockingAlgosInFlight
std::ostream & operator<<(std::ostream &s, const std::pair< T1, T2 > &p)
Serialize an std::pair in a python like format. E.g. "(1, 2)".
const std::string & name() const override
Retrieve name of the service
T hardware_concurrency(T... args)
Gaudi::Property< bool > m_enablePreemptiveBlockingTasks
Base class from which all concrete algorithm classes should be derived.
Gaudi::Property< std::string > m_whiteboardSvcName
Gaudi::Property< bool > m_checkOutput
void reset(EventContext *theeventContext)
Reset all resources in order to reuse the slot (thread-unsafe)
const ValueType & value() const
void disableSubSlots(const std::string &nodeName)
Disable event views for a given CF view node by registering an empty container Contact B.
const StatusCode & execStatus() const
Gaudi::Property< bool > m_simulateExecution
tbb::concurrent_priority_queue< TaskSpec, AlgQueueSort > m_scheduledBlockingQueue
virtual void recordOccupancy(int samplePeriod, std::function< void(OccupancySnapshot)> callback) override
Sample occupancy at fixed interval (ms) Negative value to deactivate, 0 to snapshot every change Each...
const std::string & index2algname(unsigned int index)
Convert an integer to a name.
std::vector< EventSlot > allSubSlots
Actual sub-slot instances.
AlgsExecutionStates::State AState
unsigned int m_algosInFlight
Number of algorithms presently in flight.
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
StatusCode tryPopFinishedEvent(EventContext *&eventContext) override
Try to fetch an event from the scheduler.
virtual StatusCode scheduleEventView(const EventContext *sourceContext, const std::string &nodeName, std::unique_ptr< EventContext > viewContext) override
Method to inform the scheduler about event views.
SmartIF< IAlgResourcePool > m_algResourcePool
Cache for the algorithm resource pool.
unsigned int freeSlots() override
Get free slots number.
Gaudi::Property< bool > m_showDataDeps
size_t m_maxAlgosInFlight
StatusCode initialize() override
Initialise.
bool containsAny(std::initializer_list< State > l) const
check if the collection contains at least one state of any listed types
const StatusCode & ignore() const
Allow discarding a StatusCode without warning.
T emplace_back(T... args)
AlgorithmNode * getAlgorithmNode(const std::string &algoName) const
Get the AlgorithmNode from by algorithm name using graph index.
Gaudi::Property< bool > m_dumpIntraEventDynamics
StatusCode set(unsigned int iAlgo, State newState)
std::queue< TaskSpec > m_retryQueue
constexpr static const auto SUCCESS
ContextID_t subSlot() const
TYPE * get() const
Get interface pointer.
const DataObjIDColl & outputDataObjs() const override
std::chrono::duration< int64_t, std::milli > m_snapshotInterval
bool valid(Iterator begin, Iterator end)
check the validness of the trees or nodes
#define DECLARE_COMPONENT(type)
SmartIF< IThreadPoolSvc > m_threadPoolSvc
State
Execution states of the algorithms Must have contiguous integer values 0, 1...
const unsigned int & getAlgoIndex() const
Get algorithm index.
std::string toString() const override
value -> string
StatusCode revise(unsigned int iAlgo, EventContext *contextPtr, AState state, bool iterate=false)
bool filterPassed() const
void activate()
Activate scheduler.
tbb::concurrent_bounded_queue< action > m_actionsQueue
Queue where closures are stored and picked for execution.
std::unordered_map< std::string, unsigned int > m_algname_index_map
Map to bookkeep the information necessary to the name2index conversion.
Gaudi::Property< bool > m_checkDeps
bool isStalled(const EventSlot &) const
Check if scheduling in a particular slot is in a stall.
const DataObjIDColl & inputDataObjs() const override
std::thread m_thread
The thread in which the activate function runs.
StatusCode pushNewEvents(std::vector< EventContext * > &eventContexts) override
Gaudi::Property< bool > m_showDataFlow
Gaudi::Property< std::vector< std::string > > m_checkOutputIgnoreList
constexpr static const auto FAILURE
StatusCode signoff(const TaskSpec &)
The call to this method is triggered only from within the AlgTask.
size_t sizeOfSubset(State state) const
std::atomic_int m_freeSlots
Atomic to account for asyncronous updates by the scheduler wrt the rest.
unsigned int m_blockingAlgosInFlight
Number of algorithms presently in flight.
std::function< void(OccupancySnapshot)> m_snapshotCallback
StatusCode pushNewEvent(EventContext *eventContext) override
Make an event available to the scheduler.
StatusCode popFinishedEvent(EventContext *&eventContext) override
Blocks until an event is available.
const boost::container::flat_set< int > algsInState(State state) const
AlgsExecutionStates algsStates
Vector of algorithms states.
SmartIF< IPrecedenceSvc > m_precSvc
A shortcut to the Precedence Service.
std::atomic< ActivationState > m_isActive
Flag to track if the scheduler is active or not.
tbb::concurrent_bounded_queue< EventContext * > m_finishedEvents
Queue of finished events.
std::vector< std::string > m_algname_vect
Vector to bookkeep the information necessary to the index2name conversion.
void dumpSchedulerState(int iSlot)
Dump the state of the scheduler.
size_t index(const Gaudi::ParticleProperty *property, const Gaudi::Interfaces::IParticlePropertySvc *service)
helper utility for mapping of Gaudi::ParticleProperty object into non-negative integral sequential id...
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator
A service which initializes a TBB thread pool.