Skip to content

Commit 5f6b5b7

Browse files
sawenzelclaude
andcommitted
Use std::threads instead of TBB tasks in the o2-sim hit merger
This fixes a crash of the o2-sim hit merger at the end of a run. - The concurrent flush of kinematics and detector files used a tbb::task_group and tbb::parallel_for_each. - It runs on a merger IO thread that is created anew for every merge batch. - When such a thread exits, TBB releases its thread pool and can segfault in pthread_detach. - The flush now uses std::threads that are joined before the function returns. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
1 parent 140d0e9 commit 5f6b5b7

1 file changed

Lines changed: 15 additions & 7 deletions

File tree

‎run/O2HitMerger.cxx‎

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,7 @@
8484
#endif
8585

8686
#include <tbb/concurrent_unordered_map.h>
87-
#include <tbb/parallel_for_each.h>
88-
#include <tbb/task_group.h>
87+
#include <thread>
8988

9089
namespace o2
9190
{
@@ -767,8 +766,9 @@ bool O2HitMerger::mergeAndFlushData()
767766
eventheader->putInfo("prims_total", prims);
768767
};
769768
// the kinematics and each detector go to separate files, so we merge and flush them concurrently
770-
tbb::task_group tasks;
771-
tasks.run([&]() {
769+
// plain threads, since the TBB pool teardown crashed the merger
770+
std::vector<std::thread> tasks;
771+
tasks.emplace_back([&]() {
772772
reorderAndMergeMCTracks(flusheventID, mOutTree, nprimaries, subevOrdered, mcheaderhook, eventheader);
773773

774774
if (mOutTree) {
@@ -796,13 +796,15 @@ bool O2HitMerger::mergeAndFlushData()
796796
auto& det = mDetectorInstances[id];
797797
auto hittree = det ? mDetectorToTTreeMap[id] : nullptr;
798798
if (hittree) {
799-
tasks.run([&, det = det.get(), hittree]() {
799+
tasks.emplace_back([&, det = det.get(), hittree]() {
800800
det->mergeHitEntriesAndFlush(flusheventID, *hittree, trackoffsets, nprimaries, subevOrdered);
801801
hittree->SetEntries(hittree->GetEntries() + 1);
802802
});
803803
}
804804
}
805-
tasks.wait();
805+
for (auto& t : tasks) {
806+
t.join();
807+
}
806808

807809
cleanEvent(flusheventID);
808810
LOG(info) << "Merge/flush for event " << flusheventID << " took " << timer.RealTime();
@@ -815,7 +817,13 @@ bool O2HitMerger::mergeAndFlushData()
815817
files.push_back(mDetectorOutFiles[id]);
816818
}
817819
}
818-
tbb::parallel_for_each(files, [](TFile* file) { file->Write("", TObject::kOverwrite); });
820+
std::vector<std::thread> writers;
821+
for (auto file : files) {
822+
writers.emplace_back([file]() { file->Write("", TObject::kOverwrite); });
823+
}
824+
for (auto& t : writers) {
825+
t.join();
826+
}
819827
}
820828
return true;
821829
}

0 commit comments

Comments
 (0)