24#ifndef ROOFIT_ROOFITCORE_SRC_MEMPOOLFORROOSETS_H_
25#define ROOFIT_ROOFITCORE_SRC_MEMPOOLFORROOSETS_H_
30template <
class RooSet_t, std::
size_t POOLSIZE>
35 :
ownedMemory{static_cast<RooSet_t *>(::operator new(POOLSIZE * sizeof(RooSet_t)))},
53 other.ownedMemory =
nullptr;
71 other.ownedMemory =
nullptr;
86 std::cerr << __FILE__ <<
":" << __LINE__ <<
"Deleting arena " <<
ownedMemory <<
" with use count " <<
refCount
95 bool inPool(
const RooSet_t *
const ptr)
const {
99 bool inPool(
const void *
const ptr)
const
101 return inPool(
static_cast<const RooSet_t * const
>(ptr));
127 const std::size_t index =
static_cast<RooSet_t *
>(ptr) -
memBegin;
129 std::cerr <<
"Double delete of " << ptr <<
" at index " << index <<
" in Arena with refCount " <<
refCount
130 <<
".\n\tArena: |" <<
memBegin <<
"\t" << ptr <<
"\t" <<
memEnd <<
"|" << std::endl;
170 std::cerr << __PRETTY_FUNCTION__;
172 std::cerr <<
" The mem pool being deleted is not empty. This will lead to crashes."
183 if (bytes !=
sizeof(RooSet_t))
184 throw std::bad_alloc();
191 void * ptr =
fArenas.back().tryAllocate();
192 assert(ptr !=
nullptr);
203 bool deallocSuccess =
false;
206 [ptr](
Arena& arena){return arena.tryDeallocate(ptr);})) {
207 deallocSuccess =
true;
215 return deallocSuccess;
232 std::remove_if(
fArenas.begin(),
fArenas.end(), [](
Arena& ar){return ar.ownedMemory == nullptr;}),
242 return std::all_of(
fArenas.begin(),
fArenas.end(), [](
const Arena & ar) { return ar.empty(); });
265 std::vector<Arena> failedAllocs;
269 [&ar](
Arena& other){return ar.memoryOverlaps(other);})) {
270 fArenas.push_back(std::move(ar));
274 failedAllocs.push_back(std::move(ar));
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::set< std::size_t > deletedElements
Arena & operator=(Arena &&other)
bool inPool(const RooSet_t *const ptr) const
Arena(const Arena &)=delete
Arena & operator=(const Arena &)=delete