12 #error("BulkAllocator.h is currently broken; see issue #19494.") 15 #ifndef BULKALLOCATOR_H 16 #define BULKALLOCATOR_H 27 namespace bulk_allocator {
39 virtual const char*
what()
const throw()
override {
return msg; }
42 const char* msg =
nullptr;
94 typedef typename BaseAllocator_t::size_type
size_type;
99 typedef typename BaseAllocator_t::pointer
pointer;
105 template <
typename U>
116 CreateGlobalAllocator(ChunkSize, bPreallocate);
142 pointer allocate(size_type
n,
const void* = 0);
145 void deallocate(pointer p, size_type n);
148 static void Free() { GlobalAllocator.Free(); }
151 static size_type
GetChunkSize() {
return GlobalAllocator.GetChunkSize(); }
154 static void SetChunkSize(size_type ChunkSize) { GlobalAllocator.SetChunkSize(ChunkSize); }
161 void CreateGlobalAllocator(size_type ChunkSize,
bool bPreallocate =
false);
202 template <
typename T>
205 std::string name =
typeid(T).name();
208 std::unique_ptr<char, void (*)(void*)> res{
209 abi::__cxa_demangle(name.c_str(), NULL, NULL, &status), std::free};
210 return (status == 0) ? res.get() : name;
216 template <
typename T>
219 return demangle<T>();
223 namespace bulk_allocator {
264 template <
typename T>
272 BulkAllocatorBase(size_type NewChunkSize = DefaultChunkSize,
bool bPreallocate =
false);
281 pointer
Get(size_type
n);
290 void AddUser(size_type NewChunkSize,
bool bPreallocate =
false);
296 size_type AllocatedCount()
const;
299 size_type UsedCount()
const;
302 size_type FreeCount()
const;
305 size_type
NChunks()
const {
return MemoryPool.size(); }
308 std::array<size_type, 2> GetCounts()
const;
311 void SetChunkSize(size_type NewChunkSize,
bool force =
false);
333 pointer free =
nullptr;
338 begin = n ? allocator->allocate(n) :
nullptr;
361 bool full()
const {
return !available(); }
364 pointer
get() {
return (free != end) ? free++ :
nullptr; }
367 pointer
get(
size_t n)
370 if ((free += n) <=
end)
return ptr;
390 void Preallocate(size_type n);
394 template <
typename T>
397 std::swap(allocator, from.allocator);
398 std::swap(
begin, from.begin);
399 std::swap(
end, from.end);
400 std::swap(free, from.free);
403 template <
typename T>
407 std::swap(allocator, from.allocator);
408 std::swap(
begin, from.begin);
409 std::swap(
end, from.end);
410 std::swap(free, from.free);
414 template <
typename T>
417 template <
typename T>
420 : ChunkSize(NewChunkSize), MemoryPool()
424 std::cout <<
"BulkAllocatorBase[" << ((
void*)
this) <<
"] created for type " 425 << demangle<value_type>() <<
" with chunk size " <<
GetChunkSize() <<
" x" 427 <<
" bytes/chunk" << std::endl;
431 template <
typename T>
435 std::cout <<
"BulkAllocatorBase[" << ((
void*)
this) <<
"] freeing " <<
NChunks()
436 <<
" memory chunks with " <<
AllocatedCount() <<
" elements" << std::endl;
441 template <
typename T>
450 template <
typename T>
458 template <
typename T>
465 template <
typename T>
474 template <
typename T>
483 template <
typename T>
489 std::array<BulkAllocatorBase<T>::size_type, 2> stats = {{0U, 0U}};
491 stats[0] += chunk.used();
492 stats[1] += chunk.available();
497 template <
typename T>
502 std::cout <<
"BulkAllocatorBase[" << ((
void*)
this) <<
"]" 503 <<
" changing chunk size: " <<
GetChunkSize() <<
" => " << NewChunkSize <<
": x" 505 <<
" bytes/chunk" << std::endl;
510 template <
typename T>
513 if (n == 0)
return nullptr;
522 std::array<size_type, 2> stats =
GetCounts();
523 std::cout <<
"BulkAllocatorBase[" << ((
void*)
this) <<
"] allocating " 524 << std::max(
ChunkSize, n) <<
" more elements (on top of the current " 525 << (stats[0] + stats[1]) <<
" elements, " << stats[1] <<
" unused)" 534 template <
typename T>
537 template <
typename T>
540 GlobalAllocator.AddUser(ChunkSize, bPreallocate);
543 template <
typename T>
547 return GlobalAllocator.Get(n);
550 template <
typename T>
553 return GlobalAllocator.Release(p);
557 #endif // BULKALLOCATOR_H A class managing a memory pool.
BaseAllocator_t::pointer pointer
MemoryChunk_t & operator=(const MemoryChunk_t &)=delete
Can't assign.
void Release(pointer)
Releases memory pointed by the specified pointer (but it does not).
Internal memory chunk; like a std::vector, but does not construct.
BaseAllocator_t::difference_type difference_type
BulkAllocatorBase(size_type NewChunkSize=DefaultChunkSize, bool bPreallocate=false)
Constructor; preallocates memory if explicitly requested.
bool RemoveUser()
Removed a user to the users count; returns false if no user yet.
void deallocate(pointer p, size_type n)
Frees n elements at p.
void CreateGlobalAllocator(size_type ChunkSize, bool bPreallocate=false)
Makes sure we have a valid "global allocator".
Counter_t Count() const
Returns the number of registered users.
pointer Get(size_type n)
Returns a pointer to memory for n new values of type T.
std::array< size_type, 2 > GetCounts() const
Returns an array equivalent to { UsedCount(), FreeCount() }.
void AddUser()
Adds a user to the users count.
Allocator_t::difference_type difference_type
void Free()
Releases the pool of memory; all pointer to it become invalid.
MemoryChunk_t(Allocator_t &alloc, size_type n)
void message(RunManager *runmanager)
memory_error(const char *message)
static void Free()
Releases all the allocated memory: dangerous!
cout<< "Opened file "<< fin<< " ixs= "<< ixs<< endl;if(ixs==0) hhh=(TH1F *) fff-> Get("h1")
static SharedAllocator_t GlobalAllocator
The allocator shared by all instances of this object.
BaseAllocator_t::reference reference
~BulkAllocator()
Destructor; memory is freed only if no allocators are left around.
bool full() const
Returns whether the chunk is full.
Exception thrown when BulkAllocator-specific allocation errors happen.
size_type ChunkSize
size of the chunks to add
BulkAllocator() noexcept
Default constructor: uses the default chunk size.
size_type AllocatedCount() const
Returns the total number of entries in the pool.
BaseAllocator_t::size_type size_type
BulkAllocator(const BulkAllocator< U > &a) noexcept
General copy constructor; currently, it does not preallocate.
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Allocator_t * allocator
reference to the allocator to be used
A simple reference counter, keep track of a number of users.
BaseAllocator_t::const_reference const_reference
pointer allocate(size_type n, const void *=0)
Allocates memory for n elements.
auto counter(T begin, T end)
Returns an object to iterate values from begin to end in a range-for loop.
BulkAllocator(size_type ChunkSize, bool bPreallocate=false) noexcept
Constructor: sets chunk size and optionally allocates the first chunk.
virtual const char * what() const override
~BulkAllocatorBase()
Destructor: releases all the memory pool (.
size_type size() const
Returns the number of elements in this pool.
details::bulk_allocator::BulkAllocatorBase< T > SharedAllocator_t
shared allocator type
Allocator_t allocator
the actual allocator we use
Aggressive allocator reserving a lot of memory in advance.
std::string demangle()
Demangles the name of a type.
std::allocator< T > Allocator_t
size_type NChunks() const
Returns the number of memory pool chunks allocated.
static size_type DefaultChunkSize
Default chunk size (default: 10000)
size_type available() const
Returns the number of free elements in this pool.
size_type UsedCount() const
Returns the total number of used entries in the pool.
MemoryChunk_t()
< Default constructor (does nothing)
size_type GetChunkSize() const
Returns the current chunk size.
bool hasUsers() const
Returns whether there are currently users.
unsigned int Counter_t
type of user counter
LArSoft-specific namespace.
static void SetChunkSize(size_type ChunkSize)
Sets chunk size of global allocator; only affects future allocations!
BaseAllocator_t::value_type value_type
BaseAllocator_t::const_pointer const_pointer
void SetChunkSize(size_type NewChunkSize, bool force=false)
Sets the chunk size for the future allocations.
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
std::vector< MemoryChunk_t > MemoryPool_t
std::allocator< T > BaseAllocator_t
size_type used() const
Returns the number of used elements in this pool.
static size_type GetChunkSize()
Returns the chunk size of the underlying global allocator.
bool RemoveUser()
Removed a user to the users count; if no user is left, free the pool.
MemoryPool_t MemoryPool
list of all memory chunks; first is free
void AddUser()
Add a new pool user with the current parameters.