add a pool allocator for STL containers

* spot/priv/allocator.hh, spot/priv/Makefile.am: add a STL-compliant
  allocator based on spot::fixed_size_pool
* spot/misc/fixpool.hh, spot/misc/fixpool.cc, spot/misc/Makefile.am:
  refactor the existing spot::fixed_size_pool
* spot/ltsmin/ltsmin.cc, spot/twa/twaproduct.cc: reflect changes in the
  interface of spot::fixed_size_pool
* tests/core/mempool.cc: test the new allocator
This commit is contained in:
Maximilien Colange 2017-10-19 14:14:49 +02:00
parent 3fe74f1cb9
commit c9131aee72
8 changed files with 258 additions and 21 deletions

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2011, 2015, 2016, 2018 Laboratoire de Recherche et
// Copyright (C) 2011, 2015-2018 Laboratoire de Recherche et
// Développement de l'Epita (LRDE)
//
// This file is part of Spot, a model checking library.
@ -27,20 +27,12 @@
namespace spot
{
/// A fixed-size memory pool implementation.
class fixed_size_pool
class SPOT_API fixed_size_pool
{
public:
/// Create a pool allocating objects of \a size bytes.
fixed_size_pool(size_t size)
: freelist_(nullptr), free_start_(nullptr),
free_end_(nullptr), chunklist_(nullptr)
{
const size_t alignement = 2 * sizeof(size_t);
size_ = ((size >= sizeof(block_) ? size : sizeof(block_))
+ alignement - 1) & ~(alignement - 1);
}
fixed_size_pool(size_t size);
/// Free any memory allocated by this pool.
~fixed_size_pool()
@ -48,7 +40,7 @@ namespace spot
while (chunklist_)
{
chunk_* prev = chunklist_->prev;
free(chunklist_);
::operator delete(chunklist_);
chunklist_ = prev;
}
}
@ -78,9 +70,7 @@ namespace spot
if (free_start_ + size_ > free_end_)
{
const size_t requested = (size_ > 128 ? size_ : 128) * 8192 - 64;
chunk_* c = reinterpret_cast<chunk_*>(malloc(requested));
if (!c)
throw std::bad_alloc();
chunk_* c = reinterpret_cast<chunk_*>(::operator new(requested));
c->prev = chunklist_;
chunklist_ = c;
@ -103,10 +93,10 @@ namespace spot
/// reused by allocate as soon as possible. The memory is only
/// freed when the pool is destroyed.
void
deallocate (const void* ptr)
deallocate(void* ptr)
{
SPOT_ASSERT(ptr);
block_* b = reinterpret_cast<block_*>(const_cast<void*>(ptr));
block_* b = reinterpret_cast<block_*>(ptr);
b->next = freelist_;
freelist_ = b;
#if SPOT_DEBUG && defined(HAVE_VALGRIND_MEMCHECK_H)
@ -115,11 +105,12 @@ namespace spot
}
private:
size_t size_;
const size_t size_;
struct block_ { block_* next; }* freelist_;
char* free_start_;
char* free_end_;
// chunk = several agglomerated blocks
union chunk_ { chunk_* prev; char data_[1]; }* chunklist_;
};
}