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::GetAtSlot",
"Maximum number of slots reached.");
138 auto objPointer = fObjPointers[i];
141 fObjPointers[i] = objPointer;
158 return fObjPointers[i];
178 return GetAtSlot(GetThisSlotNumber());
194 Warning(
"TThreadedObject::Merge",
"This object was already merged. Returning the previous result.");
195 return fObjPointers[0];
197 mergeFunction(fObjPointers[0], fObjPointers);
199 return fObjPointers[0];
209 Warning(
"TThreadedObject::SnapshotMerge",
"This object was already merged. Returning the previous result.");
213 std::shared_ptr<T> targetPtrShared(targetPtr, [](
T *) {});
214 mergeFunction(targetPtrShared, fObjPointers);
215 return std::unique_ptr<T>(targetPtr);
223 unsigned fCurrMaxSlotIndex = 0;
224 bool fIsMerged =
false;
230 const auto thisThreadID = std::this_thread::get_id();
233 std::lock_guard<ROOT::TSpinMutex> lg(fThrIDSlotMutex);
234 auto thisSlotNumIt = fThrIDSlotMap.find(thisThreadID);
235 if (thisSlotNumIt != fThrIDSlotMap.end())
return thisSlotNumIt->second;
236 thisIndex = fCurrMaxSlotIndex++;
237 fThrIDSlotMap[thisThreadID] = thisIndex;
257 auto model = ((std::unique_ptr<T>*)(val))->
get();
258 std::ostringstream ret;
259 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.
Namespace for new ROOT classes and functions.
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.
void SetAtSlot(unsigned i, std::shared_ptr< T > v)
Set the value of a particular 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.