1 ///-*-C++-*-////////////////////////////////////////////////////////////////// 2 // 3 // Hoard: A Fast, Scalable, and Memory-Efficient Allocator 4 // for Shared-Memory Multiprocessors 5 // Contact author: Emery Berger, http://www.cs.utexas.edu/users/emery 6 // 7 // Copyright (c) 1998-2000, The University of Texas at Austin. 8 // 9 // This library is free software; you can redistribute it and/or modify 10 // it under the terms of the GNU Library General Public License as 11 // published by the Free Software Foundation, http://www.fsf.org. 12 // 13 // This library is distributed in the hope that it will be useful, but 14 // WITHOUT ANY WARRANTY; without even the implied warranty of 15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 // Library General Public License for more details. 17 // 18 ////////////////////////////////////////////////////////////////////////////// 19 20 #ifndef _BLOCK_H_ 21 #define _BLOCK_H_ 22 23 #include "config.h" 24 25 #include "os/support/Debug.h" 26 27 //#include <assert.h> 28 29 namespace BPrivate { 30 31 class superblock; 32 33 class block { 34 public: 35 block(superblock * sb) 36 : 37 #if HEAP_DEBUG 38 _magic(FREE_BLOCK_MAGIC), 39 #endif 40 _next(NULL), _mySuperblock(sb) 41 { 42 } 43 44 block & 45 operator=(const block & b) 46 { 47 #if HEAP_DEBUG 48 _magic = b._magic; 49 #endif 50 _next = b._next; 51 _mySuperblock = b._mySuperblock; 52 #if HEAP_FRAG_STATS 53 _requestedSize = b._requestedSize; 54 #endif 55 return *this; 56 } 57 58 enum { 59 ALLOCATED_BLOCK_MAGIC = 0xcafecafe, 60 FREE_BLOCK_MAGIC = 0xbabebabe 61 }; 62 63 // Mark this block as free. 64 inline void markFree(void); 65 66 // Mark this block as allocated. 67 inline void markAllocated(void); 68 69 // Is this block valid? (i.e., 70 // does it have the right magic number?) 71 inline const int isValid(void) const; 72 73 // Return the block's superblock pointer. 74 inline superblock *getSuperblock(void); 75 76 #if HEAP_FRAG_STATS 77 void 78 setRequestedSize(size_t s) 79 { 80 _requestedSize = s; 81 } 82 83 size_t 84 getRequestedSize(void) 85 { 86 return _requestedSize; 87 } 88 #endif 89 90 #if USE_PRIVATE_HEAPS 91 void 92 setActualSize(size_t s) 93 { 94 _actualSize = s; 95 } 96 97 size_t 98 getActualSize(void) 99 { 100 return _actualSize; 101 } 102 #endif 103 void 104 setNext(block * b) 105 { 106 _next = b; 107 } 108 109 block * 110 getNext(void) 111 { 112 return _next; 113 } 114 115 #if HEAP_LEAK_CHECK 116 void 117 setCallStack(int index, void *address) 118 { 119 _callStack[index] = address; 120 } 121 122 void * 123 getCallStack(int index) 124 { 125 return _callStack[index]; 126 } 127 128 void 129 setAllocatedSize(size_t size) 130 { 131 _allocatedSize = size; 132 } 133 134 size_t 135 getAllocatedSize() 136 { 137 return _allocatedSize; 138 } 139 #endif 140 141 private: 142 #if USE_PRIVATE_HEAPS 143 #if HEAP_DEBUG 144 union { 145 unsigned long _magic; 146 double _d1; // For alignment. 147 }; 148 #endif 149 150 block *_next; // The next block in a linked-list of blocks. 151 size_t _actualSize; // The actual size of the block. 152 153 union { 154 double _d2; // For alignment. 155 superblock *_mySuperblock; // A pointer to my superblock. 156 }; 157 #else // ! USE_PRIVATE_HEAPS 158 159 #if HEAP_DEBUG 160 union { 161 unsigned long _magic; 162 double _d3; // For alignment. 163 }; 164 #endif 165 166 block *_next; // The next block in a linked-list of blocks. 167 superblock *_mySuperblock; // A pointer to my superblock. 168 169 #if defined(__i386__) && (__GNUC__ > 2) 170 double _d5; // For alignment, make sure the whole structure is 16 byte 171 // aligned 172 #endif 173 174 #endif // USE_PRIVATE_HEAPS 175 176 #if HEAP_LEAK_CHECK 177 void *_callStack[HEAP_CALL_STACK_SIZE]; 178 size_t _allocatedSize; 179 #endif 180 181 #if HEAP_FRAG_STATS 182 union { 183 double _d4; // This is just for alignment purposes. 184 size_t _requestedSize; // The amount of space requested (vs. allocated). 185 }; 186 #endif 187 188 // Disable copying. 189 block(const block &); 190 }; 191 192 // Make sure the block size does not mess up the alignment of allocations, it 193 // must be a multiple of ALIGNMENT 194 #if __GNUC__ > 2 195 // The macro we use for legacy gcc doesn't work in the global context, only 196 // inside functions since it is wrapped in a do/while. 197 STATIC_ASSERT(sizeof(block) % HAIKU_MEMORY_ALIGNMENT == 0); 198 #endif 199 200 201 superblock * 202 block::getSuperblock(void) 203 { 204 #if HEAP_DEBUG 205 assert(isValid()); 206 #endif 207 208 return _mySuperblock; 209 } 210 211 212 void 213 block::markFree(void) 214 { 215 #if HEAP_DEBUG 216 assert(_magic == ALLOCATED_BLOCK_MAGIC); 217 _magic = FREE_BLOCK_MAGIC; 218 #endif 219 } 220 221 222 void 223 block::markAllocated(void) 224 { 225 #if HEAP_DEBUG 226 assert(_magic == FREE_BLOCK_MAGIC); 227 _magic = ALLOCATED_BLOCK_MAGIC; 228 #endif 229 } 230 231 232 const int 233 block::isValid(void) const 234 { 235 #if HEAP_DEBUG 236 return _magic == FREE_BLOCK_MAGIC 237 || _magic == ALLOCATED_BLOCK_MAGIC; 238 #else 239 return 1; 240 #endif 241 } 242 243 } // namespace BPrivate 244 245 #endif // _BLOCK_H_ 246