Changes in uspace/lib/c/generic/malloc.c [3e6a98c5:fbcdeb8] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/malloc.c
r3e6a98c5 rfbcdeb8 35 35 36 36 #include <malloc.h> 37 #include < stdbool.h>37 #include <bool.h> 38 38 #include <as.h> 39 39 #include <align.h> … … 109 109 (((uintptr_t) (area)->end) - sizeof(heap_block_foot_t)) 110 110 111 #define AREA_LAST_BLOCK_HEAD(area) \112 ((uintptr_t) BLOCK_HEAD(((heap_block_foot_t *) AREA_LAST_BLOCK_FOOT(area))))113 114 111 /** Get header in heap block. 115 112 * … … 288 285 /* Align the heap area size on page boundary */ 289 286 size_t asize = ALIGN_UP(size, PAGE_SIZE); 290 void *astart = as_area_create( AS_AREA_ANY, asize,291 AS_AREA_WRITE | AS_AREA_READ | AS_AREA_CACHEABLE);292 if (astart == AS_MAP_FAILED)287 void *astart = as_area_create((void *) -1, asize, 288 AS_AREA_WRITE | AS_AREA_READ); 289 if (astart == (void *) -1) 293 290 return false; 294 291 … … 349 346 return false; 350 347 351 heap_block_head_t *last_head = 352 (heap_block_head_t *) AREA_LAST_BLOCK_HEAD(area); 353 354 if (last_head->free) { 355 /* Add the new space to the last block. */ 356 size_t net_size = (size_t) (end - area->end) + last_head->size; 357 malloc_assert(net_size > 0); 358 block_init(last_head, net_size, true, area); 359 } else { 360 /* Add new free block */ 361 size_t net_size = (size_t) (end - area->end); 362 if (net_size > 0) 363 block_init(area->end, net_size, true, area); 364 } 348 /* Add new free block */ 349 size_t net_size = (size_t) (end - area->end); 350 if (net_size > 0) 351 block_init(area->end, net_size, true, area); 365 352 366 353 /* Update heap area parameters */ … … 368 355 369 356 return true; 357 } 358 359 /** Try to enlarge any of the heap areas 360 * 361 * Should be called only inside the critical section. 362 * 363 * @param size Gross size of item to allocate (bytes). 364 * 365 */ 366 static bool heap_grow(size_t size) 367 { 368 if (size == 0) 369 return true; 370 371 /* First try to enlarge some existing area */ 372 for (heap_area_t *area = first_heap_area; area != NULL; 373 area = area->next) { 374 if (area_grow(area, size)) 375 return true; 376 } 377 378 /* Eventually try to create a new area */ 379 return area_create(AREA_OVERHEAD(size)); 370 380 } 371 381 … … 651 661 } 652 662 653 /** Try to enlarge any of the heap areas.654 *655 * If successful, allocate block of the given size in the area.656 * Should be called only inside the critical section.657 *658 * @param size Gross size of item to allocate (bytes).659 * @param align Memory address alignment.660 *661 * @return Allocated block.662 * @return NULL on failure.663 *664 */665 static void *heap_grow_and_alloc(size_t size, size_t align)666 {667 if (size == 0)668 return NULL;669 670 /* First try to enlarge some existing area */671 for (heap_area_t *area = first_heap_area; area != NULL;672 area = area->next) {673 674 if (area_grow(area, size + align)) {675 heap_block_head_t *first =676 (heap_block_head_t *) AREA_LAST_BLOCK_HEAD(area);677 678 void *addr =679 malloc_area(area, first, NULL, size, align);680 malloc_assert(addr != NULL);681 return addr;682 }683 }684 685 /* Eventually try to create a new area */686 if (area_create(AREA_OVERHEAD(size + align))) {687 heap_block_head_t *first =688 (heap_block_head_t *) AREA_FIRST_BLOCK_HEAD(last_heap_area);689 690 void *addr =691 malloc_area(last_heap_area, first, NULL, size, align);692 malloc_assert(addr != NULL);693 return addr;694 }695 696 return NULL;697 }698 699 663 /** Allocate a memory block 700 664 * … … 715 679 716 680 size_t falign = lcm(align, BASE_ALIGN); 717 718 /* Check for integer overflow. */ 719 if (falign < align) 720 return NULL; 721 722 /* 723 * The size of the allocated block needs to be naturally 724 * aligned, because the footer structure also needs to reside 725 * on a naturally aligned address in order to avoid unaligned 726 * memory accesses. 727 */ 728 size_t gross_size = GROSS_SIZE(ALIGN_UP(size, BASE_ALIGN)); 681 size_t real_size = GROSS_SIZE(ALIGN_UP(size, falign)); 682 683 bool retry = false; 684 heap_block_head_t *split; 685 686 loop: 729 687 730 688 /* Try the next fit approach */ 731 heap_block_head_t *split = next_fit;689 split = next_fit; 732 690 733 691 if (split != NULL) { 734 void *addr = malloc_area(split->area, split, NULL, gross_size,692 void *addr = malloc_area(split->area, split, NULL, real_size, 735 693 falign); 736 694 … … 745 703 AREA_FIRST_BLOCK_HEAD(area); 746 704 747 void *addr = malloc_area(area, first, split, gross_size,705 void *addr = malloc_area(area, first, split, real_size, 748 706 falign); 749 707 … … 752 710 } 753 711 754 /* Finally, try to grow heap space and allocate in the new area. */ 755 return heap_grow_and_alloc(gross_size, falign); 712 if (!retry) { 713 /* Try to grow the heap space */ 714 if (heap_grow(real_size)) { 715 retry = true; 716 goto loop; 717 } 718 } 719 720 return NULL; 756 721 } 757 722 … … 766 731 void *calloc(const size_t nmemb, const size_t size) 767 732 { 768 // FIXME: Check for overflow769 770 733 void *block = malloc(nmemb * size); 771 734 if (block == NULL) … … 907 870 if (addr == NULL) 908 871 return; 909 872 910 873 futex_down(&malloc_futex); 911 874
Note:
See TracChangeset
for help on using the changeset viewer.