Changeset 283
- Timestamp:
- Dec 11, 2002, 2:46:19 PM (18 years ago)
- Location:
- to-imperative/trunk/libp++
- Files:
-
- 3 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
to-imperative/trunk/libp++/Makefile
r276 r283 13 13 pxx_heap_allocator \ 14 14 pxx_default_allocator \ 15 pxx_chunk_allocator_block_header \ 15 16 pxx_chunk_allocator 16 17 -
to-imperative/trunk/libp++/pxx_chunk_allocator.hh
r282 r283 26 26 #include "pxx_allocator.hh" 27 27 #include "pxx_default_allocator.hh" 28 #include "pxx_chunk_allocator_block_header.hh" 28 29 29 30 namespace pxx … … 31 32 32 33 extern size_t chunks_in_block ; 33 34 //35 // Memory block header structure36 struct BlockHeader37 {38 //39 // Reference counter that is equal to a number of allocated chunks in a40 // block41 uintptr_t ref_count ;42 //43 // Pointer to the previous free block44 BlockHeader* prev ;45 //46 // Pointer to the next free block47 BlockHeader* next ;48 //49 //50 BlockHeader* left ;51 //52 //53 BlockHeader* right ;54 //55 //56 int balance ;57 //58 // Constructor59 BlockHeader (BlockHeader* _prev, BlockHeader* _next) ;60 61 NO_COPY_CTOR(BlockHeader)62 NO_ASSIGN(BlockHeader)63 //64 // Remove a memory block from block list65 inline void remove () ;66 67 };68 34 69 35 template <typename type_t> … … 87 53 88 54 }; 89 90 55 // 56 // A reference to underlying memory allocator 91 57 Allocator& allocator ; 92 93 BlockHeader block_list ; 94 58 // 59 // List of memory blocks 60 CABlockHeader block_list ; 61 // 62 // List of ofree chunks 95 63 FreeList free_list ; 96 64 // 65 // Chunk size 97 66 size_t chunk_size ; 98 67 … … 101 70 size_t nchunks ; 102 71 103 BlockHeader* root ;72 CABlockHeader* root ; 104 73 105 74 public: … … 124 93 private: 125 94 126 inline BlockHeader* get_block (void* _ptr) ; 127 inline void init_block (BlockHeader* _ptr) ; 95 inline CABlockHeader* get_block (void* _ptr) ; 96 void init_block (CABlockHeader* _ptr) ; 97 void free_block (CABlockHeader* _ptr) ; 128 98 129 99 }; -
to-imperative/trunk/libp++/pxx_chunk_allocator.ih
r282 r283 25 25 26 26 #include "pxx_chunk_allocator.hh" 27 #include "pxx_chunk_allocator_block_header.ih" 27 28 #include "pxx_common.ih" 28 29 29 30 namespace pxx 30 31 { 31 32 inline BlockHeader::BlockHeader (33 BlockHeader* _prev, BlockHeader* _next34 ) :35 ref_count (0),36 prev (_prev),37 next (_next),38 left (null),39 right (null)40 {}41 42 inline void BlockHeader::remove ()43 {44 prev->next = next;45 next->prev = prev;46 }47 32 48 33 template <typename type_t> … … 59 44 allocator (_allocator), 60 45 block_list (&block_list, &block_list), 61 chunk_size (size_align(sizeof(type_t), 2 * sizeof(void*))),46 chunk_size (size_align(sizeof(type_t), sizeof(FreeList))), 62 47 root (null) 63 48 { 64 49 free_list.prev = free_list.next = &free_list; 65 50 block_size = _allocator.get_real_size( 66 chunks_in_block * chunk_size + sizeof( BlockHeader)51 chunks_in_block * chunk_size + sizeof(CABlockHeader) 67 52 ); 68 printf("block_size: %u\n", block_size); 69 nchunks = (block_size - sizeof(BlockHeader))/chunk_size; 53 nchunks = (block_size - sizeof(CABlockHeader))/chunk_size; 70 54 } 71 55 … … 77 61 allocator (_allocator), 78 62 block_list (&block_list, &block_list), 79 chunk_size (size_align(sizeof(type_t), 2 * sizeof(void*))),63 chunk_size (size_align(sizeof(type_t), sizeof(FreeList))), 80 64 root (null) 81 65 { 82 66 free_list.prev = free_list.next = &free_list; 83 67 block_size = 84 _allocator.get_real_size(_nchunks * chunk_size + sizeof(BlockHeader)); 85 printf("block_size: %u\n", block_size); 86 printf("features: %08x\n", allocator.get_features()); 87 nchunks = (block_size - sizeof(BlockHeader))/chunk_size; 68 _allocator.get_real_size(_nchunks * chunk_size + sizeof(CABlockHeader)); 69 nchunks = (block_size - sizeof(CABlockHeader))/chunk_size; 88 70 } 89 71 … … 91 73 inline ChunkAllocator<type_t>::~ChunkAllocator () 92 74 { 93 BlockHeader* p = block_list.next;75 CABlockHeader* p = block_list.next; 94 76 while (p != &block_list) { 95 77 void* q = p; … … 105 87 if (p != &free_list) { 106 88 p->remove(); 107 BlockHeader* b = get_block(p);108 if (b != null) b->ref_count++;89 CABlockHeader* b = get_block(p); 90 (b->ref_count)++; 109 91 return (type_t*)p; 110 92 } else { 111 BlockHeader* p = (BlockHeader*)allocator.allocate(block_size);93 CABlockHeader* p = (CABlockHeader*)allocator.allocate(block_size); 112 94 //printf("Allocated block at %p\n", p); 113 95 init_block(p); 114 96 return ChunkAllocator::allocate(); 115 97 } 116 }117 118 static BlockHeader* node_balance (119 BlockHeader* _node120 );121 122 static BlockHeader* node_restore_left_balance (123 BlockHeader* _node,124 int _old_balance125 )126 {127 if (_node->left == null)128 _node->balance += 1;129 else130 if ((_node->left->balance != _old_balance) && (_node->left->balance == 0))131 _node->balance += 1;132 if (_node->balance > 1) return node_balance(_node);133 return _node;134 }135 136 static BlockHeader* node_restore_right_balance (137 BlockHeader* _node,138 int _old_balance139 )140 {141 if (_node->right == null)142 _node->balance -= 1;143 else144 if ((_node->right->balance != _old_balance) && (_node->right->balance == 0))145 _node->balance -= 1;146 if (_node->balance < -1) return node_balance(_node);147 return _node;148 }149 150 static BlockHeader* node_remove_leftmost (151 BlockHeader* _node,152 BlockHeader** _leftmost153 )154 {155 int old_balance;156 if (_node->left == null) {157 *_leftmost = _node;158 return _node->right;159 }160 old_balance = _node->left->balance;161 _node->left = node_remove_leftmost(_node->left, _leftmost);162 return node_restore_left_balance(_node, old_balance);163 }164 165 static BlockHeader* node_remove (166 BlockHeader* _node,167 BlockHeader* _key168 )169 {170 int old_balance;171 BlockHeader* new_root;172 if (_key == _node) {173 if (_node->right == null) {174 _node = _node->left;175 } else {176 old_balance = _node->right->balance;177 _node->right = node_remove_leftmost(_node->right, &new_root);178 new_root->left = _node->left;179 new_root->right = _node->right;180 new_root->balance = _node->balance;181 _node = node_restore_right_balance(new_root, old_balance);182 }183 } else if (_key < _node) {184 if (_node->left != null) {185 old_balance = _node->left->balance;186 _node->left = node_remove(_node->left, _key);187 _node = node_restore_left_balance(_node, old_balance);188 }189 } else {190 if (_node->right != null) {191 old_balance = _node->right->balance;192 _node->right = node_remove(_node->right, _key);193 _node = node_restore_right_balance(_node, old_balance);194 }195 }196 return _node;197 98 } 198 99 … … 204 105 p->next = &free_list; 205 106 free_list.prev = free_list.prev->next = p ; 206 BlockHeader* b = get_block(_ptr); 207 if ((b != null) && (--(b->ref_count) == 0)) { 208 FreeList* p = (FreeList*)ptr_add_offset(b, sizeof(BlockHeader)); 209 FreeList* q = (FreeList*)ptr_add_offset(p, nchunks * chunk_size); 210 while (p < q) { 211 p->remove(); 212 p = (FreeList*)ptr_add_offset(p, chunk_size); 213 } 214 //printf("Deallocating block at %p\n", b); 215 b->remove(); 216 if ((allocator.get_features() & ALLOCATOR_HAS_GET_BLOCK_WITH_SIZE) == 0) { 217 root = node_remove(root, b); 218 } 219 allocator.deallocate(b); 220 } 107 CABlockHeader* b = get_block(_ptr); 108 if (--(b->ref_count) != 0) return; 109 else return free_block(b); 221 110 } 222 111 223 112 template <typename type_t> 224 inline BlockHeader* ChunkAllocator<type_t>::get_block (void* _ptr) 113 inline void ChunkAllocator<type_t>::free_block (CABlockHeader* _ptr) 114 { 115 FreeList* p = (FreeList*)ptr_add_offset(_ptr, sizeof(CABlockHeader)); 116 FreeList* q = (FreeList*)ptr_add_offset(p, nchunks * chunk_size); 117 while (p < q) { 118 p->remove(); 119 p = (FreeList*)ptr_add_offset(p, chunk_size); 120 } 121 //printf("Deallocating block at %p\n", b); 122 _ptr->remove(); 123 if ((allocator.get_features() & ALLOCATOR_HAS_GET_BLOCK_WITH_SIZE) == 0) { 124 root = root->node_remove(_ptr); 125 } 126 allocator.deallocate(_ptr); 127 } 128 129 template <typename type_t> 130 inline CABlockHeader* ChunkAllocator<type_t>::get_block (void* _ptr) 225 131 { 226 132 if ((allocator.get_features() & ALLOCATOR_HAS_GET_BLOCK_WITH_SIZE) != 0) { 227 return ( BlockHeader*)(allocator.get_block(_ptr, block_size));133 return (CABlockHeader*)(allocator.get_block(_ptr, block_size)); 228 134 } else { 229 BlockHeader* node = root;135 CABlockHeader* node = root; 230 136 do { 231 137 if (_ptr < node) { … … 238 144 return null; 239 145 } 240 #if 0241 else {242 BlockHeader* p = block_list.next;243 while (p != &block_list) {244 if ((_ptr >= p) && (_ptr < ptr_add_offset(p, block_size))) return p;245 }246 return null;247 }248 #endif249 }250 251 static BlockHeader* node_rotate_left (252 BlockHeader* _node253 )254 {255 BlockHeader* right;256 int a_bal, b_bal;257 258 right = _node->right;259 260 _node->right = right->left;261 right->left = _node;262 263 a_bal = _node->balance;264 b_bal = right->balance;265 266 if (b_bal <= 0) {267 if (a_bal >= 1) right->balance = b_bal - 1;268 else right->balance = a_bal + b_bal - 2;269 _node->balance = a_bal - 1;270 } else {271 if (a_bal <= b_bal) right->balance = a_bal - 2;272 else right->balance = b_bal - 1;273 _node->balance = a_bal - b_bal - 1;274 }275 276 return right;277 }278 279 static BlockHeader* node_rotate_right (280 BlockHeader* _node281 )282 {283 BlockHeader* left;284 int a_bal, b_bal;285 286 left = _node->left;287 288 _node->left = left->right;289 left->right = _node;290 291 a_bal = _node->balance;292 b_bal = left->balance;293 294 if (b_bal <= 0) {295 if (b_bal > a_bal) left->balance = b_bal + 1;296 else left->balance = a_bal + 2;297 _node->balance = a_bal - b_bal + 1;298 } else {299 if (a_bal <= -1) left->balance = b_bal + 1;300 else left->balance = a_bal + b_bal + 2;301 _node->balance = a_bal + 1;302 }303 304 return left;305 }306 307 static BlockHeader* node_balance (308 BlockHeader* _node309 )310 {311 if (_node->balance < -1) {312 if (_node->left->balance > 0)313 _node->left = node_rotate_left(_node->left);314 _node = node_rotate_right(_node);315 } else {316 if (_node->right->balance < 0)317 _node->right = node_rotate_right(_node->right);318 _node = node_rotate_left(_node);319 }320 return _node;321 }322 323 static BlockHeader* node_insert (324 BlockHeader* _node,325 BlockHeader* _key326 )327 {328 int old_balance;329 if (_key < _node) {330 if (_node->left != null) {331 old_balance = _node->left->balance;332 _node->left = node_insert(_node->left, _key);333 if ((old_balance != _node->left->balance) && (_node->left->balance != 0))334 _node->balance -= 1;335 } else {336 _node->left = _key;337 _node->balance -= 1;338 }339 } else {340 if (_node->right != null) {341 old_balance = _node->right->balance;342 _node->right = node_insert(_node->right, _key);343 if ((old_balance != _node->right->balance) && (_node->right->balance != 0))344 _node->balance += 1;345 } else {346 _node->right = _key;347 _node->balance += 1;348 }349 }350 if ((_node->balance < -1) || (_node->balance > 1))351 _node = node_balance(_node);352 return _node;353 146 } 354 147 355 148 template <typename type_t> 356 inline void ChunkAllocator<type_t>::init_block (BlockHeader* _ptr)149 void ChunkAllocator<type_t>::init_block (CABlockHeader* _ptr) 357 150 { 358 151 _ptr->prev = block_list.prev; … … 361 154 _ptr->ref_count = 0; 362 155 363 FreeList* p = (FreeList*)ptr_add_offset(_ptr, sizeof( BlockHeader));156 FreeList* p = (FreeList*)ptr_add_offset(_ptr, sizeof(CABlockHeader)); 364 157 FreeList* q = (FreeList*)ptr_add_offset(p, (nchunks - 1) * chunk_size); 365 158 p->prev = &free_list; … … 377 170 _ptr->balance = 0; 378 171 if (root == null) root = _ptr; 379 else root = node_insert(root,_ptr);172 else root = root->node_insert(_ptr); 380 173 } 381 174 }
Note: See TracChangeset
for help on using the changeset viewer.