181 const size_t water_mark) :
182 memory_blocks_(max_num_blocks),
183 water_mark_(water_mark),
184 watermark_warning_callback_(waterMarkWarningCallback_),
185 over_allocation_callback_(overAllocationCallback_)
188 "The water_mark on SpartaSharedPointerAllocator should be less than or " <<
189 "equal to the maximum number of blocks. water_mark=" << water_mark <<
190 " max_num_blocks=" << max_num_blocks);
191 free_blocks_.resize(max_num_blocks,
nullptr);
205 std::cerr <<
"WARNING: Seems that not all of the blocks made it back. \n'" <<
206 __PRETTY_FUNCTION__ <<
"'\nAllocated: " << allocated_ <<
207 "\nReturned: " << free_idx_ << std::endl;
226 return memory_blocks_.size();
234 return (allocated_ != free_idx_);
244 std::vector<const PointerT*> allocated_objs;
246 const size_t size = memory_blocks_.size();
247 for(uint32_t i = 0; i < size; ++i) {
248 if(memory_blocks_[i]->ref_count->count > 0) {
249 allocated_objs.emplace_back(memory_blocks_[i]->
object);
253 return allocated_objs;
264 watermark_warning_callback_ = callback;
275 over_allocation_callback_ = callback;
284 template<
typename PtrT,
typename... Args>
289 struct AlignedStorage
291 alignas(T) std::byte buf[
sizeof(T)];
295 struct MemBlock :
public BaseAllocator::MemBlockBase
297 using RefCountType =
typename SpartaSharedPointer<PointerT>::RefCount;
299 using RefCountAlignedStorage = AlignedStorage<RefCountType>;
301 using PointerTAlignedStorage = AlignedStorage<PointerT>;
303 template<
typename ...ObjArgs>
304 MemBlock(SpartaSharedPointerAllocator * alloc_in, ObjArgs&&...obj_args) :
305 MemBlockBase(alloc_in)
308 object =
new (&object_storage) PointerT(std::forward<ObjArgs>(obj_args)...);
311 ref_count =
new (&ref_count_storage) RefCountType(
object, (
void*)
this);
314 PointerT *
object =
nullptr;
315 RefCountType * ref_count =
nullptr;
317 RefCountAlignedStorage ref_count_storage;
318 PointerTAlignedStorage object_storage;
320 MemBlock(
const MemBlock &) =
delete;
321 MemBlock(MemBlock &&) =
delete;
322 MemBlock & operator=(
const MemBlock&) =
delete;
330 using MemBlockAlignedStorage = AlignedStorage<MemBlock>;
332 std::vector<MemBlockAlignedStorage> data_;
333 std::size_t size_ = 0;
338 explicit MemBlockVector(
const size_t num_blocks) :
343 template<
typename ...Args>
344 MemBlock * allocate(SpartaSharedPointerAllocator * alloc, Args&&... args)
350 auto block =
new(&data_[size_]) MemBlock(alloc, std::forward<Args>(args)...);
357 const MemBlock* operator[](std::size_t idx)
const
360 return reinterpret_cast<const MemBlock*
>(&data_[idx]);
364 size_t capacity()
const {
369 size_t size()
const {
388 template<
typename ...PointerTArgs>
389 typename SpartaSharedPointer<PointerT>::RefCount * allocate_(PointerTArgs&&... args)
392 MemBlock * block =
nullptr;
397 block = free_blocks_[free_idx_];
399 block->ref_count->mem_block = (
void*)block;
400 block->ref_count->count = 1;
402 new (block->ref_count->p) PointerT(std::forward<PointerTArgs>(args)...);
407 watermark_warning_callback_(*
this);
408 water_mark_warning_ =
true;
413 over_allocation_callback_(*
this);
415 ex <<
"This allocator has run out of memory: \n\n\t"
416 << __PRETTY_FUNCTION__
418 <<
"\t\tNumber blocks preallocated: " << memory_blocks_.capacity()
419 <<
"\n\t\tWatermark : " << water_mark_;
423 block = memory_blocks_.allocate(
this, std::forward<PointerTArgs>(args)...);
426 return block->ref_count;
430 static void waterMarkWarningCallback_(
const SpartaSharedPointerAllocator & allocator) {
431 std::cerr <<
"WARNING: The watermark for this allocator has been surpassed: \n\n\t"
432 << __PRETTY_FUNCTION__
434 <<
"\t\tNumber blocks preallocated: " << allocator.memory_blocks_.capacity()
435 <<
"\n\t\tWatermark : " << allocator.water_mark_ << std::endl;
439 static void overAllocationCallback_(
const SpartaSharedPointerAllocator & allocator) {
446 void releaseObject_(
void * block)
const noexcept override {
447 static_cast<MemBlock *
>(block)->ref_count->p->~PointerT();
459 void releaseBlock_(
void * block)
override {
461 free_blocks_[free_idx_] =
static_cast<MemBlock *
>(block);
465 MemBlockVector memory_blocks_;
466 std::vector<MemBlock*> free_blocks_;
467 size_t free_idx_ = 0;
468 size_t allocated_ = 0;
469 const size_t water_mark_;
470 bool water_mark_warning_ =
false;