summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorotto <>2011-04-30 14:56:20 +0000
committerotto <>2011-04-30 14:56:20 +0000
commit9d3549427fb1b5b7e4751c18927defcca9b4e9c5 (patch)
treea16580dae10c659d609888cb4e41a6b2cf00c9c0 /src
parent246a14116b208014d1fe291101141c41bcbaed1e (diff)
downloadopenbsd-9d3549427fb1b5b7e4751c18927defcca9b4e9c5.tar.gz
openbsd-9d3549427fb1b5b7e4751c18927defcca9b4e9c5.tar.bz2
openbsd-9d3549427fb1b5b7e4751c18927defcca9b4e9c5.zip
More efficient scanning for free chunks while not losing any randomization;
thanks to all testers.
Diffstat (limited to 'src')
-rw-r--r--src/lib/libc/stdlib/malloc.c46
1 files changed, 25 insertions, 21 deletions
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c
index 8d7d3ae18a..010cb7fafc 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.127 2010/12/16 18:47:01 dhill Exp $ */ 1/* $OpenBSD: malloc.c,v 1.128 2011/04/30 14:56:20 otto Exp $ */
2/* 2/*
3 * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net> 3 * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
4 * 4 *
@@ -138,7 +138,7 @@ struct dir_info {
138 * 138 *
139 * How many bits per u_long in the bitmap 139 * How many bits per u_long in the bitmap
140 */ 140 */
141#define MALLOC_BITS (NBBY * sizeof(u_long)) 141#define MALLOC_BITS (NBBY * sizeof(u_short))
142struct chunk_info { 142struct chunk_info {
143 LIST_ENTRY(chunk_info) entries; 143 LIST_ENTRY(chunk_info) entries;
144 void *page; /* pointer to the page */ 144 void *page; /* pointer to the page */
@@ -148,7 +148,7 @@ struct chunk_info {
148 u_short free; /* how many free chunks */ 148 u_short free; /* how many free chunks */
149 u_short total; /* how many chunk */ 149 u_short total; /* how many chunk */
150 /* which chunks are free */ 150 /* which chunks are free */
151 u_long bits[(MALLOC_PAGESIZE / MALLOC_MINSIZE) / MALLOC_BITS]; 151 u_short bits[(MALLOC_PAGESIZE / MALLOC_MINSIZE) / MALLOC_BITS];
152}; 152};
153 153
154struct malloc_readonly { 154struct malloc_readonly {
@@ -958,10 +958,10 @@ omalloc_make_chunks(struct dir_info *d, int bits)
958 958
959 /* Do a bunch at a time */ 959 /* Do a bunch at a time */
960 for (; (k - i) >= MALLOC_BITS; i += MALLOC_BITS) 960 for (; (k - i) >= MALLOC_BITS; i += MALLOC_BITS)
961 bp->bits[i / MALLOC_BITS] = ~0UL; 961 bp->bits[i / MALLOC_BITS] = (u_short)~0U;
962 962
963 for (; i < k; i++) 963 for (; i < k; i++)
964 bp->bits[i / MALLOC_BITS] |= 1UL << (i % MALLOC_BITS); 964 bp->bits[i / MALLOC_BITS] |= (u_short)1U << (i % MALLOC_BITS);
965 965
966 LIST_INSERT_HEAD(&d->chunk_dir[bits], bp, entries); 966 LIST_INSERT_HEAD(&d->chunk_dir[bits], bp, entries);
967 967
@@ -982,7 +982,7 @@ malloc_bytes(struct dir_info *d, size_t size)
982{ 982{
983 int i, j; 983 int i, j;
984 size_t k; 984 size_t k;
985 u_long u, *lp; 985 u_short u, *lp;
986 struct chunk_info *bp; 986 struct chunk_info *bp;
987 987
988 if (mopts.malloc_canary != (d->canary1 ^ (u_int32_t)(uintptr_t)d) || 988 if (mopts.malloc_canary != (d->canary1 ^ (u_int32_t)(uintptr_t)d) ||
@@ -1026,22 +1026,26 @@ malloc_bytes(struct dir_info *d, size_t size)
1026 } 1026 }
1027 1027
1028 /* advance a random # of positions */ 1028 /* advance a random # of positions */
1029 i = getrnibble() % bp->free; 1029 if (bp->free > 1) {
1030 while (i > 0) { 1030 i = getrnibble() % bp->free;
1031 u += u; 1031 while (i > 0) {
1032 k++; 1032 u += u;
1033 if (k >= MALLOC_BITS) { 1033 k++;
1034 lp++; 1034 if (k >= MALLOC_BITS) {
1035 u = 1; 1035 while (!*++lp)
1036 k = 0; 1036 /* EMPTY */;
1037 } 1037 u = 1;
1038 if (lp - bp->bits > (bp->total - 1) / MALLOC_BITS) { 1038 k = 0;
1039 wrterror("chunk overflow", NULL); 1039 if (lp - bp->bits > (bp->total - 1) /
1040 errno = EFAULT; 1040 MALLOC_BITS) {
1041 return (NULL); 1041 wrterror("chunk overflow", NULL);
1042 errno = EFAULT;
1043 return (NULL);
1044 }
1045 }
1046 if (*lp & u)
1047 i--;
1042 } 1048 }
1043 if (*lp & u)
1044 i--;
1045 } 1049 }
1046 1050
1047 *lp ^= u; 1051 *lp ^= u;