Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset fdc190f in mainline


Ignore:
Timestamp:
2018-11-13T16:48:08Z (3 years ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Branches:
lfn, master
Children:
bcd4dd4
Parents:
71fb5ac
git-author:
Jiří Zárevúcky <zarevucky.jiri@…> (2018-11-13 16:44:03)
git-committer:
Jiří Zárevúcky <zarevucky.jiri@…> (2018-11-13 16:48:08)
Message:

Split realloc()

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/mm/malloc.c

    r71fb5ac rfdc190f  
    8282}
    8383
     84static inline bool _is_pow2(size_t x)
     85{
     86        return (x & (x - 1)) == 0;
     87}
     88
    8489static void _check_sizes(size_t *alignment, size_t *size)
    8590{
     
    8792        assert(alignment);
    8893
    89         assert(*size > 0);
     94        /* Force size to be nonzero. */
     95        if (*size == 0)
     96                *size = 1;
    9097
    9198        /* Alignment must be a power of 2. */
    92         assert(__builtin_popcountl(*alignment) <= 1);
     99        assert(_is_pow2(*alignment));
    93100        assert(*alignment <= PAGE_SIZE);
    94101
     
    132139        /* We assume that slab objects are aligned naturally */
    133140        return slab_alloc(cache_for_size(size), FRAME_ATOMIC);
     141}
     142
     143static void *mem_realloc(void *old_ptr, size_t alignment, size_t old_size,
     144    size_t new_size)
     145{
     146        assert(old_ptr);
     147        _check_sizes(&alignment, &old_size);
     148        _check_sizes(&alignment, &new_size);
     149
     150        // TODO: handle big objects
     151        assert(new_size <= (1 << SLAB_MAX_MALLOC_W));
     152
     153        slab_cache_t *old_cache = cache_for_size(old_size);
     154        slab_cache_t *new_cache = cache_for_size(new_size);
     155        if (old_cache == new_cache)
     156                return old_ptr;
     157
     158        void *new_ptr = slab_alloc(new_cache, FRAME_ATOMIC);
     159        if (!new_ptr)
     160                return NULL;
     161
     162        memcpy(new_ptr, old_ptr, min(old_size, new_size));
     163        slab_free(old_cache, old_ptr);
     164        return new_ptr;
    134165}
    135166
     
    186217        size_t old_size = ((size_t *) old_obj)[-1];
    187218
    188         if (cache_for_size(old_size + _offset) ==
    189             cache_for_size(new_size + _offset))
    190                 return old_obj;
    191 
    192         void *new_obj = malloc(new_size);
     219        void *new_obj = mem_realloc(old_obj - _offset, alignof(max_align_t),
     220            old_size + _offset, new_size + _offset) + _offset;
    193221        if (!new_obj)
    194222                return NULL;
    195223
    196         memcpy(new_obj, old_obj, min(old_size, new_size));
    197         free(old_obj);
     224        ((size_t *) new_obj)[-1] = new_size;
    198225        return new_obj;
    199226}
Note: See TracChangeset for help on using the changeset viewer.