summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortedu <>2014-05-12 19:02:20 +0000
committertedu <>2014-05-12 19:02:20 +0000
commit1b7bf9f1ebd8096b9d44b3bf148bd664715501ab (patch)
tree63bbc29300741fdb381b71619be0351944a63078 /src
parentdede2c823d35f580f859348c66c7313aa7093350 (diff)
downloadopenbsd-1b7bf9f1ebd8096b9d44b3bf148bd664715501ab.tar.gz
openbsd-1b7bf9f1ebd8096b9d44b3bf148bd664715501ab.tar.bz2
openbsd-1b7bf9f1ebd8096b9d44b3bf148bd664715501ab.zip
change to having four freelists per size, to reduce another source of
deterministic behavior. four selected because it's more than three, less than five. i.e., no particular reason.
Diffstat (limited to 'src')
-rw-r--r--src/lib/libc/stdlib/malloc.c36
1 files changed, 20 insertions, 16 deletions
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c
index 361294eb51..c0542fc9c8 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.162 2014/05/10 18:14:55 otto Exp $ */ 1/* $OpenBSD: malloc.c,v 1.163 2014/05/12 19:02:20 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>
@@ -64,6 +64,7 @@
64#define MALLOC_DELAYED_CHUNK_MASK 15 64#define MALLOC_DELAYED_CHUNK_MASK 15
65#define MALLOC_INITIAL_REGIONS 512 65#define MALLOC_INITIAL_REGIONS 512
66#define MALLOC_DEFAULT_CACHE 64 66#define MALLOC_DEFAULT_CACHE 64
67#define MALLOC_CHUNK_LISTS 4
67 68
68/* 69/*
69 * When the P option is active, we move allocations between half a page 70 * When the P option is active, we move allocations between half a page
@@ -110,7 +111,7 @@ struct dir_info {
110 /* lists of free chunk info structs */ 111 /* lists of free chunk info structs */
111 struct chunk_head chunk_info_list[MALLOC_MAXSHIFT + 1]; 112 struct chunk_head chunk_info_list[MALLOC_MAXSHIFT + 1];
112 /* lists of chunks with free slots */ 113 /* lists of chunks with free slots */
113 struct chunk_head chunk_dir[MALLOC_MAXSHIFT + 1]; 114 struct chunk_head chunk_dir[MALLOC_MAXSHIFT + 1][MALLOC_CHUNK_LISTS];
114 size_t free_regions_size; /* free pages cached */ 115 size_t free_regions_size; /* free pages cached */
115 /* free pages cache */ 116 /* free pages cache */
116 struct region_info free_regions[MALLOC_MAXCACHE]; 117 struct region_info free_regions[MALLOC_MAXCACHE];
@@ -621,7 +622,8 @@ omalloc_init(struct dir_info **dp)
621 } 622 }
622 for (i = 0; i <= MALLOC_MAXSHIFT; i++) { 623 for (i = 0; i <= MALLOC_MAXSHIFT; i++) {
623 LIST_INIT(&d->chunk_info_list[i]); 624 LIST_INIT(&d->chunk_info_list[i]);
624 LIST_INIT(&d->chunk_dir[i]); 625 for (j = 0; j < MALLOC_CHUNK_LISTS; j++)
626 LIST_INIT(&d->chunk_dir[i][j]);
625 } 627 }
626 malloc_used += regioninfo_size; 628 malloc_used += regioninfo_size;
627 d->canary1 = mopts.malloc_canary ^ (u_int32_t)(uintptr_t)d; 629 d->canary1 = mopts.malloc_canary ^ (u_int32_t)(uintptr_t)d;
@@ -816,7 +818,7 @@ delete(struct dir_info *d, struct region_info *ri)
816 * Allocate a page of chunks 818 * Allocate a page of chunks
817 */ 819 */
818static struct chunk_info * 820static struct chunk_info *
819omalloc_make_chunks(struct dir_info *d, int bits) 821omalloc_make_chunks(struct dir_info *d, int bits, int listnum)
820{ 822{
821 struct chunk_info *bp; 823 struct chunk_info *bp;
822 void *pp; 824 void *pp;
@@ -867,7 +869,7 @@ omalloc_make_chunks(struct dir_info *d, int bits)
867 for (; i < k; i++) 869 for (; i < k; i++)
868 bp->bits[i / MALLOC_BITS] |= (u_short)1U << (i % MALLOC_BITS); 870 bp->bits[i / MALLOC_BITS] |= (u_short)1U << (i % MALLOC_BITS);
869 871
870 LIST_INSERT_HEAD(&d->chunk_dir[bits], bp, entries); 872 LIST_INSERT_HEAD(&d->chunk_dir[bits][listnum], bp, entries);
871 873
872 bits++; 874 bits++;
873 if ((uintptr_t)pp & bits) 875 if ((uintptr_t)pp & bits)
@@ -884,7 +886,7 @@ omalloc_make_chunks(struct dir_info *d, int bits)
884static void * 886static void *
885malloc_bytes(struct dir_info *d, size_t size, void *f) 887malloc_bytes(struct dir_info *d, size_t size, void *f)
886{ 888{
887 int i, j; 889 int i, j, listnum;
888 size_t k; 890 size_t k;
889 u_short u, *lp; 891 u_short u, *lp;
890 struct chunk_info *bp; 892 struct chunk_info *bp;
@@ -907,13 +909,13 @@ malloc_bytes(struct dir_info *d, size_t size, void *f)
907 j++; 909 j++;
908 } 910 }
909 911
912 listnum = getrbyte() % MALLOC_CHUNK_LISTS;
910 /* If it's empty, make a page more of that size chunks */ 913 /* If it's empty, make a page more of that size chunks */
911 if (LIST_EMPTY(&d->chunk_dir[j])) { 914 if ((bp = LIST_FIRST(&d->chunk_dir[j][listnum])) == NULL) {
912 bp = omalloc_make_chunks(d, j); 915 bp = omalloc_make_chunks(d, j, listnum);
913 if (bp == NULL) 916 if (bp == NULL)
914 return NULL; 917 return NULL;
915 } else 918 }
916 bp = LIST_FIRST(&d->chunk_dir[j]);
917 919
918 if (bp->canary != d->canary1) 920 if (bp->canary != d->canary1)
919 wrterror("chunk info corrupted", NULL); 921 wrterror("chunk info corrupted", NULL);
@@ -973,7 +975,7 @@ free_bytes(struct dir_info *d, struct region_info *r, void *ptr)
973{ 975{
974 struct chunk_head *mp; 976 struct chunk_head *mp;
975 struct chunk_info *info; 977 struct chunk_info *info;
976 int i; 978 int i, listnum;
977 979
978 info = (struct chunk_info *)r->size; 980 info = (struct chunk_info *)r->size;
979 if (info->canary != d->canary1) 981 if (info->canary != d->canary1)
@@ -994,16 +996,18 @@ free_bytes(struct dir_info *d, struct region_info *r, void *ptr)
994 info->bits[i / MALLOC_BITS] |= 1U << (i % MALLOC_BITS); 996 info->bits[i / MALLOC_BITS] |= 1U << (i % MALLOC_BITS);
995 info->free++; 997 info->free++;
996 998
997 if (info->size != 0)
998 mp = d->chunk_dir + info->shift;
999 else
1000 mp = d->chunk_dir;
1001
1002 if (info->free == 1) { 999 if (info->free == 1) {
1003 /* Page became non-full */ 1000 /* Page became non-full */
1001 listnum = getrbyte() % MALLOC_CHUNK_LISTS;
1002 if (info->size != 0)
1003 mp = &d->chunk_dir[info->shift][listnum];
1004 else
1005 mp = &d->chunk_dir[0][listnum];
1006
1004 LIST_INSERT_HEAD(mp, info, entries); 1007 LIST_INSERT_HEAD(mp, info, entries);
1005 return; 1008 return;
1006 } 1009 }
1010
1007 if (info->free != info->total) 1011 if (info->free != info->total)
1008 return; 1012 return;
1009 1013