From 168c8fb3e6d1d2af34d9bf9ac233ffff286624e9 Mon Sep 17 00:00:00 2001
From: Charles Leggett <leggett@cern.ch>
Date: Thu, 16 Feb 2017 20:56:34 +0100
Subject: [PATCH] GMR 277: added ConcurrencyFlags class

see gaudi/Gaudi!277  (not yet accepted)
---
 GaudiHive/src/ForwardSchedulerSvc.cpp      |  4 ++
 GaudiHive/src/ThreadPoolSvc.cpp            |  5 ++
 GaudiKernel/GaudiKernel/ConcurrencyFlags.h | 65 ++++++++++++++++++++++
 GaudiKernel/src/Lib/ConcurrencyFlags.cpp   | 11 ++++
 4 files changed, 85 insertions(+)
 create mode 100644 GaudiKernel/GaudiKernel/ConcurrencyFlags.h
 create mode 100644 GaudiKernel/src/Lib/ConcurrencyFlags.cpp

diff --git a/GaudiHive/src/ForwardSchedulerSvc.cpp b/GaudiHive/src/ForwardSchedulerSvc.cpp
index 4538341d6..a4aad12e9 100644
--- a/GaudiHive/src/ForwardSchedulerSvc.cpp
+++ b/GaudiHive/src/ForwardSchedulerSvc.cpp
@@ -6,6 +6,7 @@
 #include "GaudiKernel/IDataManagerSvc.h"
 #include "GaudiKernel/SvcFactory.h"
 #include "GaudiKernel/ThreadLocalContext.h"
+#include "GaudiKernel/ConcurrencyFlags.h"
 
 // Local
 #include "AlgResourcePool.h"
@@ -105,6 +106,9 @@ StatusCode ForwardSchedulerSvc::initialize()
     }
   }
 
+  // set global concurrency flags
+  Gaudi::Concurrency::ConcurrencyFlags::setNumConcEvents( numberOfWBSlots );
+
   // Get dedicated scheduler for I/O-bound algorithms
   if ( m_useIOBoundAlgScheduler ) {
     m_IOBoundAlgScheduler = serviceLocator()->service( m_IOBoundAlgSchedulerSvcName );
diff --git a/GaudiHive/src/ThreadPoolSvc.cpp b/GaudiHive/src/ThreadPoolSvc.cpp
index 3adc0c6c6..f98765d14 100644
--- a/GaudiHive/src/ThreadPoolSvc.cpp
+++ b/GaudiHive/src/ThreadPoolSvc.cpp
@@ -1,6 +1,7 @@
 #include "ThreadPoolSvc.h"
 
 #include "GaudiKernel/SvcFactory.h"
+#include "GaudiKernel/ConcurrencyFlags.h"
 #include "ThreadInitTask.h"
 
 #include "tbb/task_scheduler_init.h"
@@ -113,8 +114,12 @@ ThreadPoolSvc::initPool(const int& poolSize) {
     if (msgLevel(MSG::DEBUG)){
       debug() << "creating barrier of size " << thePoolSize << endmsg;
     }
+    Gaudi::Concurrency::ConcurrencyFlags::setNumThreads(thePoolSize);
+
     m_barrier = std::unique_ptr<boost::barrier>( new boost::barrier(thePoolSize) );
 
+  } else {
+    Gaudi::Concurrency::ConcurrencyFlags::setNumThreads(1);
   }
 
   // Launch the init tool tasks
diff --git a/GaudiKernel/GaudiKernel/ConcurrencyFlags.h b/GaudiKernel/GaudiKernel/ConcurrencyFlags.h
new file mode 100644
index 000000000..c556c3845
--- /dev/null
+++ b/GaudiKernel/GaudiKernel/ConcurrencyFlags.h
@@ -0,0 +1,65 @@
+#ifndef GAUDIKERNEL_CONCURRENCYFLAGS_H
+#define GAUDIKERNEL_CONCURRENCYFLAGS_H 1
+
+#include <cstddef>
+
+#include "GaudiKernel/Kernel.h"
+
+class ThreadPoolSvc;
+class ForwardSchedulerSvc;
+
+/** @class ConcurrencyFlags ConcurrencyFlags.h GaudiKernel/ConcurrencyFlags.h
+ *
+ * Provides information about the level of concurrency of the currently
+ * executing job
+ *
+ * will enumerate the number of Worker Threads (for multi-threading), 
+ * Processes (for multi-processing), and total number of concurrent events.
+ *
+ */
+
+namespace Gaudi {
+
+  namespace Concurrency {
+
+    class ConcurrencyFlags {
+
+      friend class ::ThreadPoolSvc;
+      friend class ::ForwardSchedulerSvc;
+
+    public:
+      
+      /** number of Worker Threads (for MT)
+       */
+      static GAUDI_API std::size_t numThreads() {return n_threads; }
+
+      /** number of Concurrent Events (for MT)
+       */
+      static GAUDI_API std::size_t numConcurrentEvents() { return n_concEvts; }
+
+      /** number of forked child processes (for MP)
+       */
+      static GAUDI_API std::size_t numProcs() { return n_procs; }
+
+      /** serial operation, or some form of concurrency
+       */
+      static GAUDI_API bool concurrent() { 
+        return ( n_threads || n_concEvts || n_procs );
+      }
+
+    private:
+
+      static GAUDI_API void setNumThreads(const std::size_t& nT) {n_threads=nT;}
+      static GAUDI_API void setNumConcEvents(const std::size_t& nE) {n_concEvts=nE;}
+      static GAUDI_API void setNumProcs(const std::size_t& nP) {n_procs=nP;}
+
+    private:
+      static std::size_t n_threads;     // worker threads for MT
+      static std::size_t n_concEvts;    // concurrent events for MT
+      static std::size_t n_procs;       // child processes for MP
+    };
+
+  }
+}
+
+#endif
diff --git a/GaudiKernel/src/Lib/ConcurrencyFlags.cpp b/GaudiKernel/src/Lib/ConcurrencyFlags.cpp
new file mode 100644
index 000000000..ec433afd8
--- /dev/null
+++ b/GaudiKernel/src/Lib/ConcurrencyFlags.cpp
@@ -0,0 +1,11 @@
+#include "GaudiKernel/ConcurrencyFlags.h"
+
+namespace Gaudi {
+  namespace Concurrency {
+
+    std::size_t ConcurrencyFlags::n_threads  { 0 };
+    std::size_t ConcurrencyFlags::n_concEvts { 0 };
+    std::size_t ConcurrencyFlags::n_procs    { 0 };
+
+  }
+}
-- 
GitLab