Changeset 5b46ec8 in mainline


Ignore:
Timestamp:
2017-02-26T22:00:46Z (7 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1dff985, e330da6e
Parents:
b22b449d
Message:

realloc() should try harder to avoid relocating the buffer
(Thanks to Sergio Lopez)

File:
1 edited

Legend:

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

    rb22b449d r5b46ec8  
    928928                ptr = ((void *) head) + sizeof(heap_block_head_t);
    929929        } else {
     930                heap_block_head_t *next_head =
     931                    (heap_block_head_t *) (((void *) head) + head->size);
     932                bool have_next = ((void *) next_head < area->end);
     933
     934                if (((void *) head) + real_size > area->end) {
     935                        /*
     936                         * The current area is too small to hold the resized
     937                         * block. Make sure there are no used blocks standing
     938                         * in our way and try to grow the area using real_size
     939                         * as a safe upper bound.
     940                         */
     941
     942                        bool have_next_next;
     943
     944                        if (have_next) {
     945                                have_next_next = (((void *) next_head) +
     946                                    next_head->size < area->end);
     947                        }
     948                        if (!have_next || (next_head->free && !have_next_next)) {
     949                                /*
     950                                 * There is no next block in this area or
     951                                 * it is a free block and there is no used
     952                                 * block following it. There can't be any
     953                                 * free block following it either as
     954                                 * two free blocks would be merged.
     955                                 */
     956                                (void) area_grow(area, real_size);
     957                        }
     958                }
     959               
    930960                /*
    931961                 * Look at the next block. If it is free and the size is
    932                  * sufficient then merge the two. Otherwise just allocate
    933                  * a new block, copy the original data into it and
    934                  * free the original block.
     962                 * sufficient then merge the two. Otherwise just allocate a new
     963                 * block, copy the original data into it and free the original
     964                 * block.
    935965                 */
    936                 heap_block_head_t *next_head =
    937                     (heap_block_head_t *) (((void *) head) + head->size);
    938                
    939                 if (((void *) next_head < area->end) &&
    940                     (head->size + next_head->size >= real_size) &&
    941                     (next_head->free)) {
     966
     967                if (have_next && (head->size + next_head->size >= real_size) &&
     968                    next_head->free) {
    942969                        block_check(next_head);
    943                         block_init(head, head->size + next_head->size, false, area);
     970                        block_init(head, head->size + next_head->size, false,
     971                            area);
    944972                        split_mark(head, real_size);
    945973                       
    946974                        ptr = ((void *) head) + sizeof(heap_block_head_t);
    947975                        next_fit = NULL;
    948                 } else
     976                } else {
    949977                        reloc = true;
     978                }
    950979        }
    951980       
Note: See TracChangeset for help on using the changeset viewer.