From bc0ddb93c31fd26469ece6fc3a224c4e3e100367 Mon Sep 17 00:00:00 2001 From: Felix Weiglhofer <weiglhofer@fias.uni-frankfurt.de> Date: Mon, 26 Jun 2023 14:43:52 +0000 Subject: [PATCH] algo::UnpackSts: Make thread-safe. --- algo/detectors/sts/UnpackSts.cxx | 27 ++++++++++++++------------- algo/detectors/sts/UnpackSts.h | 22 ++++++++++++++-------- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/algo/detectors/sts/UnpackSts.cxx b/algo/detectors/sts/UnpackSts.cxx index 06a154a98c..7753040e7d 100644 --- a/algo/detectors/sts/UnpackSts.cxx +++ b/algo/detectors/sts/UnpackSts.cxx @@ -20,19 +20,20 @@ namespace cbm::algo // ---- Algorithm execution --------------------------------------------- UnpackSts::resultType UnpackSts::operator()(const uint8_t* msContent, const fles::MicrosliceDescriptor& msDescr, - const uint64_t tTimeslice) + const uint64_t tTimeslice) const { // --- Output data resultType result = {}; // --- Current Timeslice start time in epoch units. Note that it is always a multiple of epochs // --- and the epoch is a multiple of ns. + TimeSpec time; const uint64_t epochLengthInNs = fkEpochLength * fkClockCycleNom / fkClockCycleDen; - fCurrentTsTime = tTimeslice / epochLengthInNs; + time.currentTsTime = tTimeslice / epochLengthInNs; // --- Current TS_MSB epoch cycle auto const msTime = msDescr.idx; // Unix time of MS in ns - fCurrentCycle = std::ldiv(msTime, fkCycleLength).quot; + time.currentCycle = std::ldiv(msTime, fkCycleLength).quot; // ---Â Number of messages in microslice auto msSize = msDescr.size; @@ -60,7 +61,7 @@ namespace cbm::algo result.second.fNumErrInvalidFirstMessage++; return result; } - ProcessTsmsbMessage(message[1]); + ProcessTsmsbMessage(message[1], time); // --- Message loop for (uint32_t messageNr = 2; messageNr < numMessages; messageNr++) { @@ -69,11 +70,11 @@ namespace cbm::algo switch (message[messageNr].GetMessType()) { case stsxyter::MessType::Hit: { - ProcessHitMessage(message[messageNr], result.first, result.second); + ProcessHitMessage(message[messageNr], time, result.first, result.second); break; } case stsxyter::MessType::TsMsb: { - ProcessTsmsbMessage(message[messageNr]); + ProcessTsmsbMessage(message[messageNr], time); break; } default: { @@ -91,8 +92,8 @@ namespace cbm::algo // ----- Process hit message -------------------------------------------- - inline void UnpackSts::ProcessHitMessage(const stsxyter::Message& message, vector<CbmStsDigi>& digiVec, - UnpackStsMonitorData& monitor) const + inline void UnpackSts::ProcessHitMessage(const stsxyter::Message& message, const TimeSpec& time, + vector<CbmStsDigi>& digiVec, UnpackStsMonitorData& monitor) const { // --- Check eLink and get parameters @@ -114,7 +115,7 @@ namespace cbm::algo } // --- Expand time stamp to time within timeslice (in clock cycle) - uint64_t messageTime = message.GetHitTimeBinning() + fCurrentEpochTime; + uint64_t messageTime = message.GetHitTimeBinning() + time.currentEpochTime; // --- Convert time stamp from clock cycles to ns. Round to nearest full ns. messageTime = (messageTime * fkClockCycleNom + fkClockCycleDen / 2) / fkClockCycleDen; @@ -143,7 +144,7 @@ namespace cbm::algo // ----- Process an epoch (TS_MSB) message ------------------------------ - inline void UnpackSts::ProcessTsmsbMessage(const stsxyter::Message& message) + inline void UnpackSts::ProcessTsmsbMessage(const stsxyter::Message& message, TimeSpec& time) const { // The compression of time is based on the hierarchy epoch cycle - epoch - message time. // Cycles are counted from the start of Unix time and are multiples of an epoch (ts_msb). @@ -156,13 +157,13 @@ namespace cbm::algo auto epoch = message.GetTsMsbValBinning(); // --- Cycle wrap - if (epoch < fCurrentEpoch) fCurrentCycle++; + if (epoch < time.currentEpoch) time.currentCycle++; // --- Update current epoch counter - fCurrentEpoch = epoch; + time.currentEpoch = epoch; // --- Calculate epoch time in clocks cycles relative to timeslice start time - fCurrentEpochTime = (fCurrentCycle * fkEpochsPerCycle + epoch - fCurrentTsTime) * fkEpochLength; + time.currentEpochTime = (time.currentCycle * fkEpochsPerCycle + epoch - time.currentTsTime) * fkEpochLength; } // -------------------------------------------------------------------------- diff --git a/algo/detectors/sts/UnpackSts.h b/algo/detectors/sts/UnpackSts.h index 8378c418c3..31cad3bf1f 100644 --- a/algo/detectors/sts/UnpackSts.h +++ b/algo/detectors/sts/UnpackSts.h @@ -5,7 +5,6 @@ #ifndef CBM_ALGO_UNPACKSTS_H #define CBM_ALGO_UNPACKSTS_H 1 - #include "CbmStsDigi.h" #include "MicrosliceDescriptor.hpp" @@ -17,6 +16,7 @@ #include <memory> #include <vector> +#include "Prelude.h" #include "StsXyterMessage.h" namespace cbm::algo @@ -103,13 +103,23 @@ 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<UnpackStsPar> params) { fParams = *(std::move(params)); } + private: // types + /** + * @brief Structure to hold the current time information for the current microslice + */ + struct TimeSpec { + u64 currentTsTime = 0; ///< Unix time of timeslice in units of epoch length + u64 currentCycle = 0; ///< Current epoch cycle + u32 currentEpoch = 0; ///< Current epoch number within epoch cycle + u64 currentEpochTime = 0; ///< Current epoch time relative to timeslice in clock cycles + }; private: // methods /** @brief Process a hit message @@ -117,20 +127,16 @@ namespace cbm::algo ** @param digiVec Vector to append the created digi to ** @param monitor Reference to monitor object **/ - void ProcessHitMessage(const stsxyter::Message& message, std::vector<CbmStsDigi>& digiVec, + void ProcessHitMessage(const stsxyter::Message& message, const TimeSpec& time, std::vector<CbmStsDigi>& digiVec, UnpackStsMonitorData& monitor) const; /** @brief Process an epoch message (TS_MSB) ** @param message SMX message (32-bit word) **/ - void ProcessTsmsbMessage(const stsxyter::Message& message); + void ProcessTsmsbMessage(const stsxyter::Message& message, TimeSpec& time) const; private: // members - uint64_t fCurrentTsTime = 0; ///< Unix time of timeslice in units of epoch length - uint64_t fCurrentCycle = 0; ///< Current epoch cycle - uint32_t fCurrentEpoch = 0; ///< Current epoch number within epoch cycle - uint64_t fCurrentEpochTime = 0; ///< Current epoch time relative to timeslice in clock cycles UnpackStsPar fParams = {}; ///< Parameter container /** Number of TS_MSB epochs per cycle **/ -- GitLab