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