Changes in uspace/lib/c/generic/malloc.c [3292623:63f8966] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/malloc.c
r3292623 r63f8966 43 43 #include <bitops.h> 44 44 #include <mem.h> 45 #include <futex.h>46 45 #include <adt/gcdlcm.h> 47 46 … … 76 75 #define NET_SIZE(size) ((size) - STRUCT_OVERHEAD) 77 76 77 78 78 /** Header of a heap block 79 79 * … … 104 104 extern char _heap; 105 105 106 /** Futex for thread-safe heap manipulation */107 static futex_t malloc_futex = FUTEX_INITIALIZER;108 109 106 /** Address of heap start */ 110 107 static void *heap_start = 0; … … 122 119 * 123 120 * Fills in the structures related to a heap block. 124 * Should be called only inside the critical section.125 121 * 126 122 * @param addr Address of the block. … … 148 144 * Verifies that the structures related to a heap block still contain 149 145 * the magic constants. This helps detect heap corruption early on. 150 * Should be called only inside the critical section.151 146 * 152 147 * @param addr Address of the block. … … 166 161 } 167 162 168 /** Increase the heap area size169 *170 * Should be called only inside the critical section.171 *172 * @param size Number of bytes to grow the heap by.173 *174 */175 163 static bool grow_heap(size_t size) 176 164 { … … 201 189 } 202 190 203 /** Decrease the heap area204 *205 * Should be called only inside the critical section.206 *207 * @param size Number of bytes to shrink the heap by.208 *209 */210 191 static void shrink_heap(void) 211 192 { … … 215 196 /** Initialize the heap allocator 216 197 * 217 * Find how much physical memory we have and create198 * Finds how much physical memory we have and creates 218 199 * the heap management structures that mark the whole 219 200 * physical memory as a single free block. … … 222 203 void __heap_init(void) 223 204 { 224 futex_down(&malloc_futex);225 226 205 if (as_area_create((void *) &_heap, PAGE_SIZE, 227 206 AS_AREA_WRITE | AS_AREA_READ)) { … … 234 213 block_init(heap_start, heap_end - heap_start, true); 235 214 } 236 237 futex_up(&malloc_futex); 238 } 239 240 /** Get maximum heap address 241 * 242 */ 215 } 216 243 217 uintptr_t get_max_heap_addr(void) 244 218 { 245 futex_down(&malloc_futex);246 247 219 if (max_heap_size == (size_t) -1) 248 220 max_heap_size = 249 221 max((size_t) (heap_end - heap_start), MAX_HEAP_SIZE); 250 222 251 uintptr_t max_heap_addr = (uintptr_t) heap_start + max_heap_size; 252 253 futex_up(&malloc_futex); 254 255 return max_heap_addr; 256 } 257 258 /** Split heap block and mark it as used. 259 * 260 * Should be called only inside the critical section. 261 * 262 * @param cur Heap block to split. 263 * @param size Number of bytes to split and mark from the beginning 264 * of the block. 265 * 266 */ 223 return ((uintptr_t) heap_start + max_heap_size); 224 } 225 267 226 static void split_mark(heap_block_head_t *cur, const size_t size) 268 227 { … … 284 243 285 244 /** Allocate a memory block 286 *287 * Should be called only inside the critical section.288 245 * 289 246 * @param size The size of the block to allocate. … … 399 356 } 400 357 401 /** Allocate memory by number of elements402 *403 * @param nmemb Number of members to allocate.404 * @param size Size of one member in bytes.405 *406 * @return Allocated memory or NULL.407 *408 */409 358 void *calloc(const size_t nmemb, const size_t size) 410 359 { … … 412 361 if (block == NULL) 413 362 return NULL; 414 363 415 364 memset(block, 0, nmemb * size); 416 365 return block; 417 366 } 418 367 419 /** Allocate memory420 *421 * @param size Number of bytes to allocate.422 *423 * @return Allocated memory or NULL.424 *425 */426 368 void *malloc(const size_t size) 427 369 { 428 futex_down(&malloc_futex); 429 void *block = malloc_internal(size, BASE_ALIGN); 430 futex_up(&malloc_futex); 431 432 return block; 433 } 434 435 /** Allocate memory with specified alignment 436 * 437 * @param align Alignment in byes. 438 * @param size Number of bytes to allocate. 439 * 440 * @return Allocated memory or NULL. 441 * 442 */ 370 return malloc_internal(size, BASE_ALIGN); 371 } 372 443 373 void *memalign(const size_t align, const size_t size) 444 374 { … … 449 379 1 << (fnzb(max(sizeof(void *), align) - 1) + 1); 450 380 451 futex_down(&malloc_futex); 452 void *block = malloc_internal(size, palign); 453 futex_up(&malloc_futex); 454 455 return block; 456 } 457 458 /** Reallocate memory block 459 * 460 * @param addr Already allocated memory or NULL. 461 * @param size New size of the memory block. 462 * 463 * @return Reallocated memory or NULL. 464 * 465 */ 381 return malloc_internal(size, palign); 382 } 383 466 384 void *realloc(const void *addr, const size_t size) 467 385 { 468 386 if (addr == NULL) 469 387 return malloc(size); 470 471 futex_down(&malloc_futex);472 388 473 389 /* Calculate the position of the header. */ … … 482 398 483 399 void *ptr = NULL; 484 bool reloc = false;485 400 size_t real_size = GROSS_SIZE(ALIGN_UP(size, BASE_ALIGN)); 486 401 size_t orig_size = head->size; … … 500 415 } else { 501 416 /* Look at the next block. If it is free and the size is 502 sufficient then merge the two. Otherwise just allocate 503 a new block, copy the original data into it and 504 free the original block. */ 417 sufficient then merge the two. */ 505 418 heap_block_head_t *next_head = 506 419 (heap_block_head_t *) (((void *) head) + head->size); … … 514 427 515 428 ptr = ((void *) head) + sizeof(heap_block_head_t); 516 } else 517 reloc = true; 518 } 519 520 futex_up(&malloc_futex); 521 522 if (reloc) { 523 ptr = malloc(size); 524 if (ptr != NULL) { 525 memcpy(ptr, addr, NET_SIZE(orig_size)); 526 free(addr); 429 } else { 430 ptr = malloc(size); 431 if (ptr != NULL) { 432 memcpy(ptr, addr, NET_SIZE(orig_size)); 433 free(addr); 434 } 527 435 } 528 436 } … … 534 442 * 535 443 * @param addr The address of the block. 536 *537 444 */ 538 445 void free(const void *addr) 539 446 { 540 futex_down(&malloc_futex);541 542 447 /* Calculate the position of the header. */ 543 448 heap_block_head_t *head … … 578 483 579 484 shrink_heap(); 580 581 futex_up(&malloc_futex);582 485 } 583 486
Note:
See TracChangeset
for help on using the changeset viewer.