spot  0.8.2
mspool.hh
Go to the documentation of this file.
00001 // Copyright (C) 2011 Laboratoire de Recherche et Developpement de
00002 // l'Epita (LRDE)
00003 //
00004 // This file is part of Spot, a model checking library.
00005 //
00006 // Spot is free software; you can redistribute it and/or modify it
00007 // under the terms of the GNU General Public License as published by
00008 // the Free Software Foundation; either version 2 of the License, or
00009 // (at your option) any later version.
00010 //
00011 // Spot is distributed in the hope that it will be useful, but WITHOUT
00012 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
00013 // or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
00014 // License for more details.
00015 //
00016 // You should have received a copy of the GNU General Public License
00017 // along with Spot; see the file COPYING.  If not, write to the Free
00018 // Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
00019 // 02111-1307, USA.
00020 
00021 #ifndef SPOT_MISC_MSPOOL_HH
00022 #  define SPOT_MISC_MSPOOL_HH
00023 
00024 #include <new>
00025 #include <cstddef>
00026 #include <cstdlib>
00027 #include <cassert>
00028 #include "misc/hash.hh"
00029 
00030 namespace spot
00031 {
00032 
00034   class multiple_size_pool
00035   {
00036     static const size_t alignment_ = 2 * sizeof(size_t) - 1;
00037   public:
00039     multiple_size_pool()
00040       : free_start_(0), free_end_(0), chunklist_(0)
00041     {
00042     }
00043 
00045     ~multiple_size_pool()
00046     {
00047       while (chunklist_)
00048         {
00049           chunk_* prev = chunklist_->prev;
00050           free(chunklist_);
00051           chunklist_ = prev;
00052         }
00053     }
00054 
00055     size_t fixsize(size_t size) const
00056     {
00057       if (size < sizeof(block_))
00058         size = sizeof(block_);
00059 
00060       return (size + alignment_ - 1) & ~(alignment_ - 1);
00061     }
00062 
00064     void*
00065     allocate(size_t size)
00066     {
00067       size = fixsize(size);
00068 
00069       block_*& f = freelist_[size];
00070       // If we have free blocks available, return the first one.
00071       if (f)
00072         {
00073           block_* first = f;
00074           f = f->next;
00075           return first;
00076         }
00077 
00078       // Else, create a block out of the last chunk of allocated
00079       // memory.
00080 
00081       // If all the last chunk has been used, allocate one more.
00082       if (free_start_ + size > free_end_)
00083         {
00084           const size_t requested = (size > 128 ? size : 128) * 8192 - 64;
00085           chunk_* c = reinterpret_cast<chunk_*>(malloc(requested));
00086           if (!c)
00087             throw std::bad_alloc();
00088           c->prev = chunklist_;
00089           chunklist_ = c;
00090 
00091           free_start_ = c->data_ + size;
00092           free_end_ = c->data_ + requested;
00093         }
00094 
00095       void* res = free_start_;
00096       free_start_ += size;
00097       return res;
00098     }
00099 
00109     void
00110     deallocate (const void* ptr, size_t size)
00111     {
00112       assert(ptr);
00113       size = fixsize(size);
00114       block_* b = reinterpret_cast<block_*>(const_cast<void*>(ptr));
00115       block_*& f = freelist_[size];
00116       b->next = f;
00117       f = b;
00118     }
00119 
00120   private:
00121     struct block_ { block_* next; };
00122     Sgi::hash_map<size_t, block_*> freelist_;
00123     char* free_start_;
00124     char* free_end_;
00125     // chunk = several agglomerated blocks
00126     union chunk_ { chunk_* prev; char data_[1]; }* chunklist_;
00127   };
00128 
00129 }
00130 
00131 #endif // SPOT_MISC_INTVPOOL_HH

Please comment this page and report errors about it on the RefDocComments page.
Generated on Thu Jan 19 2012 19:33:03 for spot by doxygen 1.7.6.1