lib/rand: get rid of unused MAX_SEED_BUCKETS
[fio.git] / lib / rand.c
index 5eb6e60aeb6b651e88595b4ba9c2d875d1a5748d..0e787a62bad152568eee08824abf723716fec040 100644 (file)
@@ -59,7 +59,7 @@ static void __init_rand32(struct taus88_state *state, unsigned int seed)
                __rand32(state);
 }
 
-static void __init_rand64(struct taus258_state *state, uint64_t seed)
+void __init_rand64(struct taus258_state *state, uint64_t seed)
 {
        int cranks = 6;
 
@@ -95,40 +95,56 @@ void init_rand_seed(struct frand_state *state, uint64_t seed, bool use64)
                __init_rand64(&state->state64, seed);
 }
 
+void __fill_random_buf_small(void *buf, unsigned int len, uint64_t seed)
+{
+       uint64_t *b = buf;
+       uint64_t *e = b  + len / sizeof(*b);
+       unsigned int rest = len % sizeof(*b);
+
+       for (; b != e; ++b) {
+               *b = seed;
+               seed = __hash_u64(seed);
+       }
+
+       if (fio_unlikely(rest))
+               __builtin_memcpy(e, &seed, rest);
+}
+
 void __fill_random_buf(void *buf, unsigned int len, uint64_t seed)
 {
-       void *ptr = buf;
+       static uint64_t prime[] = {1, 2, 3, 5, 7, 11, 13, 17,
+                                  19, 23, 29, 31, 37, 41, 43, 47};
+       uint64_t *b, *e, s[CONFIG_SEED_BUCKETS];
+       unsigned int rest;
+       int p;
 
-       while (len) {
-               int this_len;
-
-               if (len >= sizeof(int64_t)) {
-                       *((int64_t *) ptr) = seed;
-                       this_len = sizeof(int64_t);
-               } else if (len >= sizeof(int32_t)) {
-                       *((int32_t *) ptr) = seed;
-                       this_len = sizeof(int32_t);
-               } else if (len >= sizeof(int16_t)) {
-                       *((int16_t *) ptr) = seed;
-                       this_len = sizeof(int16_t);
-               } else {
-                       *((int8_t *) ptr) = seed;
-                       this_len = sizeof(int8_t);
+       /*
+        * Calculate the max index which is multiples of the seed buckets.
+        */
+       rest = (len / sizeof(*b) / CONFIG_SEED_BUCKETS) * CONFIG_SEED_BUCKETS;
+
+       b = buf;
+       e = b + rest;
+
+       rest = len - (rest * sizeof(*b));
+
+       for (p = 0; p < CONFIG_SEED_BUCKETS; p++)
+               s[p] = seed * prime[p];
+
+       for (; b != e; b += CONFIG_SEED_BUCKETS) {
+               for (p = 0; p < CONFIG_SEED_BUCKETS; ++p) {
+                       b[p] = s[p];
+                       s[p] = __hash_u64(s[p]);
                }
-               ptr += this_len;
-               len -= this_len;
-               seed *= GOLDEN_RATIO_PRIME;
-               seed >>= 3;
        }
+
+       __fill_random_buf_small(b, rest, s[0]);
 }
 
 uint64_t fill_random_buf(struct frand_state *fs, void *buf,
                         unsigned int len)
 {
-       uint64_t r = __rand(fs);
-
-       if (sizeof(int) != sizeof(long *))
-               r *= (unsigned long) __rand(fs);
+       uint64_t r = __get_next_seed(fs);
 
        __fill_random_buf(buf, len, r);
        return r;
@@ -188,10 +204,7 @@ uint64_t fill_random_buf_percentage(struct frand_state *fs, void *buf,
                                    unsigned int segment, unsigned int len,
                                    char *pattern, unsigned int pbytes)
 {
-       uint64_t r = __rand(fs);
-
-       if (sizeof(int) != sizeof(long *))
-               r *= (unsigned long) __rand(fs);
+       uint64_t r = __get_next_seed(fs);
 
        __fill_random_buf_percentage(r, buf, percentage, segment, len,
                                        pattern, pbytes);