Skip to content

Commit ec4c3ff

Browse files
committed
[DF] TSlotStack uses local maps indexed with thread ids rather than thread local
this prevents bogus behaviour if two instances of TSlotStack are used simultaneously or even one after the other.
1 parent 5af33f8 commit ec4c3ff

File tree

2 files changed

+41
-15
lines changed

2 files changed

+41
-15
lines changed

tree/dataframe/inc/ROOT/RDFNodes.hxx

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#include "ROOT/RDFUtils.hxx"
1818
#include "ROOT/RIntegerSequence.hxx"
1919
#include "ROOT/RVec.hxx"
20-
#include "ROOT/TSpinMutex.hxx"
20+
#include "ROOT/TRWSpinLock.hxx"
2121
#include "ROOT/TypeTraits.hxx"
2222
#include "TError.h"
2323
#include "TTreeReaderArray.h"
@@ -30,6 +30,7 @@
3030
#include <numeric> // std::accumulate (FillReport), std::iota (TSlotStack)
3131
#include <stack>
3232
#include <string>
33+
#include <thread>
3334
#include <tuple>
3435
#include <vector>
3536

@@ -38,31 +39,25 @@ namespace Internal {
3839
namespace RDF {
3940
class RActionBase;
4041

41-
// This is an helper class to allow to pick a slot without resorting to a map
42+
// This is an helper class to allow to pick a slot resorting to a map
4243
// indexed by thread ids.
4344
// WARNING: this class does not work as a regular stack. The size is
4445
// fixed at construction time and no blocking is foreseen.
4546
class TSlotStack {
4647
private:
47-
unsigned int &GetCount()
48-
{
49-
TTHREAD_TLS(unsigned int) count = 0U;
50-
return count;
51-
}
52-
unsigned int &GetIndex()
53-
{
54-
TTHREAD_TLS(unsigned int) index = std::numeric_limits<unsigned int>::max();
55-
return index;
56-
}
48+
unsigned int &GetCount();
49+
unsigned int &GetIndex();
5750
unsigned int fCursor;
5851
std::vector<unsigned int> fBuf;
59-
ROOT::TSpinMutex fMutex;
52+
ROOT::TRWSpinLock fRWLock;
6053

6154
public:
6255
TSlotStack() = delete;
6356
TSlotStack(unsigned int size) : fCursor(size), fBuf(size) { std::iota(fBuf.begin(), fBuf.end(), 0U); }
6457
void ReturnSlot(unsigned int slotNumber);
6558
unsigned int GetSlot();
59+
std::map<std::thread::id, unsigned int> fCountMap;
60+
std::map<std::thread::id, unsigned int> fIndexMap;
6661
};
6762
} // ns RDF
6863
} // ns Internal

tree/dataframe/src/RDFNodes.cxx

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,37 @@ void RJittedFilter::InitNode()
209209
fConcreteFilter->InitNode();
210210
}
211211

212+
unsigned int &TSlotStack::GetCount()
213+
{
214+
const auto tid = std::this_thread::get_id();
215+
{
216+
ROOT::TRWSpinLockReadGuard rg(fRWLock);
217+
auto it = fCountMap.find(tid);
218+
if (fCountMap.end() != it)
219+
return it->second;
220+
}
221+
222+
{
223+
ROOT::TRWSpinLockWriteGuard rg(fRWLock);
224+
return (fCountMap[tid] = 0U);
225+
}
226+
}
227+
unsigned int &TSlotStack::GetIndex()
228+
{
229+
const auto tid = std::this_thread::get_id();
230+
231+
{
232+
ROOT::TRWSpinLockReadGuard rg(fRWLock);
233+
if (fIndexMap.end() != fIndexMap.find(tid))
234+
return fIndexMap[tid];
235+
}
236+
237+
{
238+
ROOT::TRWSpinLockWriteGuard rg(fRWLock);
239+
return (fIndexMap[tid] = std::numeric_limits<unsigned int>::max());
240+
}
241+
}
242+
212243
void TSlotStack::ReturnSlot(unsigned int slotNumber)
213244
{
214245
auto &index = GetIndex();
@@ -217,7 +248,7 @@ void TSlotStack::ReturnSlot(unsigned int slotNumber)
217248
count--;
218249
if (0U == count) {
219250
index = std::numeric_limits<unsigned int>::max();
220-
std::lock_guard<ROOT::TSpinMutex> guard(fMutex);
251+
ROOT::TRWSpinLockWriteGuard guard(fRWLock);
221252
fBuf[fCursor++] = slotNumber;
222253
R__ASSERT(fCursor <= fBuf.size() &&
223254
"TSlotStack assumes that at most a fixed number of values can be present in the "
@@ -233,7 +264,7 @@ unsigned int TSlotStack::GetSlot()
233264
count++;
234265
if (std::numeric_limits<unsigned int>::max() != index)
235266
return index;
236-
std::lock_guard<ROOT::TSpinMutex> guard(fMutex);
267+
ROOT::TRWSpinLockWriteGuard guard(fRWLock);
237268
R__ASSERT(fCursor > 0 &&
238269
"TSlotStack assumes that a value can be always obtained. In this case fCursor is <=0 and this "
239270
"violates such assumption.");

0 commit comments

Comments
 (0)