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. " 254 <<
"The model which is replicated is " <<
printValue(model);
TThreadedObject(ARGS...args)
Construct the TThreaded object and the "model" of the thread private objects.
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::shared_ptr< T > GetAtSlotUnchecked(unsigned i) const
Access a particular slot which corresponds to a single thread.
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.
std::function< void(std::shared_ptr< T >, std::vector< std::shared_ptr< T >> &)> MergeFunctionType
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.
virtual void Add(TObject *obj)
static T * Clone(const T *obj, TDirectory *d=nullptr)
unsigned GetTThreadedObjectIndex()
Get the unique index identifying a TThreadedObject.
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.