block-allocator.hh
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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