49#ifndef ROOFIT_ROOFITCORE_SRC_MEMPOOLFORROOSETS_H_
50#define ROOFIT_ROOFITCORE_SRC_MEMPOOLFORROOSETS_H_
59template <
class RooSet_t, std::
size_t POOLSIZE>
72 : ownedMemory{
other.ownedMemory},
73 memBegin{
other.memBegin}, nextItem{
other.nextItem}, memEnd{
other.memEnd},
74 refCount{
other.refCount},
75 totCount{
other.totCount},
76 assigned{
other.assigned},
80 other.ownedMemory =
nullptr;
89 ownedMemory =
other.ownedMemory;
90 memBegin =
other.memBegin;
91 nextItem =
other.nextItem;
92 memEnd =
other.memEnd;
93 refCount =
other.refCount;
94 totCount =
other.totCount;
95 assigned =
other.assigned;
97 other.ownedMemory =
nullptr;
109 if (!ownedMemory)
return;
112 std::cerr <<
__FILE__ <<
":" <<
__LINE__ <<
"Deleting arena " << ownedMemory <<
" with use count " << refCount
122 return memBegin <= ptr && ptr < memEnd;
125 bool inPool(
const void *
const ptr)
const
133 bool empty()
const {
return refCount == 0; }
136 if (ownedMemory && empty() && (!hasSpace() ||
freeNonFull) ) {
138 ownedMemory =
nullptr;
144 if (!hasSpace())
return nullptr;
146 for(std::size_t i = 0; i <
POOLSIZE; ++i) {
147 if (nextItem == memEnd) {
148 nextItem = ownedMemory;
150 std::size_t
index = (
static_cast<RooSet_t *
>(nextItem) - memBegin) / 2;
152 if(!assigned[
index]) {
158 assigned[
index] =
true;
159 auto ptr =
reinterpret_cast<RooSet_t*
>(
reinterpret_cast<char*
>(ownedMemory + 2 *
index) + cycle[
index]);
173 const std::size_t
index = ( (
reinterpret_cast<const char *
>(ptr) -
reinterpret_cast<const char *
>(memBegin)) / 2) /
sizeof(
RooSet_t);
175 if (assigned[
index] ==
false) {
176 std::cerr <<
"Double delete of " << ptr <<
" at index " <<
index <<
" in Arena with refCount " << refCount
177 <<
".\n\tArena: |" << memBegin <<
"\t" << ptr <<
"\t" << memEnd <<
"|" << std::endl;
181 assigned[
index] =
false;
189 return inPool(
other.memBegin) || inPool(
reinterpret_cast<const char*
>(
other.memEnd)-1);
196 std::size_t refCount = 0;
197 std::size_t totCount = 0;
199 std::bitset<POOLSIZE> assigned = {};
200 std::array<int, POOLSIZE> cycle = {{}};
220 std::cerr <<
" The mem pool being deleted is not empty. This will lead to crashes."
230 throw std::bad_alloc();
232 if (fArenas.empty()) {
236 void * ptr = fArenas.back().tryAllocate();
238 if (ptr ==
nullptr) {
241 ptr = fArenas.back().tryAllocate();
257 if (std::any_of(fArenas.begin(), fArenas.end(),
258 [ptr](
Arena&
arena){return arena.tryDeallocate(ptr);})) {
280 for (
auto &
arena : fArenas) {
281 arena.tryFree(fTeardownMode);
286 std::remove_if(fArenas.begin(), fArenas.end(), [](
Arena&
ar){return ar.ownedMemory == nullptr;}),
296 return std::all_of(fArenas.begin(), fArenas.end(), [](
const Arena &
ar) { return ar.empty(); });
306 fTeardownMode =
true;
322 if (std::none_of(fArenas.begin(), fArenas.end(),
323 [&
ar](
Arena&
other){return ar.memoryOverlaps(other);})) {
324 fArenas.emplace_back(std::move(
ar));
336 bool fTeardownMode{
false};
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t bytes
Memory pool for RooArgSet and RooDataSet.
~MemPoolForRooSets()
Destructor. Should not be called when RooArgSets or RooDataSets are still alive.
void prune()
Free memory in arenas that don't have space and no users.
MemPoolForRooSets & operator=(const MemPoolForRooSets &)=delete
MemPoolForRooSets(const MemPoolForRooSets &)=delete
void newArena()
RooFit relies on unique pointers for RooArgSets.
MemPoolForRooSets & operator=(MemPoolForRooSets &&)=delete
MemPoolForRooSets()
Create empty mem pool.
void * allocate(std::size_t bytes)
Allocate memory for the templated set type. Fails if bytes != sizeof(RooSet_t).
bool deallocate(void *ptr)
Deallocate memory for the templated set type if in pool.
MemPoolForRooSets(MemPoolForRooSets &&)=delete
void teardown()
Set pool to teardown mode (at program end).
std::vector< Arena > fArenas
bool empty() const
Test if pool is empty.
bool tryDeallocate(void *ptr)
void tryFree(bool freeNonFull)
bool inPool(const void *const ptr) const
bool memoryOverlaps(const Arena &other) const
const RooSet_t * memBegin
std::array< int, POOLSIZE > cycle
Arena & operator=(Arena &&other)
bool inPool(const RooSet_t *const ptr) const
Arena(const Arena &)=delete
Arena & operator=(const Arena &)=delete