12#ifndef ROOT_TThreadedObject
13#define ROOT_TThreadedObject
35 namespace TThreadedObjectUtils {
39 static unsigned fgTThreadedObjectIndex = 0;
40 return fgTThreadedObjectIndex++;
43 template<typename T, bool ISHISTO = std::is_base_of<TH1,T>::value>
53 obj->SetDirectory(
nullptr);
60 template<class T, bool isCopyConstructible = std::is_copy_constructible<T>::value>
80 clone = (
T*)obj->Clone();
82 clone = (
T*)obj->Clone();
88 template<class T, bool ISHISTO = std::is_base_of<TH1,T>::value>
90 static std::vector<TDirectory*>
Create(
unsigned maxSlots) {
91 std::string dirName =
"__TThreaded_dir_";
93 std::vector<TDirectory*> dirs;
94 dirs.reserve(maxSlots);
95 for (
unsigned i=0; i< maxSlots;++i) {
96 auto dir =
gROOT->mkdir((dirName+std::to_string(i)).c_str());
97 dirs.emplace_back(dir);
105 static std::vector<TDirectory*>
Create(
unsigned maxSlots) {
106 std::vector<TDirectory*> dirs(maxSlots,
nullptr);
114 namespace TThreadedObjectUtils {
120 void MergeTObjects(std::shared_ptr<T> target, std::vector<std::shared_ptr<T>> &objs)
125 for (
auto obj : objs) {
126 if (obj && obj != target) objTList.
Add(obj.get());
128 target->Merge(&objTList);
160 template<
class ...ARGS>
178 Warning(
"TThreadedObject::GetAtSlot",
"Maximum number of slots reached.");
247 Warning(
"TThreadedObject::Merge",
"This object was already merged. Returning the previous result.");
262 Warning(
"TThreadedObject::SnapshotMerge",
"This object was already merged. Returning the previous result.");
266 std::shared_ptr<T> targetPtrShared(targetPtr, [](
T *) {});
268 return std::unique_ptr<T>(targetPtr);
284 const auto thisThreadID = std::this_thread::get_id();
289 if (thisSlotNumIt !=
fThrIDSlotMap.end())
return thisSlotNumIt->second;
311 auto model = ((std::unique_ptr<T>*)(val))->get();
312 std::ostringstream ret;
313 ret <<
"A wrapper to make object instances thread private, lazily. "
314 <<
"The model which is replicated is " << printValue(model);
void Warning(const char *location, const char *msgfmt,...)
typedef void((*Func_t)())
A spin mutex class which respects the STL interface for mutexes.
A wrapper to make object instances thread private, lazily.
std::map< std::thread::id, unsigned > fThrIDSlotMap
A mapping between the thread IDs and the slots.
unsigned fMaxSlots
The size of the instance.
T * operator->()
Access the wrapped object and allow to call its methods.
void SetAtSlot(unsigned i, std::shared_ptr< T > v)
Set the value of a particular slot.
std::shared_ptr< T > Merge(TThreadedObjectUtils::MergeFunctionType< T > mergeFunction=TThreadedObjectUtils::MergeTObjects< T >)
Merge all the thread private objects.
std::shared_ptr< T > GetAtSlot(unsigned i)
Access a particular processing slot.
std::shared_ptr< T > Get()
Access the pointer corresponding to the current slot.
TThreadedObject(const TThreadedObject &)=delete
std::unique_ptr< T > fModel
Use to store a "model" of the object.
static unsigned fgMaxSlots
The maximum number of processing slots (distinct threads) which the instances can manage.
unsigned fCurrMaxSlotIndex
The maximum slot index.
std::unique_ptr< T > SnapshotMerge(TThreadedObjectUtils::MergeFunctionType< T > mergeFunction=TThreadedObjectUtils::MergeTObjects< T >)
Merge all the thread private objects.
std::shared_ptr< T > GetAtSlotUnchecked(unsigned i) const
Access a particular slot which corresponds to a single thread.
unsigned GetThisSlotNumber()
Get the slot number for this threadID.
ROOT::TSpinMutex fThrIDSlotMutex
Mutex to protect the ID-slot map access.
T * GetAtSlotRaw(unsigned i) const
Access a particular slot which corresponds to a single thread.
std::vector< TDirectory * > fDirectories
A TDirectory per thread is kept.
TThreadedObject(ARGS &&... args)
Construct the TThreaded object and the "model" of the thread private objects.
bool fIsMerged
Remember if the objects have been merged already.
std::vector< std::shared_ptr< T > > fObjPointers
A pointer per thread is kept.
Describe directory structure in memory.
virtual void Add(TObject *obj)
unsigned GetTThreadedObjectIndex()
Get the unique index identifying a TThreadedObject.
void function(const Char_t *name_, T fun, const Char_t *docstring=0)
void MergeTObjects(std::shared_ptr< T > target, std::vector< std::shared_ptr< T > > &objs)
Merge TObjects.
std::function< void(std::shared_ptr< T >, std::vector< std::shared_ptr< T > > &)> MergeFunctionType
Namespace for new ROOT classes and functions.
UInt_t GetImplicitMTPoolSize()
Returns the size of the pool used for implicit multi-threading.
static T * Clone(const T *obj, TDirectory *d=nullptr)
Return a copy of the object or a "Clone" if the copy constructor is not implemented.
static T * Clone(const T *obj, TDirectory *d=nullptr)
static T * Detach(T *obj)
static T * Detach(T *obj)
static std::vector< TDirectory * > Create(unsigned maxSlots)
static std::vector< TDirectory * > Create(unsigned maxSlots)