From 3396a03818a5c4e86236f91afb9158061cfcc7e2 Mon Sep 17 00:00:00 2001 From: Alexandre Duret-Lutz Date: Sun, 3 Apr 2011 19:05:11 +0200 Subject: [PATCH] Add a fixed-size memory pool implementation. * src/misc/fixpool.hh: New file. * src/misc/Makefile.am (misc_HEADERS): Add fixpool.hh. --- ChangeLog | 7 +++ src/misc/Makefile.am | 1 + src/misc/fixpool.hh | 116 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+) create mode 100644 src/misc/fixpool.hh diff --git a/ChangeLog b/ChangeLog index 601b1800e..87397312d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-04-03 Alexandre Duret-Lutz + + Add a fixed-size memory pool implementation. + + * src/misc/fixpool.hh: New file. + * src/misc/Makefile.am (misc_HEADERS): Add fixpool.hh. + 2011-04-03 Alexandre Duret-Lutz * HACKING (command): Some notes about link-time optimizations. diff --git a/src/misc/Makefile.am b/src/misc/Makefile.am index 93c2834af..d62b31fb7 100644 --- a/src/misc/Makefile.am +++ b/src/misc/Makefile.am @@ -33,6 +33,7 @@ misc_HEADERS = \ bddop.hh \ casts.hh \ escape.hh \ + fixpool.hh \ freelist.hh \ hash.hh \ hashfunc.hh \ diff --git a/src/misc/fixpool.hh b/src/misc/fixpool.hh new file mode 100644 index 000000000..dd8fae356 --- /dev/null +++ b/src/misc/fixpool.hh @@ -0,0 +1,116 @@ +// Copyright (C) 2011 Laboratoire de Recherche et Developpement de +// l'Epita (LRDE) +// +// This file is part of Spot, a model checking library. +// +// Spot is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// Spot is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +// License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Spot; see the file COPYING. If not, write to the Free +// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. + +#ifndef SPOT_MISC_FIXPOOL_HH +# define SPOT_MISC_FIXPOOL_HH + +#include +#include +#include +#include + +namespace spot +{ + + /// A fixed-size memory pool implementation. + class fixed_size_pool + { + public: + /// Create a pool allocating objects of \a size bytes. + fixed_size_pool(size_t size) + : freelist_(0), free_start_(0), free_end_(0), chunklist_(0) + { + const size_t alignement = 2 * sizeof(size_t); + size_ = ((size >= sizeof(block_) ? size : sizeof(block_)) + + alignement - 1) & ~(alignement - 1); + } + + /// Free any memory allocated by this pool. + ~fixed_size_pool() + { + while (chunklist_) + { + chunk_* prev = chunklist_->prev; + free(chunklist_); + chunklist_ = prev; + } + } + + /// Allocate \a size bytes of memory. + void* + allocate() + { + block_* f = freelist_; + // If we have free blocks available, return the first one. + if (f) + { + freelist_ = f->next; + return f; + } + + // Else, create a block out of the last chunk of allocated + // memory. + + // If all the last chunk has been used, allocate one more. + if (free_start_ + size_ > free_end_) + { + const size_t requested = (size_ > 128 ? size_ : 128) * 8192 - 64; + chunk_* c = reinterpret_cast(malloc(requested)); + if (!c) + throw std::bad_alloc(); + c->prev = chunklist_; + chunklist_ = c; + + free_start_ = c->data_ + size_; + free_end_ = c->data_ + requested; + } + + void* res = free_start_; + free_start_ += size_; + return res; + } + + /// \brief Recycle \a size bytes of memory. + /// + /// Despite the name, the memory is not really deallocate in the + /// "delete" sense: it is still owned by the pool and will be + /// reused by allocate as soon as possible. The memory is only + /// freed when the pool is destroyed. + void + deallocate (const void* ptr) + { + assert(ptr); + block_* b = reinterpret_cast(const_cast(ptr)); + b->next = freelist_; + freelist_ = b; + } + + private: + 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_; + }; + +} + +#endif // SPOT_MISC_FIXPOOL_HH