diff --git a/GaudiHive/src/AvalancheSchedulerSvc.cpp b/GaudiHive/src/AvalancheSchedulerSvc.cpp
index 24e48d6dfff40af80aff1b79fe21d5702a599cfb..7f0737f444ac0ba97d790d2044e6528a7aaa79d3 100644
--- a/GaudiHive/src/AvalancheSchedulerSvc.cpp
+++ b/GaudiHive/src/AvalancheSchedulerSvc.cpp
@@ -837,45 +837,101 @@ void AvalancheSchedulerSvc::dumpSchedulerState( int iSlot )
 {
 
   // To have just one big message
-  std::ostringstream outputMessageStream;
+  std::ostringstream outputMS;
+
+  outputMS << "Dumping scheduler state (inhale, exhale - everything is gonna be okay!)" << std::endl
+           << "=========================================================================================" << std::endl
+           << "++++++++++++++++++++++++++++++++ DUMPING SCHEDULER STATE ++++++++++++++++++++++++++++++++" << std::endl
+           << "=========================================================================================" << std::endl
+           << std::endl;
+
+  outputMS << "------------------------- Last schedule: Task/Slot/Thread Mapping -----------------------" << std::endl
+           << std::endl;
+
+  // Figure if TimelineSvc is available (used below to detect threads IDs)
+  auto timelineSvc = serviceLocator()->service<ITimelineSvc>( "TimelineSvc", false );
+  if ( !timelineSvc.isValid() ) {
+    outputMS << "Enable TimelineSvc to trace task/slot/thread mapping" << std::endl;
+  } else if ( !timelineSvc->isEnabled() ) {
+    outputMS << "Turn on timelining in the TimelineSvc to trace task/slot/thread mapping" << std::endl;
+  } else {
 
-  if ( 0 > iSlot )
-    outputMessageStream << "Dumping scheduler state for all slots:" << std::endl;
-  else
-    outputMessageStream << "Dumping scheduler state for slot " << iSlot << ":" << std::endl;
+    // Figure optimal printout layout
+    size_t indt( 0 );
+    for ( auto& slot : m_eventSlots )
+      for ( auto it = slot.algsStates.begin( AlgsExecutionStates::State::SCHEDULED );
+            it != slot.algsStates.end( AlgsExecutionStates::State::SCHEDULED ); ++it )
+        if ( index2algname( (uint)*it ).length() > indt ) indt = index2algname( (uint)*it ).length();
+
+    // Figure the last running schedule across all slots
+    for ( auto& slot : m_eventSlots ) {
+      for ( auto it = slot.algsStates.begin( AlgsExecutionStates::State::SCHEDULED );
+            it != slot.algsStates.end( AlgsExecutionStates::State::SCHEDULED ); ++it ) {
+
+        const std::string algoName{index2algname( (uint)*it )};
+
+        outputMS << "  task: " << std::setw( indt ) << algoName << " evt: " << slot.eventContext->evt()
+                 << " slot: " << slot.eventContext->slot();
+
+        // Try to get POSIX threads IDs the currently running tasks are scheduled to
+        if ( timelineSvc.isValid() ) {
+          TimelineEvent te{};
+          te.algorithm = algoName;
+          te.slot      = slot.eventContext->slot();
+          te.event     = slot.eventContext->evt();
+
+          if ( timelineSvc->getTimelineEvent( te ) )
+            outputMS << " thread.id: 0x" << std::hex << te.thread << std::dec;
+          else
+            outputMS << " thread.id: [unknown]"; // this means a task has just
+                                                 // been signed off as SCHEDULED,
+                                                 // but has not been assigned to a thread yet
+                                                 // (i.e., not running yet)
+        }
+        outputMS << " [" << m_algExecStateSvc->algExecState( algoName, *( slot.eventContext ) ) << "] " << std::endl;
+      }
+    }
+  }
 
-  outputMessageStream << "============================== Execution Task States ============================="
-                      << std::endl;
-  dumpState( outputMessageStream );
+  dumpState( outputMS );
 
-  outputMessageStream << std::endl
-                      << "============================== Control Flow and FSM States  ====================="
-                      << std::endl;
+  outputMS << std::endl
+           << "---------------------------- Task/CF/FSM Mapping " << ( 0 > iSlot ? "[all slots] --" : "[target slot] " )
+           << "--------------------------" << std::endl
+           << std::endl;
 
   int slotCount = -1;
-  for ( auto& thisSlot : m_eventSlots ) {
+  for ( auto& slot : m_eventSlots ) {
     slotCount++;
-    if ( thisSlot.complete ) continue;
+    if ( slot.complete ) continue;
 
-    outputMessageStream << "-----------  slot: " << thisSlot.eventContext->slot()
-                        << "  event: " << thisSlot.eventContext->evt() << " -----------" << std::endl;
+    outputMS << "[ slot: "
+             << ( slot.eventContext->valid() ? std::to_string( slot.eventContext->slot() ) : "[ctx invalid]" )
+             << "  event: "
+             << ( slot.eventContext->valid() ? std::to_string( slot.eventContext->evt() ) : "[ctx invalid]" )
+             << " ]:" << std::endl
+             << std::endl;
 
     if ( 0 > iSlot or iSlot == slotCount ) {
 
       // Snapshot of the Control Flow and FSM states
-      outputMessageStream << m_precSvc->printState( thisSlot ) << std::endl;
+      outputMS << m_precSvc->printState( slot ) << std::endl;
 
       // Mention sub slots
-      if ( thisSlot.allSubSlots.size() ) {
-        outputMessageStream << std::endl << "Number of sub-slots:" << thisSlot.allSubSlots.size() << std::endl;
-        outputMessageStream << "Sub-slot algorithms ready:" << thisSlot.subSlotAlgsReady.size() << std::endl;
+      if ( slot.allSubSlots.size() ) {
+        outputMS << std::endl << "Number of sub-slots:" << slot.allSubSlots.size() << std::endl;
+        outputMS << "Sub-slot algorithms ready:" << slot.subSlotAlgsReady.size() << std::endl;
       }
     }
   }
 
-  outputMessageStream << "=================================== END ======================================" << std::endl;
+  outputMS << std::endl
+           << "=========================================================================================" << std::endl
+           << "++++++++++++++++++++++++++++++++++++++ END OF DUMP ++++++++++++++++++++++++++++++++++++++" << std::endl
+           << "=========================================================================================" << std::endl
+           << std::endl;
 
-  info() << outputMessageStream.str() << endmsg;
+  info() << outputMS.str() << endmsg;
 }
 
 //---------------------------------------------------------------------------
@@ -1085,7 +1141,7 @@ StatusCode AvalancheSchedulerSvc::promoteToAsyncExecuted( unsigned int iAlgo, in
 }
 
 //===========================================================================
-void AvalancheSchedulerSvc::addAlg( Algorithm* a, EventContext* e, pthread_t t )
+void AvalancheSchedulerSvc::addAlg( IAlgorithm* a, EventContext* e, pthread_t t )
 {
 
   std::lock_guard<std::mutex> lock( m_ssMut );
@@ -1093,7 +1149,7 @@ void AvalancheSchedulerSvc::addAlg( Algorithm* a, EventContext* e, pthread_t t )
 }
 
 //===========================================================================
-bool AvalancheSchedulerSvc::delAlg( Algorithm* a )
+bool AvalancheSchedulerSvc::delAlg( IAlgorithm* a )
 {
 
   std::lock_guard<std::mutex> lock( m_ssMut );
diff --git a/GaudiHive/src/AvalancheSchedulerSvc.h b/GaudiHive/src/AvalancheSchedulerSvc.h
index 6234fc4c28457b6d06920afda196ae1e7878c3b2..6e63c57069fa4ee99bca03a9f157e0d61c762089 100644
--- a/GaudiHive/src/AvalancheSchedulerSvc.h
+++ b/GaudiHive/src/AvalancheSchedulerSvc.h
@@ -29,7 +29,6 @@
 #include "tbb/task.h"
 
 class IAlgorithm;
-class Algorithm;
 
 typedef AlgsExecutionStates::State State;
 typedef std::function<StatusCode()> action;
@@ -274,9 +273,9 @@ private:
   {
 
   public:
-    SchedulerState( Algorithm* a, EventContext* e, pthread_t t ) : m_a( a ), m_e( *e ), m_t( t ) {}
+    SchedulerState( IAlgorithm* a, EventContext* e, pthread_t t ) : m_a( a ), m_e( *e ), m_t( t ) {}
 
-    Algorithm* alg() const { return m_a; }
+    IAlgorithm* alg() const { return m_a; }
     EventContext ctx() const { return m_e; }
     pthread_t thread() const { return m_t; }
 
@@ -289,12 +288,12 @@ private:
 
     bool operator==( const SchedulerState& ss ) const { return ( m_a == ss.alg() ); }
 
-    bool operator==( Algorithm* a ) const { return ( m_a == a ); }
+    bool operator==( IAlgorithm* a ) const { return ( m_a == a ); }
 
     bool operator<( const SchedulerState& rhs ) const { return ( m_a < rhs.alg() ); }
 
   private:
-    Algorithm* m_a;
+    IAlgorithm* m_a;
     EventContext m_e;
     pthread_t m_t;
   };
@@ -303,8 +302,8 @@ private:
   static std::mutex m_ssMut;
 
 public:
-  void addAlg( Algorithm*, EventContext*, pthread_t );
-  bool delAlg( Algorithm* );
+  void addAlg( IAlgorithm*, EventContext*, pthread_t );
+  bool delAlg( IAlgorithm* );
   void dumpState() override;
 
 private:
diff --git a/GaudiHive/src/TimelineSvc.cpp b/GaudiHive/src/TimelineSvc.cpp
index ea7b1ba22afbd31b085e05667526b738ae2f126c..7bddac65ec723065167a9711c01a913195df1b98 100644
--- a/GaudiHive/src/TimelineSvc.cpp
+++ b/GaudiHive/src/TimelineSvc.cpp
@@ -72,15 +72,16 @@ void TimelineSvc::registerTimelineEvent( const TimelineEvent& e )
   }
 }
 
-void TimelineSvc::getTimelineEvent( TimelineEvent& e ) const
+bool TimelineSvc::getTimelineEvent( TimelineEvent& e ) const
 {
 
   for ( const auto& candidate : m_events ) {
     if ( candidate.algorithm == e.algorithm && candidate.event == e.event && candidate.slot == e.slot ) {
       e = candidate;
-      break;
+      return true;
     }
   }
+  return false;
 }
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
diff --git a/GaudiHive/src/TimelineSvc.h b/GaudiHive/src/TimelineSvc.h
index 4f9e6ad2ccf25a58b8fcb1c30da9a99b096040a1..b1e6d71b0428221f64d83ce7d5c8ef7d645e8da6 100644
--- a/GaudiHive/src/TimelineSvc.h
+++ b/GaudiHive/src/TimelineSvc.h
@@ -19,7 +19,7 @@ public:
   StatusCode finalize() override;
 
   void registerTimelineEvent( const TimelineEvent& ) override;
-  void getTimelineEvent( TimelineEvent& ) const override;
+  bool getTimelineEvent( TimelineEvent& ) const override;
 
   bool isEnabled() const override { return m_isEnabled; }
 
diff --git a/GaudiKernel/GaudiKernel/ITimelineSvc.h b/GaudiKernel/GaudiKernel/ITimelineSvc.h
index 15c7f5e30c63dcbc77cb7c991e7d974bc98bc64a..245d09074c3753d9efa5c6efbe7977ff43b448ce 100644
--- a/GaudiKernel/GaudiKernel/ITimelineSvc.h
+++ b/GaudiKernel/GaudiKernel/ITimelineSvc.h
@@ -30,7 +30,7 @@ public:
 
   virtual void registerTimelineEvent( const TimelineEvent& ) = 0;
   // Augment a partially pre-filled TimelineEvent object with matching info
-  virtual void getTimelineEvent( TimelineEvent& ) const = 0;
+  virtual bool getTimelineEvent( TimelineEvent& ) const = 0;
   virtual bool isEnabled() const                        = 0;
 };