diff options
Diffstat (limited to 'src/lib/libc')
| -rw-r--r-- | src/lib/libc/stdlib/malloc.c | 55 |
1 files changed, 32 insertions, 23 deletions
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c index b9f692ebb7..97092a2e0d 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.188 2016/04/12 18:14:02 otto Exp $ */ | 1 | /* $OpenBSD: malloc.c,v 1.189 2016/06/27 15:33:40 tedu Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2008, 2010, 2011 Otto Moerbeek <otto@drijf.net> | 3 | * Copyright (c) 2008, 2010, 2011 Otto Moerbeek <otto@drijf.net> |
| 4 | * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org> | 4 | * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org> |
| @@ -122,6 +122,8 @@ struct dir_info { | |||
| 122 | char *func; /* current function */ | 122 | char *func; /* current function */ |
| 123 | u_char rbytes[32]; /* random bytes */ | 123 | u_char rbytes[32]; /* random bytes */ |
| 124 | u_short chunk_start; | 124 | u_short chunk_start; |
| 125 | void *unmap_me; | ||
| 126 | size_t unmap_me_sz; | ||
| 125 | #ifdef MALLOC_STATS | 127 | #ifdef MALLOC_STATS |
| 126 | size_t inserts; | 128 | size_t inserts; |
| 127 | size_t insert_collisions; | 129 | size_t insert_collisions; |
| @@ -218,10 +220,16 @@ static void malloc_exit(void); | |||
| 218 | static inline void | 220 | static inline void |
| 219 | _MALLOC_LEAVE(struct dir_info *d) | 221 | _MALLOC_LEAVE(struct dir_info *d) |
| 220 | { | 222 | { |
| 223 | void *unmap_me = d->unmap_me; | ||
| 224 | size_t unmap_me_sz = d->unmap_me_sz; | ||
| 225 | |||
| 221 | if (__isthreaded) { | 226 | if (__isthreaded) { |
| 222 | d->active--; | 227 | d->active--; |
| 223 | _MALLOC_UNLOCK(); | 228 | _MALLOC_UNLOCK(); |
| 224 | } | 229 | } |
| 230 | |||
| 231 | if (unmap_me != NULL) | ||
| 232 | munmap(unmap_me, unmap_me_sz); | ||
| 225 | } | 233 | } |
| 226 | 234 | ||
| 227 | static inline void | 235 | static inline void |
| @@ -231,6 +239,8 @@ _MALLOC_ENTER(struct dir_info *d) | |||
| 231 | _MALLOC_LOCK(); | 239 | _MALLOC_LOCK(); |
| 232 | d->active++; | 240 | d->active++; |
| 233 | } | 241 | } |
| 242 | d->unmap_me = NULL; | ||
| 243 | d->unmap_me_sz = 0; | ||
| 234 | } | 244 | } |
| 235 | 245 | ||
| 236 | static inline size_t | 246 | static inline size_t |
| @@ -295,6 +305,16 @@ wrterror(struct dir_info *d, char *msg, void *p) | |||
| 295 | abort(); | 305 | abort(); |
| 296 | } | 306 | } |
| 297 | 307 | ||
| 308 | static inline void | ||
| 309 | _MUNMAP(struct dir_info *d, void *p, size_t sz) | ||
| 310 | { | ||
| 311 | if (d->unmap_me == NULL) { | ||
| 312 | d->unmap_me = p; | ||
| 313 | d->unmap_me_sz = sz; | ||
| 314 | } else if (munmap(p, sz) == -1) | ||
| 315 | wrterror(d, "munmap", p); | ||
| 316 | } | ||
| 317 | |||
| 298 | static void | 318 | static void |
| 299 | rbytes_init(struct dir_info *d) | 319 | rbytes_init(struct dir_info *d) |
| 300 | { | 320 | { |
| @@ -335,9 +355,7 @@ unmap(struct dir_info *d, void *p, size_t sz) | |||
| 335 | } | 355 | } |
| 336 | 356 | ||
| 337 | if (psz > mopts.malloc_cache) { | 357 | if (psz > mopts.malloc_cache) { |
| 338 | i = munmap(p, sz); | 358 | _MUNMAP(d, p, sz); |
| 339 | if (i) | ||
| 340 | wrterror(d, "munmap", p); | ||
| 341 | STATS_SUB(d->malloc_used, sz); | 359 | STATS_SUB(d->malloc_used, sz); |
| 342 | return; | 360 | return; |
| 343 | } | 361 | } |
| @@ -350,8 +368,7 @@ unmap(struct dir_info *d, void *p, size_t sz) | |||
| 350 | r = &d->free_regions[(i + offset) & (mopts.malloc_cache - 1)]; | 368 | r = &d->free_regions[(i + offset) & (mopts.malloc_cache - 1)]; |
| 351 | if (r->p != NULL) { | 369 | if (r->p != NULL) { |
| 352 | rsz = r->size << MALLOC_PAGESHIFT; | 370 | rsz = r->size << MALLOC_PAGESHIFT; |
| 353 | if (munmap(r->p, rsz)) | 371 | _MUNMAP(d, r->p, rsz); |
| 354 | wrterror(d, "munmap", r->p); | ||
| 355 | r->p = NULL; | 372 | r->p = NULL; |
| 356 | if (tounmap > r->size) | 373 | if (tounmap > r->size) |
| 357 | tounmap -= r->size; | 374 | tounmap -= r->size; |
| @@ -394,8 +411,7 @@ zapcacheregion(struct dir_info *d, void *p, size_t len) | |||
| 394 | r = &d->free_regions[i]; | 411 | r = &d->free_regions[i]; |
| 395 | if (r->p >= p && r->p <= (void *)((char *)p + len)) { | 412 | if (r->p >= p && r->p <= (void *)((char *)p + len)) { |
| 396 | rsz = r->size << MALLOC_PAGESHIFT; | 413 | rsz = r->size << MALLOC_PAGESHIFT; |
| 397 | if (munmap(r->p, rsz)) | 414 | _MUNMAP(d, r->p, rsz); |
| 398 | wrterror(d, "munmap", r->p); | ||
| 399 | r->p = NULL; | 415 | r->p = NULL; |
| 400 | d->free_regions_size -= r->size; | 416 | d->free_regions_size -= r->size; |
| 401 | r->size = 0; | 417 | r->size = 0; |
| @@ -727,11 +743,9 @@ omalloc_grow(struct dir_info *d) | |||
| 727 | } | 743 | } |
| 728 | } | 744 | } |
| 729 | /* avoid pages containing meta info to end up in cache */ | 745 | /* avoid pages containing meta info to end up in cache */ |
| 730 | if (munmap(d->r, d->regions_total * sizeof(struct region_info))) | 746 | _MUNMAP(d, d->r, d->regions_total * sizeof(struct region_info)); |
| 731 | wrterror(d, "munmap", d->r); | 747 | STATS_SUB(d->malloc_used, |
| 732 | else | 748 | d->regions_total * sizeof(struct region_info)); |
| 733 | STATS_SUB(d->malloc_used, | ||
| 734 | d->regions_total * sizeof(struct region_info)); | ||
| 735 | d->regions_free = d->regions_free + d->regions_total; | 749 | d->regions_free = d->regions_free + d->regions_total; |
| 736 | d->regions_total = newtotal; | 750 | d->regions_total = newtotal; |
| 737 | d->r = p; | 751 | d->r = p; |
| @@ -1428,10 +1442,8 @@ gotit: | |||
| 1428 | STATS_SETF(r, f); | 1442 | STATS_SETF(r, f); |
| 1429 | STATS_INC(pool->cheap_reallocs); | 1443 | STATS_INC(pool->cheap_reallocs); |
| 1430 | return p; | 1444 | return p; |
| 1431 | } else if (q != MAP_FAILED) { | 1445 | } else if (q != MAP_FAILED) |
| 1432 | if (munmap(q, needed)) | 1446 | _MUNMAP(pool, q, needed); |
| 1433 | wrterror(pool, "munmap", q); | ||
| 1434 | } | ||
| 1435 | } | 1447 | } |
| 1436 | } else if (rnewsz < roldsz) { | 1448 | } else if (rnewsz < roldsz) { |
| 1437 | if (mopts.malloc_guard) { | 1449 | if (mopts.malloc_guard) { |
| @@ -1600,12 +1612,9 @@ mapalign(struct dir_info *d, size_t alignment, size_t sz, int zero_fill) | |||
| 1600 | if (p == MAP_FAILED) | 1612 | if (p == MAP_FAILED) |
| 1601 | return MAP_FAILED; | 1613 | return MAP_FAILED; |
| 1602 | q = (char *)(((uintptr_t)p + alignment - 1) & ~(alignment - 1)); | 1614 | q = (char *)(((uintptr_t)p + alignment - 1) & ~(alignment - 1)); |
| 1603 | if (q != p) { | 1615 | if (q != p) |
| 1604 | if (munmap(p, q - p)) | 1616 | _MUNMAP(d, p, q - p); |
| 1605 | wrterror(d, "munmap", p); | 1617 | _MUNMAP(d, q + sz, alignment - (q - p)); |
| 1606 | } | ||
| 1607 | if (munmap(q + sz, alignment - (q - p))) | ||
| 1608 | wrterror(d, "munmap", q + sz); | ||
| 1609 | STATS_SUB(d->malloc_used, alignment); | 1618 | STATS_SUB(d->malloc_used, alignment); |
| 1610 | 1619 | ||
| 1611 | return q; | 1620 | return q; |
