github.com/afumu/libc@v0.0.6/musl/src/malloc/mallocng/realloc.c (about) 1 #define _GNU_SOURCE 2 #include <stdlib.h> 3 #include <sys/mman.h> 4 #include <string.h> 5 #include "meta.h" 6 7 void *realloc(void *p, size_t n) 8 { 9 if (!p) return malloc(n); 10 if (size_overflows(n)) return 0; 11 12 struct meta *g = get_meta(p); 13 int idx = get_slot_index(p); 14 size_t stride = get_stride(g); 15 unsigned char *start = g->mem->storage + stride*idx; 16 unsigned char *end = start + stride - IB; 17 size_t old_size = get_nominal_size(p, end); 18 size_t avail_size = end-(unsigned char *)p; 19 void *new; 20 21 // only resize in-place if size class matches 22 if (n <= avail_size && n<MMAP_THRESHOLD 23 && size_to_class(n)+1 >= g->sizeclass) { 24 set_size(p, end, n); 25 return p; 26 } 27 28 // use mremap if old and new size are both mmap-worthy 29 if (g->sizeclass>=48 && n>=MMAP_THRESHOLD) { 30 assert(g->sizeclass==63); 31 size_t base = (unsigned char *)p-start; 32 size_t needed = (n + base + UNIT + IB + 4095) & -4096; 33 new = g->maplen*4096UL == needed ? g->mem : 34 mremap(g->mem, g->maplen*4096UL, needed, MREMAP_MAYMOVE); 35 if (new!=MAP_FAILED) { 36 g->mem = new; 37 g->maplen = needed/4096; 38 p = g->mem->storage + base; 39 end = g->mem->storage + (needed - UNIT) - IB; 40 *end = 0; 41 set_size(p, end, n); 42 return p; 43 } 44 } 45 46 new = malloc(n); 47 if (!new) return 0; 48 memcpy(new, p, n < old_size ? n : old_size); 49 free(p); 50 return new; 51 }