Zap the rotor, it was a wrong idea. Cluebat applied by kshe who
authorotto <otto@openbsd.org>
Thu, 18 Jan 2018 20:06:16 +0000 (20:06 +0000)
committerotto <otto@openbsd.org>
Thu, 18 Jan 2018 20:06:16 +0000 (20:06 +0000)
came also up with this diff. Simple, no bias and benchmarks show the extra
random calls disappear in te measurement noise.

lib/libc/stdlib/malloc.c

index 40c602a..97d77b0 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: malloc.c,v 1.240 2018/01/18 08:37:28 otto Exp $       */
+/*     $OpenBSD: malloc.c,v 1.241 2018/01/18 20:06:16 otto Exp $       */
 /*
  * Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto@drijf.net>
  * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org>
@@ -172,7 +172,6 @@ struct chunk_info {
        u_short free;                   /* how many free chunks */
        u_short total;                  /* how many chunks */
        u_short offset;                 /* requested size table offset */
-       u_short rotor;                  /* randomization rotor */
        u_short bits[1];                /* which chunks are free */
 };
 
@@ -941,7 +940,7 @@ malloc_bytes(struct dir_info *d, size_t size, void *f)
 
        j = find_chunksize(size);
 
-       r = getrbyte(d);
+       r = ((u_int)getrbyte(d) << 8) | getrbyte(d);
        listnum = r % MALLOC_CHUNK_LISTS;
        /* If it's empty, make a page more of that size chunks */
        if ((bp = LIST_FIRST(&d->chunk_dir[j][listnum])) == NULL) {
@@ -953,9 +952,7 @@ malloc_bytes(struct dir_info *d, size_t size, void *f)
        if (bp->canary != (u_short)d->canary1)
                wrterror(d, "chunk info corrupted");
 
-       if (bp->free > 1)
-               bp->rotor += r;
-       i = bp->rotor++ & (bp->total - 1);
+       i = (r / MALLOC_CHUNK_LISTS) & (bp->total - 1);
 
        /* start somewhere in a short */
        lp = &bp->bits[i / MALLOC_BITS];