diff options
author | tedu <> | 2012-06-22 01:30:17 +0000 |
---|---|---|
committer | tedu <> | 2012-06-22 01:30:17 +0000 |
commit | 8ab3be999733505905c43d1c6b1e23220e85f6b5 (patch) | |
tree | cb793c8d0797100c55af7689875d24b90d9584af /src | |
parent | 80020aecd05f49119bfeaec130105f3890a5258a (diff) | |
download | openbsd-8ab3be999733505905c43d1c6b1e23220e85f6b5.tar.gz openbsd-8ab3be999733505905c43d1c6b1e23220e85f6b5.tar.bz2 openbsd-8ab3be999733505905c43d1c6b1e23220e85f6b5.zip |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libc/stdlib/malloc.c | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c index 92efd7d68b..7a48a0f2ff 100644 --- a/src/lib/libc/stdlib/malloc.c +++ b/src/lib/libc/stdlib/malloc.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: malloc.c,v 1.143 2012/06/20 13:13:15 tedu Exp $ */ | 1 | /* $OpenBSD: malloc.c,v 1.144 2012/06/22 01:30:17 tedu Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net> | 3 | * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net> |
4 | * | 4 | * |
@@ -94,6 +94,9 @@ | |||
94 | #define MMAPA(a,sz) mmap((a), (size_t)(sz), PROT_READ | PROT_WRITE, \ | 94 | #define MMAPA(a,sz) mmap((a), (size_t)(sz), PROT_READ | PROT_WRITE, \ |
95 | MAP_ANON | MAP_PRIVATE, -1, (off_t) 0) | 95 | MAP_ANON | MAP_PRIVATE, -1, (off_t) 0) |
96 | 96 | ||
97 | #define MQUERY(a, sz) mquery((a), (size_t)(sz), PROT_READ | PROT_WRITE, \ | ||
98 | MAP_ANON | MAP_PRIVATE, -1, (off_t)0) | ||
99 | |||
97 | struct region_info { | 100 | struct region_info { |
98 | void *p; /* page; low bits used to mark chunks */ | 101 | void *p; /* page; low bits used to mark chunks */ |
99 | uintptr_t size; /* size for pages, or chunk_info pointer */ | 102 | uintptr_t size; /* size for pages, or chunk_info pointer */ |
@@ -356,7 +359,7 @@ unmap(struct dir_info *d, void *p, size_t sz) | |||
356 | } | 359 | } |
357 | 360 | ||
358 | static void | 361 | static void |
359 | zapcacheregion(struct dir_info *d, void *p) | 362 | zapcacheregion(struct dir_info *d, void *p, size_t len) |
360 | { | 363 | { |
361 | u_int i; | 364 | u_int i; |
362 | struct region_info *r; | 365 | struct region_info *r; |
@@ -364,7 +367,7 @@ zapcacheregion(struct dir_info *d, void *p) | |||
364 | 367 | ||
365 | for (i = 0; i < mopts.malloc_cache; i++) { | 368 | for (i = 0; i < mopts.malloc_cache; i++) { |
366 | r = &d->free_regions[i]; | 369 | r = &d->free_regions[i]; |
367 | if (r->p == p) { | 370 | if (r->p >= p && r->p <= (void *)((char *)p + len)) { |
368 | rsz = r->size << MALLOC_PAGESHIFT; | 371 | rsz = r->size << MALLOC_PAGESHIFT; |
369 | if (munmap(r->p, rsz)) | 372 | if (munmap(r->p, rsz)) |
370 | wrterror("munmap", r->p); | 373 | wrterror("munmap", r->p); |
@@ -1283,20 +1286,26 @@ orealloc(void *p, size_t newsz, void *f) | |||
1283 | 1286 | ||
1284 | if (rnewsz > roldsz) { | 1287 | if (rnewsz > roldsz) { |
1285 | if (!mopts.malloc_guard) { | 1288 | if (!mopts.malloc_guard) { |
1289 | void *hint = (char *)p + roldsz; | ||
1290 | size_t needed = rnewsz - roldsz; | ||
1291 | |||
1286 | STATS_INC(g_pool->cheap_realloc_tries); | 1292 | STATS_INC(g_pool->cheap_realloc_tries); |
1287 | zapcacheregion(g_pool, (char *)p + roldsz); | 1293 | zapcacheregion(g_pool, hint, needed); |
1288 | q = MMAPA((char *)p + roldsz, rnewsz - roldsz); | 1294 | q = MQUERY(hint, needed); |
1289 | if (q == (char *)p + roldsz) { | 1295 | if (q == hint) |
1290 | malloc_used += rnewsz - roldsz; | 1296 | q = MMAPA(hint, needed); |
1297 | else | ||
1298 | q = MAP_FAILED; | ||
1299 | if (q == hint) { | ||
1300 | malloc_used += needed; | ||
1291 | if (mopts.malloc_junk) | 1301 | if (mopts.malloc_junk) |
1292 | memset(q, SOME_JUNK, | 1302 | memset(q, SOME_JUNK, needed); |
1293 | rnewsz - roldsz); | ||
1294 | r->size = newsz; | 1303 | r->size = newsz; |
1295 | STATS_SETF(r, f); | 1304 | STATS_SETF(r, f); |
1296 | STATS_INC(g_pool->cheap_reallocs); | 1305 | STATS_INC(g_pool->cheap_reallocs); |
1297 | return p; | 1306 | return p; |
1298 | } else if (q != MAP_FAILED) { | 1307 | } else if (q != MAP_FAILED) { |
1299 | if (munmap(q, rnewsz - roldsz)) | 1308 | if (munmap(q, needed)) |
1300 | wrterror("munmap", q); | 1309 | wrterror("munmap", q); |
1301 | } | 1310 | } |
1302 | } | 1311 | } |