On Wed, Jan 03, 2018 at 01:56:43PM +0100, Otto Moerbeek wrote: > Hi, > > this is mostly kshe's work, with an additional change on the cache > maintenance by me. > > I did not take the ffs change yet, since I want to measure the impact > separately.
no feedback :-( I'm going to commit this soon to force testing for machines running snaps or current. -Otto > > Index: malloc.c > =================================================================== > RCS file: /cvs/src/lib/libc/stdlib/malloc.c,v > retrieving revision 1.238 > diff -u -p -r1.238 malloc.c > --- malloc.c 1 Jan 2018 12:41:48 -0000 1.238 > +++ malloc.c 3 Jan 2018 12:52:14 -0000 > @@ -376,12 +376,11 @@ omalloc_parseopt(char opt) > case 'X': > mopts.malloc_xmalloc = 1; > break; > - default: { > + default: > dprintf(STDERR_FILENO, "malloc() warning: " > "unknown char in MALLOC_OPTIONS\n"); > break; > } > - } > } > > static void > @@ -448,9 +447,6 @@ omalloc_init(void) > ; > } > > -/* > - * Initialize a dir_info, which should have been cleared by caller > - */ > static void > omalloc_poolinit(struct dir_info **dp) > { > @@ -502,7 +498,7 @@ omalloc_grow(struct dir_info *d) > size_t i; > struct region_info *p; > > - if (d->regions_total > SIZE_MAX / sizeof(struct region_info) / 2 ) > + if (d->regions_total > SIZE_MAX / sizeof(struct region_info) / 2) > return 1; > > newtotal = d->regions_total * 2; > @@ -641,9 +637,9 @@ static void > unmap(struct dir_info *d, void *p, size_t sz, int clear) > { > size_t psz = sz >> MALLOC_PAGESHIFT; > - size_t rsz, tounmap; > + size_t rsz; > struct region_info *r; > - u_int i, offset; > + u_int i, offset, mask; > > if (sz != PAGEROUND(sz)) > wrterror(d, "munmap round"); > @@ -662,30 +658,34 @@ unmap(struct dir_info *d, void *p, size_ > STATS_SUB(d->malloc_used, sz); > return; > } > - tounmap = 0; > - if (psz > rsz) > - tounmap = psz - rsz; > offset = getrbyte(d); > - for (i = 0; tounmap > 0 && i < mopts.malloc_cache; i++) { > - r = &d->free_regions[(i + offset) & (mopts.malloc_cache - 1)]; > - if (r->p != NULL) { > - rsz = r->size << MALLOC_PAGESHIFT; > - if (munmap(r->p, rsz)) > - wrterror(d, "munmap %p", r->p); > - r->p = NULL; > - if (tounmap > r->size) > - tounmap -= r->size; > - else > - tounmap = 0; > - d->free_regions_size -= r->size; > - r->size = 0; > - STATS_SUB(d->malloc_used, rsz); > + mask = mopts.malloc_cache - 1; > + if (psz > rsz) { > + size_t tounmap = psz - rsz; > + i = 0; > + for (;;) { > + r = &d->free_regions[(i + offset) & mask]; > + if (r->p != NULL) { > + rsz = r->size << MALLOC_PAGESHIFT; > + if (munmap(r->p, rsz)) > + wrterror(d, "munmap %p", r->p); > + r->p = NULL; > + if (tounmap > r->size) > + tounmap -= r->size; > + else > + tounmap = 0; > + d->free_regions_size -= r->size; > + STATS_SUB(d->malloc_used, rsz); > + if (tounmap == 0) { > + offset = i; > + break; > + } > + } > + i++; > } > } > - if (tounmap > 0) > - wrterror(d, "malloc cache underflow"); > - for (i = 0; i < mopts.malloc_cache; i++) { > - r = &d->free_regions[(i + offset) & (mopts.malloc_cache - 1)]; > + for (i = 0; ; i++) { > + r = &d->free_regions[(i + offset) & mask]; > if (r->p == NULL) { > if (clear) > memset(p, 0, sz - mopts.malloc_guard); > @@ -702,8 +702,6 @@ unmap(struct dir_info *d, void *p, size_ > break; > } > } > - if (i == mopts.malloc_cache) > - wrterror(d, "malloc free slot lost"); > if (d->free_regions_size > mopts.malloc_cache) > wrterror(d, "malloc cache overflow"); > } > @@ -723,7 +721,6 @@ zapcacheregion(struct dir_info *d, void > wrterror(d, "munmap %p", r->p); > r->p = NULL; > d->free_regions_size -= r->size; > - r->size = 0; > STATS_SUB(d->malloc_used, rsz); > } > } > @@ -760,7 +757,6 @@ map(struct dir_info *d, void *hint, size > if (r->size == psz) { > p = r->p; > r->p = NULL; > - r->size = 0; > d->free_regions_size -= psz; > if (mopts.malloc_freeunmap) > mprotect(p, sz, PROT_READ | PROT_WRITE); > @@ -808,10 +804,7 @@ init_chunk_info(struct dir_info *d, stru > int i; > > if (bits == 0) { > - p->shift = 1; > - i = MALLOC_MINSIZE - 1; > - while (i >>= 1) > - p->shift++; > + p->shift = MALLOC_MINSHIFT; > p->total = p->free = MALLOC_PAGESIZE >> p->shift; > p->size = 0; > p->offset = 0xdead; > @@ -824,13 +817,9 @@ init_chunk_info(struct dir_info *d, stru > p->canary = (u_short)d->canary1; > > /* set all valid bits in the bitmap */ > - for (i = 0; p->total - i >= MALLOC_BITS; i += MALLOC_BITS) > - p->bits[i / MALLOC_BITS] = (u_short)~0U; > - > - if (i < p->total) > - p->bits[i / MALLOC_BITS] = 0; > - for (; i < p->total; i++) > - p->bits[i / MALLOC_BITS] |= (u_short)1U << (i % MALLOC_BITS); > + i = p->total - 1; > + memset(p->bits, 0xff, sizeof(p->bits[0]) * (i / MALLOC_BITS)); > + p->bits[i / MALLOC_BITS] = (2U << (i % MALLOC_BITS)) - 1; > } > > static struct chunk_info * > @@ -907,23 +896,20 @@ err: > static int > find_chunksize(size_t size) > { > - int i, j; > + int r; > + > + /* malloc(0) is special */ > + if (size == 0) > + return 0; > > - /* Don't bother with anything less than this */ > - /* unless we have a malloc(0) requests */ > - if (size != 0 && size < MALLOC_MINSIZE) > + if (size < MALLOC_MINSIZE) > size = MALLOC_MINSIZE; > + size--; > > - /* Find the right bucket */ > - if (size == 0) > - j = 0; > - else { > - j = MALLOC_MINSHIFT; > - i = (size - 1) >> (MALLOC_MINSHIFT - 1); > - while (i >>= 1) > - j++; > - } > - return j; > + r = MALLOC_MINSHIFT; > + while (size >> r) > + r++; > + return r; > } > > static void > @@ -1013,7 +999,7 @@ found: > *lp ^= u; > > /* If there are no more free, remove from free-list */ > - if (!--bp->free) > + if (--bp->free == 0) > LIST_REMOVE(bp, entries); > > /* Adjust to the real offset of that chunk */ > @@ -1048,8 +1034,8 @@ validate_canary(struct dir_info *d, u_ch > while (p < q) { > if (*p != SOME_JUNK) { > wrterror(d, "chunk canary corrupted %p %#tx@%#zx%s", > - ptr, p - ptr, sz, *p == SOME_FREEJUNK ? > - " (double free?)" : ""); > + ptr, p - ptr, sz, > + *p == SOME_FREEJUNK ? " (double free?)" : ""); > } > p++; > } > @@ -1173,8 +1159,7 @@ omalloc(struct dir_info *pool, size_t sz > else > memset(p, SOME_JUNK, > psz - mopts.malloc_guard); > - } > - else if (mopts.chunk_canaries) > + } else if (mopts.chunk_canaries) > fill_canary(p, sz - mopts.malloc_guard, > psz - mopts.malloc_guard); > } > @@ -1225,7 +1210,7 @@ _malloc_init(int from_rthreads) > max = from_rthreads ? _MALLOC_MUTEXES : 1; > if (((uintptr_t)&malloc_readonly & MALLOC_PAGEMASK) == 0) > mprotect(&malloc_readonly, sizeof(malloc_readonly), > - PROT_READ | PROT_WRITE); > + PROT_READ | PROT_WRITE); > for (i = 0; i < max; i++) { > if (mopts.malloc_pool[i]) > continue; > @@ -2030,8 +2015,7 @@ omemalign(struct dir_info *pool, size_t > SOME_JUNK, psz - sz); > else > memset(p, SOME_JUNK, psz - mopts.malloc_guard); > - } > - else if (mopts.chunk_canaries) > + } else if (mopts.chunk_canaries) > fill_canary(p, sz - mopts.malloc_guard, > psz - mopts.malloc_guard); >