Generated on Wed Nov 1 15:04:48 2006 for Gecode by doxygen 1.4.5

block-allocator.hh

Go to the documentation of this file.
00001 /*
00002  *  Main authors:
00003  *     Christian Schulte <schulte@gecode.org>
00004  *
00005  *  Copyright:
00006  *     Christian Schulte, 2004
00007  *
00008  *  Last modified:
00009  *     $Date: 2006-04-11 15:58:37 +0200 (Tue, 11 Apr 2006) $ by $Author: tack $
00010  *     $Revision: 3188 $
00011  *
00012  *  This file is part of Gecode, the generic constraint
00013  *  development environment:
00014  *     http://www.gecode.org
00015  *
00016  *  See the file "LICENSE" for information on usage and
00017  *  redistribution of this file, and for a
00018  *     DISCLAIMER OF ALL WARRANTIES.
00019  *
00020  */
00021 
00022 #ifndef __GECODE_SUPPORT_BLOCK_ALLOCATOR_HH__
00023 #define __GECODE_SUPPORT_BLOCK_ALLOCATOR_HH__
00024 
00025 #include "gecode/kernel.hh"
00026 
00027 namespace Gecode { namespace Support {
00028 
00038   template <class T>
00039   class BlockAllocator {
00040   private:
00042     class Block {
00043     public:
00044       static const int blocksize = 512;
00045       T      b[blocksize];
00046       Block* next;
00047     };
00049     Block* b;
00051     T*     n;
00053     size_t _size;
00055     void allocate(void);
00056   public:
00058     BlockAllocator(void);
00060     ~BlockAllocator(void);
00062     T* operator()(void);
00064     size_t size(void) const;
00065   };
00066 
00075   template <class T>
00076   class BlockClient {
00077   public:
00079     static void* operator new(size_t s, BlockAllocator<T>& ba);
00081     static void  operator delete(void*, BlockAllocator<T>& ba);
00083     static void  operator delete(void*);
00084   };
00085 
00086 
00087 
00088   template <class T>
00089   forceinline
00090   BlockAllocator<T>::BlockAllocator(void) {
00091     b = reinterpret_cast<Block*>(Memory::malloc(sizeof(Block)));
00092     b->next = NULL;
00093     n       = &b->b[Block::blocksize];
00094     _size = sizeof(Block);
00095   }
00096 
00097   template <class T>
00098   forceinline
00099   BlockAllocator<T>::~BlockAllocator(void) {
00100     while (b != NULL) {
00101       Block* f = b; b = b->next;
00102       Memory::free(f);
00103     }
00104   }
00105 
00106   template <class T>
00107   forceinline T*
00108   BlockAllocator<T>::operator()(void) {
00109     T* t = --n;
00110     if (t == &b->b[0])
00111       allocate();
00112     return t;
00113   }
00114 
00115   template <class T>
00116   void
00117   BlockAllocator<T>::allocate(void) {
00118     // Allocate another block
00119     Block* nb = reinterpret_cast<Block*>(Memory::malloc(sizeof(Block)));
00120     nb->next = b; b = nb;
00121     n = &nb->b[Block::blocksize];
00122     _size += sizeof(Block);
00123   }
00124 
00125   template <class T>
00126   forceinline size_t
00127   BlockAllocator<T>::size(void) const {
00128     return _size;
00129   }
00130 
00131 
00132 
00133   template <class T>
00134   forceinline void
00135   BlockClient<T>::operator delete(void*, BlockAllocator<T>&) {
00136   }
00137   template <class T>
00138   forceinline void
00139   BlockClient<T>::operator delete(void*) {
00140   }
00141   template <class T>
00142   forceinline void*
00143   BlockClient<T>::operator new(size_t s, BlockAllocator<T>& ba) {
00144     assert(s == sizeof(T));
00145     return ba();
00146   }
00147 
00148 }}
00149 
00150 #endif
00151 
00152 // STATISTICS: support-any