Browse Source

two changes which should improve realloc. first, fix zapcacheregion to

clear out the entire requested area, not just a perfect fit.  second,
use mquery to check for room to avoid getting an address we don't like
and having to send it back.
OPENBSD_5_2
tedu 13 years ago
parent
commit
d8de214e9d
1 changed files with 19 additions and 10 deletions
  1. +19
    -10
      src/lib/libc/stdlib/malloc.c

+ 19
- 10
src/lib/libc/stdlib/malloc.c View File

@ -1,4 +1,4 @@
/* $OpenBSD: malloc.c,v 1.143 2012/06/20 13:13:15 tedu Exp $ */ /* $OpenBSD: malloc.c,v 1.144 2012/06/22 01:30:17 tedu Exp $ */
/* /*
* Copyright (c) 2008 Otto Moerbeek <otto@drijf.net> * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
* *
@ -94,6 +94,9 @@
#define MMAPA(a,sz) mmap((a), (size_t)(sz), PROT_READ | PROT_WRITE, \ #define MMAPA(a,sz) mmap((a), (size_t)(sz), PROT_READ | PROT_WRITE, \
MAP_ANON | MAP_PRIVATE, -1, (off_t) 0) MAP_ANON | MAP_PRIVATE, -1, (off_t) 0)
#define MQUERY(a, sz) mquery((a), (size_t)(sz), PROT_READ | PROT_WRITE, \
MAP_ANON | MAP_PRIVATE, -1, (off_t)0)
struct region_info { struct region_info {
void *p; /* page; low bits used to mark chunks */ void *p; /* page; low bits used to mark chunks */
uintptr_t size; /* size for pages, or chunk_info pointer */ uintptr_t size; /* size for pages, or chunk_info pointer */
@ -356,7 +359,7 @@ unmap(struct dir_info *d, void *p, size_t sz)
} }
static void static void
zapcacheregion(struct dir_info *d, void *p) zapcacheregion(struct dir_info *d, void *p, size_t len)
{ {
u_int i; u_int i;
struct region_info *r; struct region_info *r;
@ -364,7 +367,7 @@ zapcacheregion(struct dir_info *d, void *p)
for (i = 0; i < mopts.malloc_cache; i++) { for (i = 0; i < mopts.malloc_cache; i++) {
r = &d->free_regions[i]; r = &d->free_regions[i];
if (r->p == p) { if (r->p >= p && r->p <= (void *)((char *)p + len)) {
rsz = r->size << MALLOC_PAGESHIFT; rsz = r->size << MALLOC_PAGESHIFT;
if (munmap(r->p, rsz)) if (munmap(r->p, rsz))
wrterror("munmap", r->p); wrterror("munmap", r->p);
@ -1283,20 +1286,26 @@ orealloc(void *p, size_t newsz, void *f)
if (rnewsz > roldsz) { if (rnewsz > roldsz) {
if (!mopts.malloc_guard) { if (!mopts.malloc_guard) {
void *hint = (char *)p + roldsz;
size_t needed = rnewsz - roldsz;
STATS_INC(g_pool->cheap_realloc_tries); STATS_INC(g_pool->cheap_realloc_tries);
zapcacheregion(g_pool, (char *)p + roldsz); zapcacheregion(g_pool, hint, needed);
q = MMAPA((char *)p + roldsz, rnewsz - roldsz); q = MQUERY(hint, needed);
if (q == (char *)p + roldsz) { if (q == hint)
malloc_used += rnewsz - roldsz; q = MMAPA(hint, needed);
else
q = MAP_FAILED;
if (q == hint) {
malloc_used += needed;
if (mopts.malloc_junk) if (mopts.malloc_junk)
memset(q, SOME_JUNK, memset(q, SOME_JUNK, needed);
rnewsz - roldsz);
r->size = newsz; r->size = newsz;
STATS_SETF(r, f); STATS_SETF(r, f);
STATS_INC(g_pool->cheap_reallocs); STATS_INC(g_pool->cheap_reallocs);
return p; return p;
} else if (q != MAP_FAILED) { } else if (q != MAP_FAILED) {
if (munmap(q, rnewsz - roldsz)) if (munmap(q, needed))
wrterror("munmap", q); wrterror("munmap", q);
} }
} }


|||||||
|||||||
xxxxxxxxxx
 
000:0
x
 
000:0
Loading…
Cancel
Save