lfsr: add lfsr_reset()
[fio.git] / lib / lfsr.c
index 01c97cb80b1df7a7c8bfa6f9d84f7e366f286390..61a3aaf3e6532c32722314da125bcce69cf98416 100644 (file)
@@ -216,14 +216,15 @@ static uint64_t __lfsr_next(uint64_t v, struct lfsr_taps *lt)
        return xor_mask | (v >> 1);
 }
 
-int lfsr_next(struct fio_lfsr *fl, uint64_t *off)
+int lfsr_next(struct fio_lfsr *fl, uint64_t *off, uint64_t last)
 {
        if (fl->num_vals > fl->max_val)
                return 1;
 
        do {
                fl->last_val = __lfsr_next(fl->last_val, &fl->taps);
-               if (fl->last_val - 1 <= fl->max_val)
+               if (fl->last_val - 1 <= fl->max_val &&
+                   fl->last_val <= last)
                        break;
        } while (1);
 
@@ -243,7 +244,18 @@ static struct lfsr_taps *find_lfsr(uint64_t size)
        return NULL;
 }
 
-int lfsr_init(struct fio_lfsr *fl, uint64_t size)
+void lfsr_reset(struct fio_lfsr *fl, unsigned long seed)
+{
+       unsigned int i;
+
+       fl->last_val = seed;
+       fl->num_vals = 0;
+
+       for (i = 0; i < FIO_LFSR_CRANKS; i++)
+               fl->last_val = __lfsr_next(fl->last_val, &fl->taps);
+}
+
+int lfsr_init(struct fio_lfsr *fl, uint64_t size, unsigned long seed)
 {
        struct lfsr_taps *tap;
        int i;
@@ -252,18 +264,15 @@ int lfsr_init(struct fio_lfsr *fl, uint64_t size)
        if (!tap)
                return 1;
 
-       fl->last_val = 1;
        fl->max_val = size - 1;
-       fl->num_vals = 0;
        fl->taps.length = tap->length;
+
        for (i = 0; i < FIO_MAX_TAPS; i++) {
                fl->taps.taps[i] = tap->taps[i];
                if (!fl->taps.taps[i])
                        break;
        }
 
-       for (i = 0; i < FIO_LFSR_CRANKS; i++)
-               fl->last_val = __lfsr_next(fl->last_val, &fl->taps);
-
+       lfsr_reset(fl, seed);
        return 0;
 }