summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortedu <>2014-05-12 19:02:20 +0000
committertedu <>2014-05-12 19:02:20 +0000
commit1b7bf9f1ebd8096b9d44b3bf148bd664715501ab (patch)
tree63bbc29300741fdb381b71619be0351944a63078
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.
-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