Skip to content

Commit f085736

Browse files
sawenzelclaude
andcommitted
Make the shared-memory hit-buffer busy flag atomic
This makes the flag that guards a hit buffer between a sim worker and the hit merger safe across processes. - The flag was a plain bool in shared memory, written by the merger and polled by the worker. - Without atomic semantics its stores may become visible out of order with the buffer reads, notably on aarch64. - It is now a std::atomic<bool> (ShmBusyFlag) placed in the segment. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 43df410 commit f085736

2 files changed

Lines changed: 15 additions & 12 deletions

File tree

‎Detectors/Base/include/DetectorsBase/Detector.h‎

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "CommonUtils/ShmManager.h"
3333
#include "CommonUtils/ShmAllocator.h"
3434
#include <sys/shm.h>
35+
#include <atomic>
3536
#include <type_traits>
3637
#include <unistd.h>
3738
#include <cassert>
@@ -269,11 +270,14 @@ inline std::string demangle(const char* name)
269270
return (status == 0) ? res.get() : name;
270271
}
271272

272-
void attachShmMessage(void* hitsptr, fair::mq::Channel& channel, fair::mq::Parts& parts, bool* busy_ptr);
273-
void* decodeShmCore(fair::mq::Parts& dataparts, int index, bool*& busy);
273+
// a flag in shared memory telling whether the hit merger still reads a hit buffer
274+
using ShmBusyFlag = std::atomic<bool>;
275+
276+
void attachShmMessage(void* hitsptr, fair::mq::Channel& channel, fair::mq::Parts& parts, ShmBusyFlag* busy_ptr);
277+
void* decodeShmCore(fair::mq::Parts& dataparts, int index, ShmBusyFlag*& busy);
274278

275279
template <typename T>
276-
T decodeShmMessage(fair::mq::Parts& dataparts, int index, bool*& busy)
280+
T decodeShmMessage(fair::mq::Parts& dataparts, int index, ShmBusyFlag*& busy)
277281
{
278282
return reinterpret_cast<T>(decodeShmCore(dataparts, index, busy));
279283
}
@@ -553,7 +557,7 @@ class DetImpl : public o2::base::Detector
553557
mHitCollectorBufferPtr = (char*)&hitcollector;
554558

555559
int probe = 0;
556-
bool* busy = nullptr;
560+
ShmBusyFlag* busy = nullptr;
557561
using HitPtr_t = decltype(static_cast<Det*>(this)->Det::getHits(probe));
558562
std::string name = static_cast<Det*>(this)->getHitBranchNames(probe);
559563

@@ -606,7 +610,7 @@ class DetImpl : public o2::base::Detector
606610
void fillHitBranch(TTree& tr, fair::mq::Parts& parts, int& index) override
607611
{
608612
int probe = 0;
609-
bool* busy = nullptr;
613+
ShmBusyFlag* busy = nullptr;
610614
using Hit_t = decltype(static_cast<Det*>(this)->Det::getHits(probe));
611615
std::string name = static_cast<Det*>(this)->getHitBranchNames(probe++);
612616
while (name.size() > 0) {
@@ -697,8 +701,7 @@ class DetImpl : public o2::base::Detector
697701
static_cast<Det*>(this)->Det::createHitBuffers();
698702
for (int b = 0; b < NHITBUFFERS; ++b) {
699703
auto& instance = o2::utils::ShmManager::Instance();
700-
mShmBusy[b] = instance.hasSegment() ? (bool*)instance.getmemblock(sizeof(bool)) : new bool;
701-
*mShmBusy[b] = false;
704+
mShmBusy[b] = instance.hasSegment() ? new (instance.getmemblock(sizeof(ShmBusyFlag))) ShmBusyFlag(false) : new ShmBusyFlag(false);
702705
}
703706
}
704707
mInitialized = true;
@@ -749,7 +752,7 @@ class DetImpl : public o2::base::Detector
749752
static constexpr int NHITBUFFERS = 3; // number of buffers for hits in order to allow async processing
750753
// in the hit merger without blocking nor copying the data
751754
// (like done in typical data aquisition systems)
752-
bool* mShmBusy[NHITBUFFERS] = {nullptr}; //! pointer to bool in shared mem indicating of IO busy
755+
ShmBusyFlag* mShmBusy[NHITBUFFERS] = {nullptr}; //! pointer to flag in shared mem indicating of IO busy
753756
std::vector<void*> mCachedPtr[NHITBUFFERS];
754757
int mCurrentBuffer = 0; // holding the current buffer information
755758
int mInitialized = false;

‎Detectors/Base/src/Detector.cxx‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,12 +220,12 @@ void attachDetIDHeaderMessage(int id, fair::mq::Channel& channel, fair::mq::Part
220220
std::unique_ptr<fair::mq::Message> message(channel.NewSimpleMessage(id));
221221
parts.AddPart(std::move(message));
222222
}
223-
void attachShmMessage(void* hits_ptr, fair::mq::Channel& channel, fair::mq::Parts& parts, bool* busy_ptr)
223+
void attachShmMessage(void* hits_ptr, fair::mq::Channel& channel, fair::mq::Parts& parts, ShmBusyFlag* busy_ptr)
224224
{
225225
struct shmcontext {
226226
int id;
227227
void* object_ptr;
228-
bool* busy_ptr;
228+
ShmBusyFlag* busy_ptr;
229229
};
230230

231231
auto& instance = o2::utils::ShmManager::Instance();
@@ -237,13 +237,13 @@ void attachShmMessage(void* hits_ptr, fair::mq::Channel& channel, fair::mq::Part
237237
std::unique_ptr<fair::mq::Message> message(channel.NewSimpleMessage(info));
238238
parts.AddPart(std::move(message));
239239
}
240-
void* decodeShmCore(fair::mq::Parts& dataparts, int index, bool*& busy)
240+
void* decodeShmCore(fair::mq::Parts& dataparts, int index, ShmBusyFlag*& busy)
241241
{
242242
auto rawmessage = std::move(dataparts.At(index));
243243
struct shmcontext {
244244
int id;
245245
void* object_ptr;
246-
bool* busy_ptr;
246+
ShmBusyFlag* busy_ptr;
247247
};
248248

249249
shmcontext* info = (shmcontext*)rawmessage->GetData();

0 commit comments

Comments
 (0)