nibbles aren't enough random, use bytes. does a better job of picking
authortedu <tedu@openbsd.org>
Thu, 1 May 2014 04:08:13 +0000 (04:08 +0000)
committertedu <tedu@openbsd.org>
Thu, 1 May 2014 04:08:13 +0000 (04:08 +0000)
a free chunk at random and may allow to increase delayed chunk array.
ok otto

lib/libc/stdlib/malloc.c

index e7a113c..40bf665 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: malloc.c,v 1.158 2014/04/23 15:07:27 tedu Exp $       */
+/*     $OpenBSD: malloc.c,v 1.159 2014/05/01 04:08:13 tedu Exp $       */
 /*
  * Copyright (c) 2008, 2010, 2011 Otto Moerbeek <otto@drijf.net>
  * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org>
@@ -61,7 +61,7 @@
 
 #define MALLOC_MAXCHUNK                (1 << MALLOC_MAXSHIFT)
 #define MALLOC_MAXCACHE                256
-#define MALLOC_DELAYED_CHUNKS  15      /* max of getrnibble() */
+#define MALLOC_DELAYED_CHUNK_MASK      15
 #define MALLOC_INITIAL_REGIONS 512
 #define MALLOC_DEFAULT_CACHE   64
 
@@ -115,7 +115,7 @@ struct dir_info {
                                        /* free pages cache */
        struct region_info free_regions[MALLOC_MAXCACHE];
                                        /* delayed free chunk slots */
-       void *delayed_chunks[MALLOC_DELAYED_CHUNKS + 1];
+       void *delayed_chunks[MALLOC_DELAYED_CHUNK_MASK + 1];
        u_short chunk_start;
 #ifdef MALLOC_STATS
        size_t inserts;
@@ -191,9 +191,9 @@ static int  malloc_active;          /* status of malloc */
 static size_t  malloc_guarded;         /* bytes used for guards */
 static size_t  malloc_used;            /* bytes allocated */
 
-static size_t rnibblesused;            /* random nibbles used */
+static size_t rbytesused;              /* random bytes used */
 static u_char rbytes[512];             /* random bytes */
-static u_char getrnibble(void);
+static u_char getrbyte(void);
 
 extern char    *__progname;
 
@@ -273,18 +273,18 @@ static void
 rbytes_init(void)
 {
        arc4random_buf(rbytes, sizeof(rbytes));
-       rnibblesused = 0;
+       rbytesused = 0;
 }
 
 static inline u_char
-getrnibble(void)
+getrbyte(void)
 {
        u_char x;
 
-       if (rnibblesused >= 2 * sizeof(rbytes))
+       if (rbytesused >= sizeof(rbytes))
                rbytes_init();
-       x = rbytes[rnibblesused++ / 2];
-       return (rnibblesused & 1 ? x & 0xf : x >> 4);
+       x = rbytes[rbytesused++];
+       return x;
 }
 
 /*
@@ -317,7 +317,7 @@ unmap(struct dir_info *d, void *p, size_t sz)
        rsz = mopts.malloc_cache - d->free_regions_size;
        if (psz > rsz)
                tounmap = psz - rsz;
-       offset = getrnibble() + (getrnibble() << 4);
+       offset = getrbyte();
        for (i = 0; tounmap > 0 && i < mopts.malloc_cache; i++) {
                r = &d->free_regions[(i + offset) & (mopts.malloc_cache - 1)];
                if (r->p != NULL) {
@@ -398,7 +398,7 @@ map(struct dir_info *d, size_t sz, int zero_fill)
                /* zero fill not needed */
                return p;
        }
-       offset = getrnibble() + (getrnibble() << 4);
+       offset = getrbyte();
        for (i = 0; i < mopts.malloc_cache; i++) {
                r = &d->free_regions[(i + offset) & (mopts.malloc_cache - 1)];
                if (r->p != NULL) {
@@ -920,7 +920,7 @@ malloc_bytes(struct dir_info *d, size_t size, void *f)
 
        i = d->chunk_start;
        if (bp->free > 1)
-               i += getrnibble();
+               i += getrbyte();
        if (i >= bp->total)
                i &= bp->total - 1;
        for (;;) {
@@ -1200,7 +1200,7 @@ ofree(void *p)
                if (mopts.malloc_junk && sz > 0)
                        memset(p, SOME_FREEJUNK, sz);
                if (!mopts.malloc_freenow) {
-                       i = getrnibble();
+                       i = getrbyte() & MALLOC_DELAYED_CHUNK_MASK;
                        tmp = p;
                        p = g_pool->delayed_chunks[i];
                        g_pool->delayed_chunks[i] = tmp;