Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/malloc.c

    re6eee2b r207533f  
    7979        (sizeof(heap_block_head_t) + sizeof(heap_block_foot_t))
    8080
     81/** Overhead of each area. */
     82#define AREA_OVERHEAD(size) \
     83        (ALIGN_UP(size + sizeof(heap_area_t), BASE_ALIGN))
     84
    8185/** Calculate real size of a heap block.
    8286 *
     
    183187
    184188/** Next heap block to examine (next fit algorithm) */
    185 static heap_block_head_t *next = NULL;
     189static heap_block_head_t *next_fit = NULL;
    186190
    187191/** Futex for thread-safe heap manipulation */
    188192static futex_t malloc_futex = FUTEX_INITIALIZER;
     193
     194#ifndef NDEBUG
     195
     196#define malloc_assert(expr) \
     197        do { \
     198                if (!(expr)) {\
     199                        futex_up(&malloc_futex); \
     200                        assert_abort(#expr, __FILE__, __LINE__); \
     201                } \
     202        } while (0)
     203
     204#else /* NDEBUG */
     205
     206#define malloc_assert(expr)
     207
     208#endif /* NDEBUG */
    189209
    190210/** Initialize a heap block
     
    228248        heap_block_head_t *head = (heap_block_head_t *) addr;
    229249       
    230         assert(head->magic == HEAP_BLOCK_HEAD_MAGIC);
     250        malloc_assert(head->magic == HEAP_BLOCK_HEAD_MAGIC);
    231251       
    232252        heap_block_foot_t *foot = BLOCK_FOOT(head);
    233253       
    234         assert(foot->magic == HEAP_BLOCK_FOOT_MAGIC);
    235         assert(head->size == foot->size);
     254        malloc_assert(foot->magic == HEAP_BLOCK_FOOT_MAGIC);
     255        malloc_assert(head->size == foot->size);
    236256}
    237257
     
    247267        heap_area_t *area = (heap_area_t *) addr;
    248268       
    249         assert(area->magic == HEAP_AREA_MAGIC);
    250         assert(addr == area->start);
    251         assert(area->start < area->end);
    252         assert(((uintptr_t) area->start % PAGE_SIZE) == 0);
    253         assert(((uintptr_t) area->end % PAGE_SIZE) == 0);
     269        malloc_assert(area->magic == HEAP_AREA_MAGIC);
     270        malloc_assert(addr == area->start);
     271        malloc_assert(area->start < area->end);
     272        malloc_assert(((uintptr_t) area->start % PAGE_SIZE) == 0);
     273        malloc_assert(((uintptr_t) area->end % PAGE_SIZE) == 0);
    254274}
    255275
     
    362382       
    363383        /* Eventually try to create a new area */
    364         return area_create(AREA_FIRST_BLOCK_HEAD(size));
     384        return area_create(AREA_OVERHEAD(size));
    365385}
    366386
     
    382402       
    383403        block_check((void *) last_head);
    384         assert(last_head->area == area);
     404        malloc_assert(last_head->area == area);
    385405       
    386406        if (last_head->free) {
     
    395415               
    396416                block_check((void *) first_head);
    397                 assert(first_head->area == area);
     417                malloc_assert(first_head->area == area);
    398418               
    399419                size_t shrink_size = ALIGN_DOWN(last_head->size, PAGE_SIZE);
     
    439459                        /* Update heap area parameters */
    440460                        area->end = end;
    441                        
    442                         /* Update block layout */
    443                         void *last = (void *) last_head;
    444                         size_t excess = (size_t) (area->end - last);
     461                        size_t excess = ((size_t) area->end) - ((size_t) last_head);
    445462                       
    446463                        if (excess > 0) {
     
    451468                                         * create a new free block.
    452469                                         */
    453                                         block_init(last, excess, true, area);
     470                                        block_init((void *) last_head, excess, true, area);
    454471                                } else {
    455472                                        /*
     
    470487        }
    471488       
    472         next = NULL;
     489        next_fit = NULL;
    473490}
    474491
     
    497514static void split_mark(heap_block_head_t *cur, const size_t size)
    498515{
    499         assert(cur->size >= size);
     516        malloc_assert(cur->size >= size);
    500517       
    501518        /* See if we should split the block. */
     
    533550{
    534551        area_check((void *) area);
    535         assert((void *) first_block >= (void *) AREA_FIRST_BLOCK_HEAD(area));
    536         assert((void *) first_block < area->end);
     552        malloc_assert((void *) first_block >= (void *) AREA_FIRST_BLOCK_HEAD(area));
     553        malloc_assert((void *) first_block < area->end);
    537554       
    538555        for (heap_block_head_t *cur = first_block; (void *) cur < area->end;
     
    559576                                split_mark(cur, real_size);
    560577                               
    561                                 next = cur;
     578                                next_fit = cur;
    562579                                return addr;
    563580                        } else {
     
    611628                                                split_mark(next_head, real_size);
    612629                                               
    613                                                 next = next_head;
     630                                                next_fit = next_head;
    614631                                                return aligned;
    615632                                        } else {
     
    637654                                                        split_mark(cur, real_size);
    638655                                                       
    639                                                         next = cur;
     656                                                        next_fit = cur;
    640657                                                        return aligned;
    641658                                                }
     
    661678static void *malloc_internal(const size_t size, const size_t align)
    662679{
    663         assert(first_heap_area != NULL);
     680        malloc_assert(first_heap_area != NULL);
    664681       
    665682        if (align == 0)
     
    675692       
    676693        /* Try the next fit approach */
    677         split = next;
     694        split = next_fit;
    678695       
    679696        if (split != NULL) {
     
    786803       
    787804        block_check(head);
    788         assert(!head->free);
     805        malloc_assert(!head->free);
    789806       
    790807        heap_area_t *area = head->area;
    791808       
    792809        area_check(area);
    793         assert((void *) head >= (void *) AREA_FIRST_BLOCK_HEAD(area));
    794         assert((void *) head < area->end);
     810        malloc_assert((void *) head >= (void *) AREA_FIRST_BLOCK_HEAD(area));
     811        malloc_assert((void *) head < area->end);
    795812       
    796813        void *ptr = NULL;
     
    831848                       
    832849                        ptr = ((void *) head) + sizeof(heap_block_head_t);
    833                         next = NULL;
     850                        next_fit = NULL;
    834851                } else
    835852                        reloc = true;
     
    863880       
    864881        block_check(head);
    865         assert(!head->free);
     882        malloc_assert(!head->free);
    866883       
    867884        heap_area_t *area = head->area;
    868885       
    869886        area_check(area);
    870         assert((void *) head >= (void *) AREA_FIRST_BLOCK_HEAD(area));
    871         assert((void *) head < area->end);
     887        malloc_assert((void *) head >= (void *) AREA_FIRST_BLOCK_HEAD(area));
     888        malloc_assert((void *) head < area->end);
    872889       
    873890        /* Mark the block itself as free. */
     
    904921}
    905922
     923void *heap_check(void)
     924{
     925        futex_down(&malloc_futex);
     926       
     927        if (first_heap_area == NULL) {
     928                futex_up(&malloc_futex);
     929                return (void *) -1;
     930        }
     931       
     932        /* Walk all heap areas */
     933        for (heap_area_t *area = first_heap_area; area != NULL;
     934            area = area->next) {
     935               
     936                /* Check heap area consistency */
     937                if ((area->magic != HEAP_AREA_MAGIC) ||
     938                    ((void *) area != area->start) ||
     939                    (area->start >= area->end) ||
     940                    (((uintptr_t) area->start % PAGE_SIZE) != 0) ||
     941                    (((uintptr_t) area->end % PAGE_SIZE) != 0)) {
     942                        futex_up(&malloc_futex);
     943                        return (void *) area;
     944                }
     945               
     946                /* Walk all heap blocks */
     947                for (heap_block_head_t *head = (heap_block_head_t *)
     948                    AREA_FIRST_BLOCK_HEAD(area); (void *) head < area->end;
     949                    head = (heap_block_head_t *) (((void *) head) + head->size)) {
     950                       
     951                        /* Check heap block consistency */
     952                        if (head->magic != HEAP_BLOCK_HEAD_MAGIC) {
     953                                futex_up(&malloc_futex);
     954                                return (void *) head;
     955                        }
     956                       
     957                        heap_block_foot_t *foot = BLOCK_FOOT(head);
     958                       
     959                        if ((foot->magic != HEAP_BLOCK_FOOT_MAGIC) ||
     960                            (head->size != foot->size)) {
     961                                futex_up(&malloc_futex);
     962                                return (void *) foot;
     963                        }
     964                }
     965        }
     966       
     967        futex_up(&malloc_futex);
     968       
     969        return NULL;
     970}
     971
    906972/** @}
    907973 */
Note: See TracChangeset for help on using the changeset viewer.