Skip to content

Commit 6c8b77d

Browse files
bendavidpcanal
authored andcommitted
add TBB based RWMutex classes and use by default when TBB is available
1 parent a540a18 commit 6c8b77d

File tree

5 files changed

+149
-1
lines changed

5 files changed

+149
-1
lines changed

core/thread/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,12 @@ target_include_directories(Thread PRIVATE
8181
set_source_files_properties(src/RConcurrentHashColl.cxx
8282
PROPERTIES COMPILE_FLAGS -I${CMAKE_SOURCE_DIR}/core/foundation/res)
8383

84+
if (tbb OR builtin_tbb)
85+
target_include_directories(Thread SYSTEM PRIVATE ${TBB_INCLUDE_DIRS})
86+
target_link_libraries(Thread PRIVATE ${TBB_LIBRARIES})
87+
set_target_properties(Thread PROPERTIES COMPILE_FLAGS "${TBB_CXXFLAGS}")
88+
endif()
89+
8490
if(WIN32)
8591
target_sources(Thread PRIVATE
8692
src/TWin32Condition.cxx

core/thread/inc/ROOT/TReentrantRWLock.hxx

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222
#include <thread>
2323
#include <unordered_map>
2424

25+
#ifdef R__HAS_TBB
26+
#include "tbb/enumerable_thread_specific.h"
27+
#endif
28+
2529
namespace ROOT {
2630
namespace Internal {
2731
struct UniqueLockRecurseCount {
@@ -147,6 +151,127 @@ struct RecurseCounts {
147151

148152

149153
};
154+
155+
#ifdef R__HAS_TBB
156+
struct RecurseCountsTBB {
157+
using Hint_t = TVirtualRWMutex::Hint_t;
158+
159+
struct LocalCounts {
160+
size_t fReadersCount = 0;
161+
bool fIsWriter = false;
162+
};
163+
tbb::enumerable_thread_specific<LocalCounts> fLocalCounts;
164+
size_t fWriteRecurse = 0; ///<! Number of re-entry in the lock by the same thread.
165+
166+
using local_t = LocalCounts*;
167+
168+
local_t GetLocal(){
169+
return &fLocalCounts.local();
170+
}
171+
172+
Hint_t *IncrementReadCount(local_t &local) {
173+
++(local->fReadersCount);
174+
return reinterpret_cast<TVirtualRWMutex::Hint_t *>(&(local->fReadersCount));
175+
}
176+
177+
template <typename MutexT>
178+
Hint_t *IncrementReadCount(local_t &local, MutexT &) {
179+
return IncrementReadCount(local);
180+
}
181+
182+
Hint_t *DecrementReadCount(local_t &local) {
183+
--(local->fReadersCount);
184+
return reinterpret_cast<TVirtualRWMutex::Hint_t *>(&(local->fReadersCount));
185+
}
186+
187+
template <typename MutexT>
188+
Hint_t *DecrementReadCount(local_t &local, MutexT &) {
189+
return DecrementReadCount(local);
190+
}
191+
192+
void ResetReadCount(local_t &local, int newvalue) {
193+
local->fReadersCount = newvalue;
194+
}
195+
196+
bool IsCurrentWriter(local_t &local) { return local->fIsWriter; }
197+
bool IsNotCurrentWriter(local_t &local) { return !local->fIsWriter; }
198+
199+
void SetIsWriter(local_t &local)
200+
{
201+
// if (fWriteRecurse == std::numeric_limits<decltype(fWriteRecurse)>::max()) {
202+
// ::Fatal("TRWSpinLock::WriteLock", "Too many recursions in TRWSpinLock!");
203+
// }
204+
++fWriteRecurse;
205+
local->fIsWriter = true;
206+
}
207+
208+
void DecrementWriteCount() { --fWriteRecurse; }
209+
210+
void ResetIsWriter(local_t &local) { local->fIsWriter = false; }
211+
212+
size_t &GetLocalReadersCount(local_t &local) { return local->fReadersCount; }
213+
};
214+
215+
struct RecurseCountsTBBUnique {
216+
using Hint_t = TVirtualRWMutex::Hint_t;
217+
218+
struct LocalCounts {
219+
size_t fReadersCount = 0;
220+
bool fIsWriter = false;
221+
};
222+
tbb::enumerable_thread_specific<LocalCounts, tbb::cache_aligned_allocator<LocalCounts>, tbb::ets_key_per_instance> fLocalCounts;
223+
size_t fWriteRecurse = 0; ///<! Number of re-entry in the lock by the same thread.
224+
225+
using local_t = LocalCounts*;
226+
227+
local_t GetLocal(){
228+
return &fLocalCounts.local();
229+
}
230+
231+
Hint_t *IncrementReadCount(local_t &local) {
232+
++(local->fReadersCount);
233+
return reinterpret_cast<TVirtualRWMutex::Hint_t *>(&(local->fReadersCount));
234+
}
235+
236+
template <typename MutexT>
237+
Hint_t *IncrementReadCount(local_t &local, MutexT &) {
238+
return IncrementReadCount(local);
239+
}
240+
241+
Hint_t *DecrementReadCount(local_t &local) {
242+
--(local->fReadersCount);
243+
return reinterpret_cast<TVirtualRWMutex::Hint_t *>(&(local->fReadersCount));
244+
}
245+
246+
template <typename MutexT>
247+
Hint_t *DecrementReadCount(local_t &local, MutexT &) {
248+
return DecrementReadCount(local);
249+
}
250+
251+
void ResetReadCount(local_t &local, int newvalue) {
252+
local->fReadersCount = newvalue;
253+
}
254+
255+
bool IsCurrentWriter(local_t &local) { return local->fIsWriter; }
256+
bool IsNotCurrentWriter(local_t &local) { return !local->fIsWriter; }
257+
258+
void SetIsWriter(local_t &local)
259+
{
260+
// if (fWriteRecurse == std::numeric_limits<decltype(fWriteRecurse)>::max()) {
261+
// ::Fatal("TRWSpinLock::WriteLock", "Too many recursions in TRWSpinLock!");
262+
// }
263+
++fWriteRecurse;
264+
local->fIsWriter = true;
265+
}
266+
267+
void DecrementWriteCount() { --fWriteRecurse; }
268+
269+
void ResetIsWriter(local_t &local) { local->fIsWriter = false; }
270+
271+
size_t &GetLocalReadersCount(local_t &local) { return local->fReadersCount; }
272+
};
273+
#endif
274+
150275
} // Internal
151276

152277
template <typename MutexT = ROOT::TSpinMutex, typename RecurseCountsT = Internal::RecurseCounts>

core/thread/src/TRWMutexImp.cxx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,9 @@ template class TRWMutexImp<std::mutex>;
114114
template class TRWMutexImp<TMutex, ROOT::Internal::UniqueLockRecurseCount>;
115115
template class TRWMutexImp<ROOT::TSpinMutex, ROOT::Internal::UniqueLockRecurseCount>;
116116

117-
} // End of namespace ROOT
117+
#ifdef R__HAS_TBB
118+
template class TRWMutexImp<std::mutex, ROOT::Internal::RecurseCountsTBB>;
119+
template class TRWMutexImp<std::mutex, ROOT::Internal::RecurseCountsTBBUnique>;
120+
#endif
121+
122+
} // End of namespace ROOT

core/thread/src/TReentrantRWLock.cxx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,4 +413,10 @@ template class TReentrantRWLock<std::mutex, ROOT::Internal::RecurseCounts>;
413413
template class TReentrantRWLock<ROOT::TSpinMutex, ROOT::Internal::UniqueLockRecurseCount>;
414414
template class TReentrantRWLock<TMutex, ROOT::Internal::UniqueLockRecurseCount>;
415415
template class TReentrantRWLock<std::mutex, ROOT::Internal::UniqueLockRecurseCount>;
416+
417+
#ifdef R__HAS_TBB
418+
template class TReentrantRWLock<std::mutex, ROOT::Internal::RecurseCountsTBB>;
419+
template class TReentrantRWLock<std::mutex, ROOT::Internal::RecurseCountsTBBUnique>;
420+
#endif
421+
416422
}

core/thread/src/TThread.cxx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,13 @@ void TThread::Init()
352352
if (!ROOT::gCoreMutex) {
353353
// To avoid dead locks, caused by shared library opening and/or static initialization
354354
// taking the same lock as 'tls_get_addr_tail', we can not use UniqueLockRecurseCount.
355+
#ifdef R__HAS_TBB
356+
printf("using RecurseCountsTBBUnique\n");
357+
ROOT::gCoreMutex = new ROOT::TRWMutexImp<std::mutex, ROOT::Internal::RecurseCountsTBBUnique>();
358+
#else
359+
printf("using RecurseCounts\n");
355360
ROOT::gCoreMutex = new ROOT::TRWMutexImp<std::mutex, ROOT::Internal::RecurseCounts>();
361+
#endif
356362
}
357363
gInterpreterMutex = ROOT::gCoreMutex;
358364
gROOTMutex = gInterpreterMutex;

0 commit comments

Comments
 (0)