diff options
author | otto <> | 2011-04-30 14:56:20 +0000 |
---|---|---|
committer | otto <> | 2011-04-30 14:56:20 +0000 |
commit | 9d3549427fb1b5b7e4751c18927defcca9b4e9c5 (patch) | |
tree | a16580dae10c659d609888cb4e41a6b2cf00c9c0 /src | |
parent | 246a14116b208014d1fe291101141c41bcbaed1e (diff) | |
download | openbsd-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.c | 46 |
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)) |
142 | struct chunk_info { | 142 | struct 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 | ||
154 | struct malloc_readonly { | 154 | struct 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; |