#include "lfsr.h"
/*
- * Trom table 3 of
+ * From table 3 of
*
* http://www.xilinx.com/support/documentation/application_notes/xapp052.pdf
*/
},
};
+#define FIO_LFSR_CRANKS 128
+
static uint64_t __lfsr_next(uint64_t v, struct lfsr_taps *lt)
{
uint64_t xor_mask = 0;
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);
int i;
for (i = 0; lfsr_taps[i].length; i++)
- if ((1UL << lfsr_taps[i].length) >= size)
+ if (((1UL << lfsr_taps[i].length) + FIO_LFSR_CRANKS) >= size)
return &lfsr_taps[i];
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;
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;
}
+ lfsr_reset(fl, seed);
return 0;
}