Changeset 394 for soft/giet_vm/giet_libs/malloc.c
- Timestamp:
- Aug 11, 2014, 9:32:24 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_libs/malloc.c
r390 r394 46 46 (size <= 0x80000000) ? 31 :\ 47 47 32 48 //////////////////////////////// 49 void heap_init( unsigned int x, 50 unsigned int y ) 51 { 52 unsigned int heap_base; // heap segment base 53 unsigned int heap_size; // heap segment size 54 unsigned int heap_index; // size_index in free[array] 55 56 unsigned int alloc_base; // alloc[] array base 57 unsigned int alloc_size; // alloc[] array size 58 unsigned int alloc_index; // size_index in free[array] 59 60 unsigned int index; // iterator 61 62 // get heap_base, heap size, and heap index 63 giet_heap_info( &heap_base, &heap_size, x, y ); 64 heap_index = GET_SIZE_INDEX( heap_size ); 65 66 // checking heap segment constraints 67 if ( heap_size == 0 ) // heap segment exist 68 { 69 giet_exit("ERROR in malloc() : heap not found \n"); 70 } 71 if ( heap_size != (1<<heap_index) ) // heap size power of 2 72 { 73 giet_exit("ERROR in malloc() : heap size must be power of 2\n"); 74 } 75 if ( heap_base % heap_size ) // heap segment aligned 76 { 77 giet_exit("ERROR in malloc() : heap segment must be aligned\n"); 78 } 79 80 // compute size of block containin alloc[] array 81 alloc_size = heap_size / MIN_BLOCK_SIZE; 82 if ( alloc_size < MIN_BLOCK_SIZE) alloc_size = MIN_BLOCK_SIZE; 83 84 // get index for the corresponding block 85 alloc_index = GET_SIZE_INDEX( alloc_size ); 86 87 // compute alloc[] array base address 88 alloc_base = heap_base + heap_size - alloc_size; 89 90 // reset the free[] array 91 for ( index = 0 ; index < 32 ; index++ ) 92 { 93 heap[x][y].free[index] = 0; 94 } 95 96 // split the heap into various sizes blocks, 97 // initializes the free[] array and NEXT pointers 98 // base is the block base address 99 unsigned int base = heap_base; 100 unsigned int* ptr; 101 for ( index = heap_index-1 ; index >= alloc_index ; index-- ) 102 { 103 heap[x][y].free[index] = base; 104 ptr = (unsigned int*)base; 105 *ptr = 0; 106 base = base + (1<<index); 107 } 108 109 heap[x][y].init = HEAP_INITIALIZED; 110 heap[x][y].x = x; 111 heap[x][y].y = y; 112 heap[x][y].heap_base = heap_base; 113 heap[x][y].heap_size = heap_size; 114 heap[x][y].alloc_size = alloc_size; 115 heap[x][y].alloc_base = alloc_base; 116 117 lock_release( &heap[x][y].lock ); 118 119 #if GIET_DEBUG_MALLOC 120 giet_shr_printf("\n[MALLOC DEBUG] Heap[%d][%d] initialisation\n" 121 " - heap_base = %x\n" 122 " - heap_size = %x\n" 123 " - alloc_base = %x\n" 124 " - alloc_size = %x\n" 125 " - free[0] = %x\n" 126 " - free[1] = %x\n" 127 " - free[2] = %x\n" 128 " - free[3] = %x\n" 129 " - free[4] = %x\n" 130 " - free[5] = %x\n" 131 " - free[6] = %x\n" 132 " - free[7] = %x\n" 133 " - free[8] = %x\n" 134 " - free[9] = %x\n" 135 " - free[10] = %x\n" 136 " - free[11] = %x\n" 137 " - free[12] = %x\n" 138 " - free[13] = %x\n" 139 " - free[14] = %x\n" 140 " - free[15] = %x\n" 141 " - free[16] = %x\n" 142 " - free[17] = %x\n" 143 " - free[18] = %x\n" 144 " - free[19] = %x\n" 145 " - free[20] = %x\n" 146 " - free[21] = %x\n" 147 " - free[22] = %x\n" 148 " - free[23] = %x\n", 48 //////////////////////////////////////// 49 void display_free_array( unsigned int x, 50 unsigned int y ) 51 { 52 giet_shr_printf( 53 " - coordinates = [%d][%d]\n" 54 " - heap_base = %x\n" 55 " - heap_size = %x\n" 56 " - alloc_base = %x\n" 57 " - alloc_size = %x\n" 58 " - free[0] = %x\n" 59 " - free[1] = %x\n" 60 " - free[2] = %x\n" 61 " - free[3] = %x\n" 62 " - free[4] = %x\n" 63 " - free[5] = %x\n" 64 " - free[6] = %x\n" 65 " - free[7] = %x\n" 66 " - free[8] = %x\n" 67 " - free[9] = %x\n" 68 " - free[10] = %x\n" 69 " - free[11] = %x\n" 70 " - free[12] = %x\n" 71 " - free[13] = %x\n" 72 " - free[14] = %x\n" 73 " - free[15] = %x\n" 74 " - free[16] = %x\n" 75 " - free[17] = %x\n" 76 " - free[18] = %x\n" 77 " - free[19] = %x\n" 78 " - free[20] = %x\n" 79 " - free[21] = %x\n" 80 " - free[22] = %x\n" 81 " - free[23] = %x\n", 149 82 heap[x][y].x, heap[x][y].y, 150 83 heap[x][y].heap_base, heap[x][y].heap_size, … … 162 95 heap[x][y].free[20], heap[x][y].free[21], 163 96 heap[x][y].free[22], heap[x][y].free[23] ); 97 } // end display_free array() 98 99 //////////////////////////////// 100 void heap_init( unsigned int x, 101 unsigned int y ) 102 { 103 unsigned int heap_base; // heap segment base 104 unsigned int heap_size; // heap segment size 105 unsigned int heap_index; // size_index in free[array] 106 107 unsigned int alloc_base; // alloc[] array base 108 unsigned int alloc_size; // alloc[] array size 109 unsigned int alloc_index; // size_index in free[array] 110 111 unsigned int index; // iterator 112 113 // get heap_base, heap size, and heap index 114 giet_heap_info( &heap_base, &heap_size, x, y ); 115 heap_index = GET_SIZE_INDEX( heap_size ); 116 117 // checking heap segment constraints 118 if ( heap_size == 0 ) // heap segment exist 119 { 120 giet_exit("ERROR in malloc() : heap not found \n"); 121 } 122 if ( heap_size != (1<<heap_index) ) // heap size power of 2 123 { 124 giet_exit("ERROR in malloc() : heap size must be power of 2\n"); 125 } 126 if ( heap_base % heap_size ) // heap segment aligned 127 { 128 giet_exit("ERROR in malloc() : heap segment must be aligned\n"); 129 } 130 131 // compute size of block containin alloc[] array 132 alloc_size = heap_size / MIN_BLOCK_SIZE; 133 if ( alloc_size < MIN_BLOCK_SIZE) alloc_size = MIN_BLOCK_SIZE; 134 135 // get index for the corresponding block 136 alloc_index = GET_SIZE_INDEX( alloc_size ); 137 138 // compute alloc[] array base address 139 alloc_base = heap_base + heap_size - alloc_size; 140 141 // reset the free[] array 142 for ( index = 0 ; index < 32 ; index++ ) 143 { 144 heap[x][y].free[index] = 0; 145 } 146 147 // split the heap into various sizes blocks, 148 // initializes the free[] array and NEXT pointers 149 // base is the block base address 150 unsigned int base = heap_base; 151 unsigned int* ptr; 152 for ( index = heap_index-1 ; index >= alloc_index ; index-- ) 153 { 154 heap[x][y].free[index] = base; 155 ptr = (unsigned int*)base; 156 *ptr = 0; 157 base = base + (1<<index); 158 } 159 160 heap[x][y].init = HEAP_INITIALIZED; 161 heap[x][y].x = x; 162 heap[x][y].y = y; 163 heap[x][y].heap_base = heap_base; 164 heap[x][y].heap_size = heap_size; 165 heap[x][y].alloc_size = alloc_size; 166 heap[x][y].alloc_base = alloc_base; 167 168 lock_release( &heap[x][y].lock ); 169 170 #if GIET_DEBUG_MALLOC 171 giet_shr_printf("\n[MALLOC DEBUG] Completing Heap[%d][%d] initialisation\n", x, y ); 172 display_free_array(x,y); 164 173 #endif 165 174 … … 254 263 unsigned int requested_index = GET_SIZE_INDEX( size ); 255 264 256 // take the lock protecting access to heap (x,y)265 // take the lock protecting access to heap[x][y] 257 266 lock_acquire( &heap[x][y].lock ); 258 267 … … 273 282 lock_release( &heap[x][y].lock ); 274 283 284 #if GIET_DEBUG_MALLOC 285 giet_shr_printf("\n[MALLOC DEBUG] Malloc for Heap[%d][%d] / size = %x / base = %x\n", 286 x, y, size, base ); 287 display_free_array(x,y); 288 #endif 289 275 290 return (void*)base; 276 291 … … 289 304 } 290 305 306 /////////////////////////////////////////// 307 void update_free_array( giet_heap_t* heap, 308 unsigned int base, 309 unsigned int size_index ) 310 { 311 // This recursive function try to merge the released block 312 // with the companion block if this companion block is free. 313 // This companion has the same size, and almost the same address 314 // (only one address bit is different) 315 // - If the companion is not in free[size_index], 316 // the released block is pushed in free[size_index]. 317 // - If the companion is found, it is evicted from free[size_index] 318 // and the merged bloc is pushed in the free[size_index+1]. 319 320 321 // compute released block size 322 unsigned int size = 1<<size_index; 323 324 // compute companion_base and merged_base 325 unsigned int companion_base; // companion block base address 326 unsigned int merged_base; // merged block base address 327 if ( base % (size<<1) ) 328 { 329 companion_base = base + size; 330 merged_base = base; 331 } 332 else 333 { 334 companion_base = base - size; 335 merged_base = base - size; 336 } 337 338 // scan all blocks in free[size_index] 339 // the iter & prev variables are actually addresses 340 unsigned int found = 0; 341 unsigned int iter = heap->free[size_index]; 342 unsigned int prev = (unsigned int)&heap->free[size_index]; 343 while ( iter != 0 ) 344 { 345 if ( iter == companion_base ) 346 { 347 found = 1; 348 break; 349 } 350 iter = *(unsigned int*)iter; 351 prev = iter; 352 } 353 354 if ( found == 0 ) // Companion not found 355 { 356 // push the block in free[size_index] 357 *(unsigned int*)base = heap->free[size_index]; 358 heap->free[size_index] = base; 359 } 360 else // Companion found : merge 361 { 362 // evict the searched block from free[size_index] 363 *(unsigned int*)prev = *(unsigned int*)iter; 364 365 // call the update_free() function for free[size_index+1] 366 update_free_array( heap, merged_base , size_index+1 ); 367 } 368 } 291 369 292 370 ////////////////////// 293 371 void free( void* ptr ) 294 372 { 295 unsigned int vaddr = (unsigned int)ptr; 296 297 // get the cluster coordinate 373 // get the cluster coordinate from ptr value 298 374 unsigned int x; 299 375 unsigned int y; 300 376 giet_get_xy( ptr, &x, &y ); 301 377 302 // compute index in alloc[] array 303 unsigned index = ( (unsigned int)ptr - heap[x][y].heap_base ) / MAX_BLOCK_SIZE; 378 // get the lock protecting heap[x][y] 379 lock_acquire( &heap[x][y].lock ); 380 381 // check ptr value 382 unsigned int base = (unsigned int)ptr; 383 if ( (base < heap[x][y].heap_base) || 384 (base >= (heap[x][y].heap_base + heap[x][y].heap_size)) ) 385 { 386 giet_exit("ERROR in free() : illegal pointer for released block"); 387 } 304 388 305 // get the freed block size_index 306 unsigned char* p i = (unsigned char*)(heap[x][y].alloc_base + index); 307 unsigned int size_index = (unsigned int)*p; 308 309 // update the free[] array and NEXT pointer 310 *(unsigned int*)ptr = heap[x][y].free[size_index]; 311 heap[x][y].free[size_index] = (unsigned int)ptr; 312 313 // TODO try to concatenate with another free block of same size 314 // this require probably to replace this simple push by a recursive function 315 } 389 // compute released block index in alloc[] array 390 unsigned index = (base - heap[x][y].heap_base ) / MIN_BLOCK_SIZE; 391 392 // get the released block size_index 393 unsigned char* pchar = (unsigned char*)(heap[x][y].alloc_base + index); 394 unsigned int size_index = (unsigned int)*pchar; 395 396 // check released block alignment 397 if ( base % (1 << size_index) ) 398 { 399 giet_exit("ERROR in free() : released block not aligned"); 400 } 401 402 // call the recursive function update_free_array() 403 update_free_array( &heap[x][y], base, size_index ); 404 405 // release the lock 406 lock_release( &heap[x][y].lock ); 407 408 #if GIET_DEBUG_MALLOC 409 giet_shr_printf("\n[MALLOC DEBUG] Free for Heap[%d][%d] / base = %x / size = %x\n", 410 x, y, base, 1<<size_index ); 411 display_free_array(x,y); 412 #endif 413 414 } // end free() 316 415 317 416
Note: See TracChangeset
for help on using the changeset viewer.