Ignore:
File:
1 edited

Legend:

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

    rd161715 r3292623  
    4444#include <mem.h>
    4545#include <futex.h>
    46 #include <stdlib.h>
    4746#include <adt/gcdlcm.h>
    48 #include "private/malloc.h"
    49 
    50 /** Magic used in heap headers. */
    51 #define HEAP_BLOCK_HEAD_MAGIC  UINT32_C(0xBEEF0101)
    52 
    53 /** Magic used in heap footers. */
    54 #define HEAP_BLOCK_FOOT_MAGIC  UINT32_C(0xBEEF0202)
    55 
    56 /** Magic used in heap descriptor. */
    57 #define HEAP_AREA_MAGIC  UINT32_C(0xBEEFCAFE)
    58 
    59 /** Allocation alignment.
    60  *
    61  * This also covers the alignment of fields
    62  * in the heap header and footer.
    63  *
    64  */
     47
     48/* Magic used in heap headers. */
     49#define HEAP_BLOCK_HEAD_MAGIC  0xBEEF0101
     50
     51/* Magic used in heap footers. */
     52#define HEAP_BLOCK_FOOT_MAGIC  0xBEEF0202
     53
     54/** Allocation alignment (this also covers the alignment of fields
     55    in the heap header and footer) */
    6556#define BASE_ALIGN  16
    6657
    67 /** Overhead of each heap block. */
    68 #define STRUCT_OVERHEAD \
    69         (sizeof(heap_block_head_t) + sizeof(heap_block_foot_t))
    70 
    71 /** Calculate real size of a heap block.
    72  *
    73  * Add header and footer size.
    74  *
     58/**
     59 * Either 4 * 256M on 32-bit architecures or 16 * 256M on 64-bit architectures
     60 */
     61#define MAX_HEAP_SIZE  (sizeof(uintptr_t) << 28)
     62
     63/**
     64 *
     65 */
     66#define STRUCT_OVERHEAD  (sizeof(heap_block_head_t) + sizeof(heap_block_foot_t))
     67
     68/**
     69 * Calculate real size of a heap block (with header and footer)
    7570 */
    7671#define GROSS_SIZE(size)  ((size) + STRUCT_OVERHEAD)
    7772
    78 /** Calculate net size of a heap block.
    79  *
    80  * Subtract header and footer size.
    81  *
     73/**
     74 * Calculate net size of a heap block (without header and footer)
    8275 */
    8376#define NET_SIZE(size)  ((size) - STRUCT_OVERHEAD)
    84 
    85 /** Get first block in heap area.
    86  *
    87  */
    88 #define AREA_FIRST_BLOCK(area) \
    89         (ALIGN_UP(((uintptr_t) (area)) + sizeof(heap_area_t), BASE_ALIGN))
    90 
    91 /** Get footer in heap block.
    92  *
    93  */
    94 #define BLOCK_FOOT(head) \
    95         ((heap_block_foot_t *) \
    96             (((uintptr_t) head) + head->size - sizeof(heap_block_foot_t)))
    97 
    98 /** Heap area.
    99  *
    100  * The memory managed by the heap allocator is divided into
    101  * multiple discontinuous heaps. Each heap is represented
    102  * by a separate address space area which has this structure
    103  * at its very beginning.
    104  *
    105  */
    106 typedef struct heap_area {
    107         /** Start of the heap area (including this structure)
    108          *
    109          * Aligned on page boundary.
    110          *
    111          */
    112         void *start;
    113        
    114         /** End of the heap area (aligned on page boundary) */
    115         void *end;
    116        
    117         /** Next heap area */
    118         struct heap_area *next;
    119        
    120         /** A magic value */
    121         uint32_t magic;
    122 } heap_area_t;
    12377
    12478/** Header of a heap block
     
    13286        bool free;
    13387       
    134         /** Heap area this block belongs to */
    135         heap_area_t *area;
    136        
    13788        /* A magic value to detect overwrite of heap header */
    13889        uint32_t magic;
     
    150101} heap_block_foot_t;
    151102
    152 /** First heap area */
    153 static heap_area_t *first_heap_area = NULL;
    154 
    155 /** Last heap area */
    156 static heap_area_t *last_heap_area = NULL;
    157 
    158 /** Next heap block to examine (next fit algorithm) */
    159 static heap_block_head_t *next = NULL;
     103/** Linker heap symbol */
     104extern char _heap;
    160105
    161106/** Futex for thread-safe heap manipulation */
    162107static futex_t malloc_futex = FUTEX_INITIALIZER;
    163108
     109/** Address of heap start */
     110static void *heap_start = 0;
     111
     112/** Address of heap end */
     113static void *heap_end = 0;
     114
     115/** Maximum heap size */
     116static size_t max_heap_size = (size_t) -1;
     117
     118/** Current number of pages of heap area */
     119static size_t heap_pages = 0;
     120
    164121/** Initialize a heap block
    165122 *
    166  * Fill in the structures related to a heap block.
     123 * Fills in the structures related to a heap block.
    167124 * Should be called only inside the critical section.
    168125 *
     
    170127 * @param size Size of the block including the header and the footer.
    171128 * @param free Indication of a free block.
    172  * @param area Heap area the block belongs to.
    173  *
    174  */
    175 static void block_init(void *addr, size_t size, bool free, heap_area_t *area)
     129 *
     130 */
     131static void block_init(void *addr, size_t size, bool free)
    176132{
    177133        /* Calculate the position of the header and the footer */
    178134        heap_block_head_t *head = (heap_block_head_t *) addr;
     135        heap_block_foot_t *foot =
     136            (heap_block_foot_t *) (addr + size - sizeof(heap_block_foot_t));
    179137       
    180138        head->size = size;
    181139        head->free = free;
    182         head->area = area;
    183140        head->magic = HEAP_BLOCK_HEAD_MAGIC;
    184        
    185         heap_block_foot_t *foot = BLOCK_FOOT(head);
    186141       
    187142        foot->size = size;
     
    204159        assert(head->magic == HEAP_BLOCK_HEAD_MAGIC);
    205160       
    206         heap_block_foot_t *foot = BLOCK_FOOT(head);
     161        heap_block_foot_t *foot =
     162            (heap_block_foot_t *) (addr + head->size - sizeof(heap_block_foot_t));
    207163       
    208164        assert(foot->magic == HEAP_BLOCK_FOOT_MAGIC);
     
    210166}
    211167
    212 /** Check a heap area structure
    213  *
    214  * @param addr Address of the heap area.
    215  *
    216  */
    217 static void area_check(void *addr)
    218 {
    219         heap_area_t *area = (heap_area_t *) addr;
    220        
    221         assert(area->magic == HEAP_AREA_MAGIC);
    222         assert(area->start < area->end);
    223         assert(((uintptr_t) area->start % PAGE_SIZE) == 0);
    224         assert(((uintptr_t) area->end % PAGE_SIZE) == 0);
    225 }
    226 
    227 /** Create new heap area
    228  *
    229  * @param start Preffered starting address of the new area.
    230  * @param size  Size of the area.
    231  *
    232  */
    233 static bool area_create(size_t size)
    234 {
    235         void *start = as_get_mappable_page(size);
    236         if (start == NULL)
     168/** Increase the heap area size
     169 *
     170 * Should be called only inside the critical section.
     171 *
     172 * @param size Number of bytes to grow the heap by.
     173 *
     174 */
     175static bool grow_heap(size_t size)
     176{
     177        if (size == 0)
    237178                return false;
    238        
    239         /* Align the heap area on page boundary */
    240         void *astart = (void *) ALIGN_UP((uintptr_t) start, PAGE_SIZE);
    241         size_t asize = ALIGN_UP(size, PAGE_SIZE);
    242        
    243         astart = as_area_create(astart, asize, AS_AREA_WRITE | AS_AREA_READ);
    244         if (astart == (void *) -1)
     179
     180        if ((heap_start + size < heap_start) || (heap_end + size < heap_end))
    245181                return false;
    246182       
    247         heap_area_t *area = (heap_area_t *) astart;
    248        
    249         area->start = astart;
    250         area->end = (void *)
    251             ALIGN_DOWN((uintptr_t) astart + asize, BASE_ALIGN);
    252         area->next = NULL;
    253         area->magic = HEAP_AREA_MAGIC;
    254        
    255         void *block = (void *) AREA_FIRST_BLOCK(area);
    256         size_t bsize = (size_t) (area->end - block);
    257        
    258         block_init(block, bsize, true, area);
    259        
    260         if (last_heap_area == NULL) {
    261                 first_heap_area = area;
    262                 last_heap_area = area;
    263         } else {
    264                 last_heap_area->next = area;
    265                 last_heap_area = area;
    266         }
    267        
    268         return true;
    269 }
    270 
    271 /** Try to enlarge a heap area
    272  *
    273  * @param area Heap area to grow.
    274  * @param size Gross size of item to allocate (bytes).
    275  *
    276  */
    277 static bool area_grow(heap_area_t *area, size_t size)
    278 {
    279         if (size == 0)
     183        size_t heap_size = (size_t) (heap_end - heap_start);
     184       
     185        if ((max_heap_size != (size_t) -1) && (heap_size + size > max_heap_size))
     186                return false;
     187       
     188        size_t pages = (size - 1) / PAGE_SIZE + 1;
     189       
     190        if (as_area_resize((void *) &_heap, (heap_pages + pages) * PAGE_SIZE, 0)
     191            == EOK) {
     192                void *end = (void *) ALIGN_DOWN(((uintptr_t) &_heap) +
     193                    (heap_pages + pages) * PAGE_SIZE, BASE_ALIGN);
     194                block_init(heap_end, end - heap_end, true);
     195                heap_pages += pages;
     196                heap_end = end;
    280197                return true;
    281        
    282         area_check(area);
    283        
    284         size_t asize = ALIGN_UP((size_t) (area->end - area->start) + size,
    285             PAGE_SIZE);
    286        
    287         /* New heap area size */
    288         void *end = (void *)
    289             ALIGN_DOWN((uintptr_t) area->start + asize, BASE_ALIGN);
    290        
    291         /* Check for overflow */
    292         if (end < area->start)
    293                 return false;
    294        
    295         /* Resize the address space area */
    296         int ret = as_area_resize(area->start, asize, 0);
    297         if (ret != EOK)
    298                 return false;
    299        
    300         /* Add new free block */
    301         block_init(area->end, (size_t) (end - area->end), true, area);
    302        
    303         /* Update heap area parameters */
    304         area->end = end;
    305        
    306         return true;
    307 }
    308 
    309 /** Try to enlarge any of the heap areas
    310  *
    311  * @param size Gross size of item to allocate (bytes).
    312  *
    313  */
    314 static bool heap_grow(size_t size)
    315 {
    316         if (size == 0)
    317                 return true;
    318        
    319         /* First try to enlarge some existing area */
    320         heap_area_t *area;
    321         for (area = first_heap_area; area != NULL; area = area->next) {
    322                 if (area_grow(area, size))
    323                         return true;
    324         }
    325        
    326         /* Eventually try to create a new area */
    327         return area_create(AREA_FIRST_BLOCK(size));
    328 }
    329 
    330 /** Try to shrink heap space
    331  *
    332  * In all cases the next pointer is reset.
    333  *
    334  */
    335 static void heap_shrink(void)
    336 {
    337         next = NULL;
     198        }
     199       
     200        return false;
     201}
     202
     203/** Decrease the heap area
     204 *
     205 * Should be called only inside the critical section.
     206 *
     207 * @param size Number of bytes to shrink the heap by.
     208 *
     209 */
     210static void shrink_heap(void)
     211{
     212        // TODO
    338213}
    339214
    340215/** Initialize the heap allocator
    341216 *
    342  * Create initial heap memory area. This routine is
    343  * only called from libc initialization, thus we do not
    344  * take any locks.
    345  *
    346  */
    347 void __malloc_init(void)
    348 {
    349         if (!area_create(PAGE_SIZE))
    350                 abort();
     217 * Find how much physical memory we have and create
     218 * the heap management structures that mark the whole
     219 * physical memory as a single free block.
     220 *
     221 */
     222void __heap_init(void)
     223{
     224        futex_down(&malloc_futex);
     225       
     226        if (as_area_create((void *) &_heap, PAGE_SIZE,
     227            AS_AREA_WRITE | AS_AREA_READ)) {
     228                heap_pages = 1;
     229                heap_start = (void *) ALIGN_UP((uintptr_t) &_heap, BASE_ALIGN);
     230                heap_end =
     231                    (void *) ALIGN_DOWN(((uintptr_t) &_heap) + PAGE_SIZE, BASE_ALIGN);
     232               
     233                /* Make the entire area one large block. */
     234                block_init(heap_start, heap_end - heap_start, true);
     235        }
     236       
     237        futex_up(&malloc_futex);
     238}
     239
     240/** Get maximum heap address
     241 *
     242 */
     243uintptr_t get_max_heap_addr(void)
     244{
     245        futex_down(&malloc_futex);
     246       
     247        if (max_heap_size == (size_t) -1)
     248                max_heap_size =
     249                    max((size_t) (heap_end - heap_start), MAX_HEAP_SIZE);
     250       
     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;
    351256}
    352257
     
    370275                /* Block big enough -> split. */
    371276                void *next = ((void *) cur) + size;
    372                 block_init(next, cur->size - size, true, cur->area);
    373                 block_init(cur, size, false, cur->area);
     277                block_init(next, cur->size - size, true);
     278                block_init(cur, size, false);
    374279        } else {
    375280                /* Block too small -> use as is. */
     
    378283}
    379284
    380 /** Allocate memory from heap area starting from given block
     285/** Allocate a memory block
    381286 *
    382287 * Should be called only inside the critical section.
    383  * As a side effect this function also sets the current
    384  * pointer on successful allocation.
    385  *
    386  * @param area        Heap area where to allocate from.
    387  * @param first_block Starting heap block.
    388  * @param final_block Heap block where to finish the search
    389  *                    (may be NULL).
    390  * @param real_size   Gross number of bytes to allocate.
    391  * @param falign      Physical alignment of the block.
    392  *
    393  * @return Address of the allocated block or NULL on not enough memory.
    394  *
    395  */
    396 static void *malloc_area(heap_area_t *area, heap_block_head_t *first_block,
    397     heap_block_head_t *final_block, size_t real_size, size_t falign)
    398 {
    399         area_check((void *) area);
    400         assert((void *) first_block >= (void *) AREA_FIRST_BLOCK(area));
    401         assert((void *) first_block < area->end);
    402        
    403         heap_block_head_t *cur;
    404         for (cur = first_block; (void *) cur < area->end;
    405             cur = (heap_block_head_t *) (((void *) cur) + cur->size)) {
     288 *
     289 * @param size  The size of the block to allocate.
     290 * @param align Memory address alignment.
     291 *
     292 * @return the address of the block or NULL when not enough memory.
     293 *
     294 */
     295static void *malloc_internal(const size_t size, const size_t align)
     296{
     297        if (align == 0)
     298                return NULL;
     299       
     300        size_t falign = lcm(align, BASE_ALIGN);
     301        size_t real_size = GROSS_SIZE(ALIGN_UP(size, falign));
     302       
     303        bool grown = false;
     304        void *result;
     305       
     306loop:
     307        result = NULL;
     308        heap_block_head_t *cur = (heap_block_head_t *) heap_start;
     309       
     310        while ((result == NULL) && ((void *) cur < heap_end)) {
    406311                block_check(cur);
    407                
    408                 /* Finish searching on the final block */
    409                 if ((final_block != NULL) && (cur == final_block))
    410                         break;
    411312               
    412313                /* Try to find a block that is free and large enough. */
    413314                if ((cur->free) && (cur->size >= real_size)) {
    414                         /*
    415                          * We have found a suitable block.
    416                          * Check for alignment properties.
    417                          */
    418                         void *addr = (void *)
    419                             ((uintptr_t) cur + sizeof(heap_block_head_t));
    420                         void *aligned = (void *)
    421                             ALIGN_UP((uintptr_t) addr, falign);
     315                        /* We have found a suitable block.
     316                           Check for alignment properties. */
     317                        void *addr = ((void *) cur) + sizeof(heap_block_head_t);
     318                        void *aligned = (void *) ALIGN_UP(addr, falign);
    422319                       
    423320                        if (addr == aligned) {
    424321                                /* Exact block start including alignment. */
    425322                                split_mark(cur, real_size);
    426                                
    427                                 next = cur;
    428                                 return addr;
     323                                result = addr;
    429324                        } else {
    430325                                /* Block start has to be aligned */
     
    432327                               
    433328                                if (cur->size >= real_size + excess) {
    434                                         /*
    435                                          * The current block is large enough to fit
    436                                          * data in (including alignment).
    437                                          */
    438                                         if ((void *) cur > (void *) AREA_FIRST_BLOCK(area)) {
    439                                                 /*
    440                                                  * There is a block before the current block.
    441                                                  * This previous block can be enlarged to
    442                                                  * compensate for the alignment excess.
    443                                                  */
    444                                                 heap_block_foot_t *prev_foot = (heap_block_foot_t *)
    445                                                     ((void *) cur - sizeof(heap_block_foot_t));
     329                                        /* The current block is large enough to fit
     330                                           data in including alignment */
     331                                        if ((void *) cur > heap_start) {
     332                                                /* There is a block before the current block.
     333                                                   This previous block can be enlarged to compensate
     334                                                   for the alignment excess */
     335                                                heap_block_foot_t *prev_foot =
     336                                                    ((void *) cur) - sizeof(heap_block_foot_t);
    446337                                               
    447                                                 heap_block_head_t *prev_head = (heap_block_head_t *)
    448                                                     ((void *) cur - prev_foot->size);
     338                                                heap_block_head_t *prev_head =
     339                                                    (heap_block_head_t *) (((void *) cur) - prev_foot->size);
    449340                                               
    450341                                                block_check(prev_head);
     
    453344                                                heap_block_head_t *next_head = ((void *) cur) + excess;
    454345                                               
    455                                                 if ((!prev_head->free) &&
    456                                                     (excess >= STRUCT_OVERHEAD)) {
    457                                                         /*
    458                                                          * The previous block is not free and there
    459                                                          * is enough free space left to fill in
    460                                                          * a new free block between the previous
    461                                                          * and current block.
    462                                                          */
    463                                                         block_init(cur, excess, true, area);
     346                                                if ((!prev_head->free) && (excess >= STRUCT_OVERHEAD)) {
     347                                                        /* The previous block is not free and there is enough
     348                                                           space to fill in a new free block between the previous
     349                                                           and current block */
     350                                                        block_init(cur, excess, true);
    464351                                                } else {
    465                                                         /*
    466                                                          * The previous block is free (thus there
    467                                                          * is no need to induce additional
    468                                                          * fragmentation to the heap) or the
    469                                                          * excess is small. Therefore just enlarge
    470                                                          * the previous block.
    471                                                          */
    472                                                         block_init(prev_head, prev_head->size + excess,
    473                                                             prev_head->free, area);
     352                                                        /* The previous block is free (thus there is no need to
     353                                                           induce additional fragmentation to the heap) or the
     354                                                           excess is small, thus just enlarge the previous block */
     355                                                        block_init(prev_head, prev_head->size + excess, prev_head->free);
    474356                                                }
    475357                                               
    476                                                 block_init(next_head, reduced_size, true, area);
     358                                                block_init(next_head, reduced_size, true);
    477359                                                split_mark(next_head, real_size);
    478                                                
    479                                                 next = next_head;
    480                                                 return aligned;
     360                                                result = aligned;
     361                                                cur = next_head;
    481362                                        } else {
    482                                                 /*
    483                                                  * The current block is the first block
    484                                                  * in the heap area. We have to make sure
    485                                                  * that the alignment excess is large enough
    486                                                  * to fit a new free block just before the
    487                                                  * current block.
    488                                                  */
     363                                                /* The current block is the first block on the heap.
     364                                                   We have to make sure that the alignment excess
     365                                                   is large enough to fit a new free block just
     366                                                   before the current block */
    489367                                                while (excess < STRUCT_OVERHEAD) {
    490368                                                        aligned += falign;
     
    495373                                                if (cur->size >= real_size + excess) {
    496374                                                        size_t reduced_size = cur->size - excess;
    497                                                         cur = (heap_block_head_t *)
    498                                                             (AREA_FIRST_BLOCK(area) + excess);
     375                                                        cur = (heap_block_head_t *) (heap_start + excess);
    499376                                                       
    500                                                         block_init((void *) AREA_FIRST_BLOCK(area), excess,
    501                                                             true, area);
    502                                                         block_init(cur, reduced_size, true, area);
     377                                                        block_init(heap_start, excess, true);
     378                                                        block_init(cur, reduced_size, true);
    503379                                                        split_mark(cur, real_size);
    504                                                        
    505                                                         next = cur;
    506                                                         return aligned;
     380                                                        result = aligned;
    507381                                                }
    508382                                        }
     
    510384                        }
    511385                }
    512         }
    513        
    514         return NULL;
    515 }
    516 
    517 /** Allocate a memory block
    518  *
    519  * Should be called only inside the critical section.
    520  *
    521  * @param size  The size of the block to allocate.
    522  * @param align Memory address alignment.
    523  *
    524  * @return Address of the allocated block or NULL on not enough memory.
    525  *
    526  */
    527 static void *malloc_internal(const size_t size, const size_t align)
    528 {
    529         assert(first_heap_area != NULL);
    530        
    531         if (align == 0)
    532                 return NULL;
    533        
    534         size_t falign = lcm(align, BASE_ALIGN);
    535         size_t real_size = GROSS_SIZE(ALIGN_UP(size, falign));
    536        
    537         bool retry = false;
    538         heap_block_head_t *split;
    539        
    540 loop:
    541        
    542         /* Try the next fit approach */
    543         split = next;
    544        
    545         if (split != NULL) {
    546                 void *addr = malloc_area(split->area, split, NULL, real_size,
    547                     falign);
    548                
    549                 if (addr != NULL)
    550                         return addr;
    551         }
    552        
    553         /* Search the entire heap */
    554         heap_area_t *area;
    555         for (area = first_heap_area; area != NULL; area = area->next) {
    556                 heap_block_head_t *first = (heap_block_head_t *)
    557                     AREA_FIRST_BLOCK(area);
    558                
    559                 void *addr = malloc_area(area, first, split, real_size,
    560                     falign);
    561                
    562                 if (addr != NULL)
    563                         return addr;
    564         }
    565        
    566         if (!retry) {
    567                 /* Try to grow the heap space */
    568                 if (heap_grow(real_size)) {
    569                         retry = true;
     386               
     387                /* Advance to the next block. */
     388                cur = (heap_block_head_t *) (((void *) cur) + cur->size);
     389        }
     390       
     391        if ((result == NULL) && (!grown)) {
     392                if (grow_heap(real_size)) {
     393                        grown = true;
    570394                        goto loop;
    571395                }
    572396        }
    573397       
    574         return NULL;
     398        return result;
    575399}
    576400
     
    651475            (heap_block_head_t *) (addr - sizeof(heap_block_head_t));
    652476       
     477        assert((void *) head >= heap_start);
     478        assert((void *) head < heap_end);
     479       
    653480        block_check(head);
    654481        assert(!head->free);
    655        
    656         heap_area_t *area = head->area;
    657        
    658         area_check(area);
    659         assert((void *) head >= (void *) AREA_FIRST_BLOCK(area));
    660         assert((void *) head < area->end);
    661482       
    662483        void *ptr = NULL;
     
    668489                /* Shrink */
    669490                if (orig_size - real_size >= STRUCT_OVERHEAD) {
    670                         /*
    671                          * Split the original block to a full block
    672                          * and a trailing free block.
    673                          */
    674                         block_init((void *) head, real_size, false, area);
     491                        /* Split the original block to a full block
     492                           and a trailing free block */
     493                        block_init((void *) head, real_size, false);
    675494                        block_init((void *) head + real_size,
    676                             orig_size - real_size, true, area);
    677                         heap_shrink();
     495                            orig_size - real_size, true);
     496                        shrink_heap();
    678497                }
    679498               
    680499                ptr = ((void *) head) + sizeof(heap_block_head_t);
    681500        } else {
    682                 /*
    683                  * Look at the next block. If it is free and the size is
    684                  * sufficient then merge the two. Otherwise just allocate
    685                  * a new block, copy the original data into it and
    686                  * free the original block.
    687                  */
     501                /* 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. */
    688505                heap_block_head_t *next_head =
    689506                    (heap_block_head_t *) (((void *) head) + head->size);
    690507               
    691                 if (((void *) next_head < area->end) &&
     508                if (((void *) next_head < heap_end) &&
    692509                    (head->size + next_head->size >= real_size) &&
    693510                    (next_head->free)) {
    694511                        block_check(next_head);
    695                         block_init(head, head->size + next_head->size, false, area);
     512                        block_init(head, head->size + next_head->size, false);
    696513                        split_mark(head, real_size);
    697514                       
    698515                        ptr = ((void *) head) + sizeof(heap_block_head_t);
    699                         next = NULL;
    700516                } else
    701517                        reloc = true;
     
    728544            = (heap_block_head_t *) (addr - sizeof(heap_block_head_t));
    729545       
     546        assert((void *) head >= heap_start);
     547        assert((void *) head < heap_end);
     548       
    730549        block_check(head);
    731550        assert(!head->free);
    732        
    733         heap_area_t *area = head->area;
    734        
    735         area_check(area);
    736         assert((void *) head >= (void *) AREA_FIRST_BLOCK(area));
    737         assert((void *) head < area->end);
    738551       
    739552        /* Mark the block itself as free. */
     
    744557            = (heap_block_head_t *) (((void *) head) + head->size);
    745558       
    746         if ((void *) next_head < area->end) {
     559        if ((void *) next_head < heap_end) {
    747560                block_check(next_head);
    748561                if (next_head->free)
    749                         block_init(head, head->size + next_head->size, true, area);
     562                        block_init(head, head->size + next_head->size, true);
    750563        }
    751564       
    752565        /* Look at the previous block. If it is free, merge the two. */
    753         if ((void *) head > (void *) AREA_FIRST_BLOCK(area)) {
     566        if ((void *) head > heap_start) {
    754567                heap_block_foot_t *prev_foot =
    755568                    (heap_block_foot_t *) (((void *) head) - sizeof(heap_block_foot_t));
     
    761574               
    762575                if (prev_head->free)
    763                         block_init(prev_head, prev_head->size + head->size, true,
    764                             area);
    765         }
    766        
    767         heap_shrink();
     576                        block_init(prev_head, prev_head->size + head->size, true);
     577        }
     578       
     579        shrink_heap();
    768580       
    769581        futex_up(&malloc_futex);
Note: See TracChangeset for help on using the changeset viewer.