From b4ed63405c9c7603aeaabc78434d1f1ede02bb84 Mon Sep 17 00:00:00 2001
From: Felix Weiglhofer <weiglhofer@fias.uni-frankfurt.de>
Date: Mon, 10 Jul 2023 14:00:07 +0000
Subject: [PATCH] Unpack: Make BMON Unpacker thread-safe.

---
 algo/detectors/bmon/UnpackBmon.cxx | 21 +++++++++++----------
 algo/detectors/bmon/UnpackBmon.h   | 13 ++++++++-----
 2 files changed, 19 insertions(+), 15 deletions(-)

diff --git a/algo/detectors/bmon/UnpackBmon.cxx b/algo/detectors/bmon/UnpackBmon.cxx
index 8719d9593c..4809362b63 100644
--- a/algo/detectors/bmon/UnpackBmon.cxx
+++ b/algo/detectors/bmon/UnpackBmon.cxx
@@ -19,15 +19,16 @@ namespace cbm::algo
 
   // ----   Algorithm execution   ---------------------------------------------
   UnpackBmon::resultType UnpackBmon::operator()(const uint8_t* msContent, const fles::MicrosliceDescriptor& msDescr,
-                                                const uint64_t tTimeslice)
+                                                const uint64_t tTimeslice) const
   {
 
     // --- Output data
     resultType result = {};
+    TimeSpec time;
 
     // --- Current Timeslice start time in epoch units. Note that it is always a multiple of epochs
     // --- and the epoch is a multiple of ns.
-    fCurrentTsTime = static_cast<uint64_t>(tTimeslice / critof001::kuEpochInNs) % critof001::kulEpochCycleEp;
+    time.currentTsTime = static_cast<uint64_t>(tTimeslice / critof001::kuEpochInNs) % critof001::kulEpochCycleEp;
 
     // --- Number of messages in microslice
     auto msSize = msDescr.size;
@@ -76,11 +77,11 @@ namespace cbm::algo
       switch (message[messageNr].getMessageType()) {
 
         case critof001::MSG_HIT: {
-          ProcessHitMessage(message[messageNr], result.first, result.second);
+          ProcessHitMessage(message[messageNr], time, result.first, result.second);
           break;
         }
         case critof001::MSG_EPOCH: {
-          ProcessEpochMessage(message[messageNr]);
+          ProcessEpochMessage(message[messageNr], time);
           break;
         }
         case critof001::MSG_SLOWC: {
@@ -104,8 +105,8 @@ namespace cbm::algo
 
 
   // -----   Process hit message   --------------------------------------------
-  inline void UnpackBmon::ProcessHitMessage(const critof001::Message& message, vector<CbmBmonDigi>& digiVec,
-                                            UnpackBmonMonitorData& monitor) const
+  inline void UnpackBmon::ProcessHitMessage(const critof001::Message& message, const TimeSpec& time,
+                                            vector<CbmBmonDigi>& digiVec, UnpackBmonMonitorData& monitor) const
   {
     // IGNORES:
     // - Duplicate messages
@@ -126,7 +127,7 @@ namespace cbm::algo
     const uint32_t channel    = message.getGdpbHitChanId();
     const uint32_t channelUId = (elinkPar.fChannelUId)[channel];
 
-    double messageTime  = message.getMsgFullTimeD(fCurrentEpochInTs) - elinkPar.fTimeOffset;
+    double messageTime  = message.getMsgFullTimeD(time.currentEpochInTs) - elinkPar.fTimeOffset;
     const double charge = (double) message.getGdpbHit32Tot();  //cast from uint32_t
 
     // --- Create output digi
@@ -136,14 +137,14 @@ namespace cbm::algo
 
 
   // -----   Process an epoch message   ---------------------------------------
-  inline void UnpackBmon::ProcessEpochMessage(const critof001::Message& message)
+  inline void UnpackBmon::ProcessEpochMessage(const critof001::Message& message, TimeSpec& time) const
   {
     const uint64_t epoch = message.getGdpbEpEpochNb();
 
     // --- Calculate epoch relative to timeslice start time; correct for epoch cycles
-    if (fCurrentTsTime <= epoch) { fCurrentEpochInTs = epoch - fCurrentTsTime; }
+    if (time.currentTsTime <= epoch) { time.currentEpochInTs = epoch - time.currentTsTime; }
     else {
-      fCurrentEpochInTs = epoch + critof001::kulEpochCycleEp - fCurrentTsTime;
+      time.currentEpochInTs = epoch + critof001::kulEpochCycleEp - time.currentTsTime;
     }
     //Problem if MS spans multiple epoch cycles?
   }
diff --git a/algo/detectors/bmon/UnpackBmon.h b/algo/detectors/bmon/UnpackBmon.h
index 7b01a4a767..681e368387 100644
--- a/algo/detectors/bmon/UnpackBmon.h
+++ b/algo/detectors/bmon/UnpackBmon.h
@@ -104,13 +104,18 @@ namespace cbm::algo
      ** @return STS digi data
      **/
     resultType operator()(const uint8_t* msContent, const fles::MicrosliceDescriptor& msDescr,
-                          const uint64_t tTimeslice);
+                          const uint64_t tTimeslice) const;
 
     /** @brief Set the parameter container
      ** @param params Pointer to parameter container
      **/
     void SetParams(std::unique_ptr<UnpackBmonPar> params) { fParams = *(std::move(params)); }
 
+  private:  // datatypes
+    struct TimeSpec {
+      uint64_t currentTsTime;     ///< Unix time of timeslice in units of epoch length
+      uint32_t currentEpochInTs;  ///< Current epoch number relative to timeslice start epoch
+    };
 
   private:  // methods
     /** @brief Process a hit message
@@ -118,18 +123,16 @@ namespace cbm::algo
      ** @param digiVec Vector to append the created digi to
      ** @param monitor Reference to monitor object
      **/
-    void ProcessHitMessage(const critof001::Message& message, std::vector<CbmBmonDigi>& digiVec,
+    void ProcessHitMessage(const critof001::Message& message, const TimeSpec& time, std::vector<CbmBmonDigi>& digiVec,
                            UnpackBmonMonitorData& monitor) const;
 
     /** @brief Process an epoch message (TS_MSB)
      ** @param message SMX message (32-bit word)
      **/
-    void ProcessEpochMessage(const critof001::Message& message);
+    void ProcessEpochMessage(const critof001::Message& message, TimeSpec& time) const;
 
 
   private:                            // members
-    uint64_t fCurrentTsTime    = 0;   ///< Unix time of timeslice in units of epoch length
-    uint32_t fCurrentEpochInTs = 0;   ///< Current epoch number relative to timeslice start epoch
     UnpackBmonPar fParams      = {};  ///< Parameter container
   };
 
-- 
GitLab