summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorotto <>2008-08-22 17:14:57 +0000
committerotto <>2008-08-22 17:14:57 +0000
commite6c446cc76e761b92735aca89f612db2ed9a52d2 (patch)
treef6236b9a87997344d17ae9b8295480c318e6ddca /src
parente72de9455c1c4ac62f67569f4309a7875d9ca4fa (diff)
downloadopenbsd-e6c446cc76e761b92735aca89f612db2ed9a52d2.tar.gz
openbsd-e6c446cc76e761b92735aca89f612db2ed9a52d2.tar.bz2
openbsd-e6c446cc76e761b92735aca89f612db2ed9a52d2.zip
Smarter implementation of calloc(3), which uses the fact that mmap(2)
returns zero filled pages; remember to replace this function as well if you provide your own malloc implementation; ok djm@ deraadt@
Diffstat (limited to 'src')
-rw-r--r--src/lib/libc/stdlib/Makefile.inc4
-rw-r--r--src/lib/libc/stdlib/malloc.c61
2 files changed, 57 insertions, 8 deletions
diff --git a/src/lib/libc/stdlib/Makefile.inc b/src/lib/libc/stdlib/Makefile.inc
index f1708a1111..09db4ce793 100644
--- a/src/lib/libc/stdlib/Makefile.inc
+++ b/src/lib/libc/stdlib/Makefile.inc
@@ -1,10 +1,10 @@
1# $OpenBSD: Makefile.inc,v 1.38 2008/06/13 21:04:24 landry Exp $ 1# $OpenBSD: Makefile.inc,v 1.39 2008/08/22 17:14:56 otto Exp $
2 2
3# stdlib sources 3# stdlib sources
4.PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/stdlib ${LIBCSRCDIR}/stdlib 4.PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/stdlib ${LIBCSRCDIR}/stdlib
5 5
6SRCS+= a64l.c abort.c atexit.c atoi.c atof.c atol.c atoll.c bsearch.c \ 6SRCS+= a64l.c abort.c atexit.c atoi.c atof.c atol.c atoll.c bsearch.c \
7 calloc.c cfree.c exit.c ecvt.c gcvt.c getenv.c getopt_long.c \ 7 cfree.c exit.c ecvt.c gcvt.c getenv.c getopt_long.c \
8 getsubopt.c hcreate.c heapsort.c imaxabs.c imaxdiv.c l64a.c llabs.c \ 8 getsubopt.c hcreate.c heapsort.c imaxabs.c imaxdiv.c l64a.c llabs.c \
9 lldiv.c lsearch.c malloc.c merge.c putenv.c qsort.c radixsort.c rand.c \ 9 lldiv.c lsearch.c malloc.c merge.c putenv.c qsort.c radixsort.c rand.c \
10 random.c realpath.c setenv.c strtoimax.c strtod.c strtof.c strtol.c \ 10 random.c realpath.c setenv.c strtoimax.c strtod.c strtof.c strtol.c \
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c
index 645dc5afc9..d03b831514 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.93 2008/08/07 18:41:47 otto Exp $ */ 1/* $OpenBSD: malloc.c,v 1.94 2008/08/22 17:14:57 otto Exp $ */
2/* 2/*
3 * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net> 3 * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
4 * 4 *
@@ -443,7 +443,7 @@ unmap(struct dir_info *d, void *p, size_t sz)
443} 443}
444 444
445static void * 445static void *
446map(struct dir_info *d, size_t sz) 446map(struct dir_info *d, size_t sz, int zero_fill)
447{ 447{
448 size_t psz = PAGEROUND(sz) >> MALLOC_PAGESHIFT; 448 size_t psz = PAGEROUND(sz) >> MALLOC_PAGESHIFT;
449 struct region_info *r, *big = NULL; 449 struct region_info *r, *big = NULL;
@@ -454,6 +454,7 @@ map(struct dir_info *d, size_t sz)
454 p = MMAP(sz); 454 p = MMAP(sz);
455 if (p != MAP_FAILED) 455 if (p != MAP_FAILED)
456 malloc_used += sz; 456 malloc_used += sz;
457 /* zero fill not needed */
457 return p; 458 return p;
458 } 459 }
459 offset = getrbyte(); 460 offset = getrbyte();
@@ -469,6 +470,8 @@ map(struct dir_info *d, size_t sz)
469 r->p = NULL; 470 r->p = NULL;
470 r->size = 0; 471 r->size = 0;
471 d->free_regions_size -= psz; 472 d->free_regions_size -= psz;
473 if (zero_fill)
474 memset(p, 0, sz);
472 return p; 475 return p;
473 } else if (r->size > psz) 476 } else if (r->size > psz)
474 big = r; 477 big = r;
@@ -483,6 +486,8 @@ map(struct dir_info *d, size_t sz)
483 madvise(p, sz, MADV_NORMAL); 486 madvise(p, sz, MADV_NORMAL);
484 r->size -= psz; 487 r->size -= psz;
485 d->free_regions_size -= psz; 488 d->free_regions_size -= psz;
489 if (zero_fill)
490 memset(p, 0, sz);
486 return p; 491 return p;
487 } 492 }
488 p = MMAP(sz); 493 p = MMAP(sz);
@@ -490,6 +495,7 @@ map(struct dir_info *d, size_t sz)
490 malloc_used += sz; 495 malloc_used += sz;
491 if (d->free_regions_size > malloc_cache) 496 if (d->free_regions_size > malloc_cache)
492 wrtwarning("malloc cache"); 497 wrtwarning("malloc cache");
498 /* zero fill not needed */
493 return p; 499 return p;
494} 500}
495 501
@@ -835,7 +841,7 @@ omalloc_make_chunks(struct dir_info *d, int bits)
835 long i, k; 841 long i, k;
836 842
837 /* Allocate a new bucket */ 843 /* Allocate a new bucket */
838 pp = map(d, MALLOC_PAGESIZE); 844 pp = map(d, MALLOC_PAGESIZE, 0);
839 if (pp == MAP_FAILED) 845 if (pp == MAP_FAILED)
840 return NULL; 846 return NULL;
841 847
@@ -1053,7 +1059,7 @@ omalloc(size_t sz, int zero_fill)
1053 } 1059 }
1054 sz += malloc_guard; 1060 sz += malloc_guard;
1055 psz = PAGEROUND(sz); 1061 psz = PAGEROUND(sz);
1056 p = map(&g_pool, psz); 1062 p = map(&g_pool, psz, zero_fill);
1057 if (p == MAP_FAILED) { 1063 if (p == MAP_FAILED) {
1058 errno = ENOMEM; 1064 errno = ENOMEM;
1059 return NULL; 1065 return NULL;
@@ -1077,8 +1083,6 @@ omalloc(size_t sz, int zero_fill)
1077 sz - malloc_guard < MALLOC_PAGESIZE - MALLOC_MINSIZE) 1083 sz - malloc_guard < MALLOC_PAGESIZE - MALLOC_MINSIZE)
1078 p = ((char *)p) + ((MALLOC_PAGESIZE - MALLOC_MINSIZE - 1084 p = ((char *)p) + ((MALLOC_PAGESIZE - MALLOC_MINSIZE -
1079 (sz - malloc_guard)) & ~(MALLOC_MINSIZE-1)); 1085 (sz - malloc_guard)) & ~(MALLOC_MINSIZE-1));
1080 if (zero_fill)
1081 memset(p, 0, sz - malloc_guard);
1082 } else { 1086 } else {
1083 /* takes care of SOME_JUNK */ 1087 /* takes care of SOME_JUNK */
1084 p = malloc_bytes(&g_pool, sz); 1088 p = malloc_bytes(&g_pool, sz);
@@ -1323,3 +1327,48 @@ realloc(void *ptr, size_t size)
1323 } 1327 }
1324 return r; 1328 return r;
1325} 1329}
1330
1331
1332#define MUL_NO_OVERFLOW (1UL << (sizeof(size_t) * 4))
1333
1334void *
1335calloc(size_t nmemb, size_t size)
1336{
1337 void *r;
1338
1339 _MALLOC_LOCK();
1340 malloc_func = " in calloc():";
1341 if (!g_pool.regions_total) {
1342 if (omalloc_init(&g_pool)) {
1343 _MALLOC_UNLOCK();
1344 if (malloc_xmalloc)
1345 wrterror("out of memory");
1346 errno = ENOMEM;
1347 return NULL;
1348 }
1349 }
1350 if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
1351 nmemb > 0 && SIZE_MAX / nmemb < size) {
1352 _MALLOC_UNLOCK();
1353 if (malloc_xmalloc)
1354 wrterror("out of memory");
1355 errno = ENOMEM;
1356 return NULL;
1357 }
1358
1359 if (malloc_active++) {
1360 malloc_recurse();
1361 return NULL;
1362 }
1363
1364 size *= nmemb;
1365 r = omalloc(size, 1);
1366
1367 malloc_active--;
1368 _MALLOC_UNLOCK();
1369 if (r == NULL && malloc_xmalloc) {
1370 wrterror("out of memory");
1371 errno = ENOMEM;
1372 }
1373 return r;
1374}