12 #ifndef ROOT_TThreadedObject 13 #define ROOT_TThreadedObject 33 namespace TThreadedObjectUtils {
37 static unsigned fgTThreadedObjectIndex = 0;
38 return fgTThreadedObjectIndex++;
42 template<class T, bool isCopyConstructible = std::is_copy_constructible<T>::value>
62 clone = (
T*)obj->Clone();
64 clone = (
T*)obj->Clone();
73 namespace TThreadedObjectUtils {
76 using MergeFunctionType = std::function<void(std::shared_ptr<T>, std::vector<std::shared_ptr<T>>&)>;
79 void MergeTObjects(std::shared_ptr<T> target, std::vector<std::shared_ptr<T>> &objs)
84 for (
auto obj : objs) {
85 if (obj && obj != target) objTList.
Add(obj.get());
87 target->Merge(&objTList);
114 template<
class ...ARGS>
117 fDirectories.reserve(fgMaxSlots);
119 std::string dirName =
"__TThreaded_dir_";
121 for (
unsigned i=0; i< fgMaxSlots;++i) {
122 fDirectories.emplace_back(
gROOT->mkdir((dirName+std::to_string(i)).c_str()));
126 fModel.reset(
new T(std::forward<ARGS>(args)...));
134 if ( i >= fObjPointers.size()) {
135 Warning(
"TThreadedObject::Merge",
"Maximum number of slots reached.");
138 auto objPointer = fObjPointers[i];
141 fObjPointers[i] = objPointer;
152 return fObjPointers[i];
172 return GetAtSlot(GetThisSlotNumber());
188 Warning(
"TThreadedObject::Merge",
"This object was already merged. Returning the previous result.");
189 return fObjPointers[0];
191 mergeFunction(fObjPointers[0], fObjPointers);
193 return fObjPointers[0];
203 Warning(
"TThreadedObject::SnapshotMerge",
"This object was already merged. Returning the previous result.");
207 std::shared_ptr<T> targetPtrShared(targetPtr, [](
T *) {});
208 mergeFunction(targetPtrShared, fObjPointers);
209 return std::unique_ptr<T>(targetPtr);
217 unsigned fCurrMaxSlotIndex = 0;
218 bool fIsMerged =
false;
224 const auto thisThreadID = std::this_thread::get_id();
227 std::lock_guard<ROOT::TSpinMutex> lg(fThrIDSlotMutex);
228 auto thisSlotNumIt = fThrIDSlotMap.find(thisThreadID);
229 if (thisSlotNumIt != fThrIDSlotMap.end())
return thisSlotNumIt->second;
230 thisIndex = fCurrMaxSlotIndex++;
231 fThrIDSlotMap[thisThreadID] = thisIndex;
251 auto model = ((std::unique_ptr<T>*)(val))->
get();
252 std::ostringstream ret;
253 ret <<
"A wrapper to make object instances thread private, lazily. " std::shared_ptr< T > GetAtSlotUnchecked(unsigned i) const
Access a particular slot which corresponds to a single thread.
T * operator->()
Access the wrapped object and allow to call its methods.
This namespace contains pre-defined functions to be used in conjuction with TExecutor::Map and TExecu...
A wrapper to make object instances thread private, lazily.
std::string printValue(ROOT::TThreadedObject< T > *val)
A spin mutex class which respects the STL interface for mutexes.
std::unique_ptr< T > fModel
Use to store a "model" of the object.
std::shared_ptr< T > Get()
Access the pointer corresponding to the current slot.
std::vector< std::shared_ptr< T > > fObjPointers
A pointer per thread is kept.
std::map< std::thread::id, unsigned > fThrIDSlotMap
A mapping between the thread IDs and the slots.
unsigned GetThisSlotNumber()
Get the slot number for this threadID.
static unsigned fgMaxSlots
The maximum number of processing slots (distinct threads) which the instances can manage...
std::shared_ptr< T > GetAtSlot(unsigned i)
Access a particular processing slot.
void Warning(const char *location, const char *msgfmt,...)
void MergeTObjects(std::shared_ptr< T > target, std::vector< std::shared_ptr< T >> &objs)
Merge TObjects.
static T * Clone(const T *obj, TDirectory *d=nullptr)
Describe directory structure in memory.
Print a TSeq at the prompt:
std::shared_ptr< T > Merge(TThreadedObjectUtils::MergeFunctionType< T > mergeFunction=TThreadedObjectUtils::MergeTObjects< T >)
Merge all the thread private objects.
std::vector< TDirectory * > fDirectories
A TDirectory per thread is kept.
ROOT::TSpinMutex fThrIDSlotMutex
Mutex to protect the ID-slot map access.
std::function< void(std::shared_ptr< T >, std::vector< std::shared_ptr< T > > &)> MergeFunctionType
virtual void Add(TObject *obj)
static T * Clone(const T *obj, TDirectory *d=nullptr)
unsigned GetTThreadedObjectIndex()
Get the unique index identifying a TThreadedObject.
TThreadedObject(ARGS &&... args)
Construct the TThreaded object and the "model" of the thread private objects.
Return a copy of the object or a "Clone" if the copy constructor is not implemented.
std::unique_ptr< T > SnapshotMerge(TThreadedObjectUtils::MergeFunctionType< T > mergeFunction=TThreadedObjectUtils::MergeTObjects< T >)
Merge all the thread private objects.