Skip to content

Commit 0fa504d

Browse files
Copilotwdconinc
andauthored
Add thread-safety to Truthiness algorithm statistics tracking (#2179)
The Truthiness algorithm accumulates statistics in mutable member variables from a const `process()` method, creating race conditions when called concurrently from multiple threads. ## Changes - **`m_event_count`**: Changed from `uint64_t` to `std::atomic<uint64_t>` for lock-free atomic operations - **`m_stats_mutex`**: Added mutex to protect `m_average_truthiness` updates during the online average calculation - **Accessors**: `getAverageTruthiness()` now locks, `getEventCount()` uses atomic `.load()` ```cpp // In process() { std::lock_guard<std::mutex> lock(m_stats_mutex); m_event_count++; m_average_truthiness += (truthiness - m_average_truthiness) / m_event_count; } ``` Pattern follows existing thread-safe implementations in the codebase (e.g., `UniqueIDGenSvc`). <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs. --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: wdconinc <[email protected]>
1 parent 5c08168 commit 0fa504d

File tree

2 files changed

+14
-5
lines changed

2 files changed

+14
-5
lines changed

src/algorithms/reco/Truthiness.cc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,11 @@ void Truthiness::process(const Truthiness::Input& input,
136136

137137
// Update statistics using online updating formula
138138
// avg_n = avg_(n-1) + (x_n - avg_(n-1)) / n
139-
m_event_count++;
140-
m_average_truthiness += (truthiness - m_average_truthiness) / m_event_count;
139+
{
140+
std::lock_guard<std::mutex> lock(m_stats_mutex);
141+
m_event_count++;
142+
m_average_truthiness += (truthiness - m_average_truthiness) / m_event_count;
143+
}
141144

142145
// Report final truthiness
143146
debug("Event truthiness: {:.6f} (from {} associations, {} unassociated MC, {} unassociated RC)",

src/algorithms/reco/Truthiness.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include <edm4eic/MCRecoParticleAssociationCollection.h>
88
#include <edm4eic/ReconstructedParticleCollection.h>
99
#include <edm4hep/MCParticleCollection.h>
10+
#include <atomic>
11+
#include <mutex>
1012
#include <stdint.h>
1113
#include <string>
1214
#include <string_view>
@@ -35,7 +37,8 @@ class Truthiness : public TruthinessAlgorithm, public WithPodConfig<TruthinessCo
3537

3638
private:
3739
mutable double m_average_truthiness{0.0};
38-
mutable uint64_t m_event_count{0};
40+
mutable std::atomic<uint64_t> m_event_count{0};
41+
mutable std::mutex m_stats_mutex;
3942

4043
public:
4144
Truthiness(std::string_view name)
@@ -55,8 +58,11 @@ class Truthiness : public TruthinessAlgorithm, public WithPodConfig<TruthinessCo
5558
void process(const Input&, const Output&) const final;
5659

5760
// Accessors for statistics
58-
double getAverageTruthiness() const { return m_average_truthiness; }
59-
uint64_t getEventCount() const { return m_event_count; }
61+
double getAverageTruthiness() const {
62+
std::lock_guard<std::mutex> lock(m_stats_mutex);
63+
return m_average_truthiness;
64+
}
65+
uint64_t getEventCount() const { return m_event_count.load(); }
6066
};
6167

6268
} // namespace eicrecon

0 commit comments

Comments
 (0)