this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2/* 3 * Main authors: 4 * Christian Schulte <schulte@gecode.org> 5 * 6 * Copyright: 7 * Christian Schulte, 2004 8 * 9 * This file is part of Gecode, the generic constraint 10 * development environment: 11 * http://www.gecode.org 12 * 13 * Permission is hereby granted, free of charge, to any person obtaining 14 * a copy of this software and associated documentation files (the 15 * "Software"), to deal in the Software without restriction, including 16 * without limitation the rights to use, copy, modify, merge, publish, 17 * distribute, sublicense, and/or sell copies of the Software, and to 18 * permit persons to whom the Software is furnished to do so, subject to 19 * the following conditions: 20 * 21 * The above copyright notice and this permission notice shall be 22 * included in all copies or substantial portions of the Software. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 28 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 29 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 30 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 31 * 32 */ 33 34namespace Gecode { namespace Support { 35 36 /** 37 * \brief Manage memory organized into block lists (allocator) 38 * 39 * The allocation policy is to free all memory allocated when 40 * the block allocator is deleted. 41 * 42 * \ingroup FuncSupport 43 */ 44 template<class T, class A, int blocksize = 512> 45 class BlockAllocator { 46 private: 47 /// Memory allocator 48 A& a; 49 /// One block of memory 50 class Block { 51 public: 52 T b[blocksize]; 53 Block* next; 54 }; 55 /// Pointer to current block 56 Block* b; 57 /// Pointer to next part of block (decreasing) 58 T* n; 59 /// Size of allocated blocks 60 size_t _size; 61 /// Allocate additional block 62 void allocate(void); 63 public: 64 /// Initialize 65 BlockAllocator(A& a); 66 /// Free all allocated blocks 67 ~BlockAllocator(void); 68 /// Return allocator used 69 A& allocator(void); 70 /// Return memory of size required by \a T 71 T* operator ()(void); 72 /// Return size of memory required by allocator 73 size_t size(void) const; 74 }; 75 76 /** 77 * \brief Client for block allocator of type \a T 78 * 79 * Provides memory management for objects of type \a T. 80 * 81 * \ingroup FuncSupport 82 */ 83 template<class T, class A, int blocksize = 512> 84 class BlockClient { 85 public: 86 /// Allocate memory from block allocator \a ba 87 static void* operator new(size_t s, BlockAllocator<T,A,blocksize>& ba); 88 /// Noop (memory freed only when block allocator deleted) 89 static void operator delete(void*, BlockAllocator<T,A,blocksize>& ba); 90 /// Noop (memory freed only when block allocator deleted) 91 static void operator delete(void*); 92 }; 93 94 95 96 template<class T, class A, int blocksize> 97 forceinline 98 BlockAllocator<T,A,blocksize>::BlockAllocator(A& a0) : a(a0) { 99 b = static_cast<Block*>(a.ralloc(sizeof(Block))); 100 b->next = nullptr; 101 n = &b->b[blocksize]; 102 _size = sizeof(Block); 103 } 104 105 template<class T, class A, int blocksize> 106 forceinline 107 BlockAllocator<T,A,blocksize>::~BlockAllocator(void) { 108 while (b != nullptr) { 109 Block* f = b; b = b->next; 110 a.rfree(f,sizeof(Block)); 111 } 112 } 113 114 template<class T, class A, int blocksize> 115 forceinline A& 116 BlockAllocator<T,A,blocksize>::allocator(void) { 117 return a; 118 } 119 120 template<class T, class A, int blocksize> 121 forceinline T* 122 BlockAllocator<T,A,blocksize>::operator ()(void) { 123 T* t = --n; 124 if (t == &b->b[0]) 125 allocate(); 126 return t; 127 } 128 129 template<class T, class A, int blocksize> 130 void 131 BlockAllocator<T,A,blocksize>::allocate(void) { 132 // Allocate another block 133 Block* nb = static_cast<Block*>(a.ralloc(sizeof(Block))); 134 nb->next = b; b = nb; 135 n = &nb->b[blocksize]; 136 _size += sizeof(Block); 137 } 138 139 template<class T, class A, int blocksize> 140 forceinline size_t 141 BlockAllocator<T,A,blocksize>::size(void) const { 142 return _size; 143 } 144 145 146 147 template<class T, class A, int blocksize> 148 forceinline void 149 BlockClient<T,A,blocksize>::operator 150 delete(void*,BlockAllocator<T,A,blocksize>&) { 151 } 152 template<class T, class A, int blocksize> 153 forceinline void 154 BlockClient<T,A,blocksize>::operator delete(void*) { 155 } 156 template<class T, class A, int blocksize> 157 forceinline void* 158 BlockClient<T,A,blocksize>::operator new(size_t, 159 BlockAllocator<T,A,blocksize>& ba) { 160 return ba(); 161 } 162 163}} 164 165// STATISTICS: support-any