X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=lib%2Flfsr.c;h=61a3aaf3e6532c32722314da125bcce69cf98416;hb=44cbc6daaae3674ea5d0a113b66596ca24f372e0;hp=64442ab536d40fc2ac3894fc30043fcc94ef1e2b;hpb=8055e41d0ecc54770a2653427532b3e2c5fabdad;p=fio.git diff --git a/lib/lfsr.c b/lib/lfsr.c index 64442ab5..61a3aaf3 100644 --- a/lib/lfsr.c +++ b/lib/lfsr.c @@ -3,7 +3,7 @@ #include "lfsr.h" /* - * Trom table 3 of + * From table 3 of * * http://www.xilinx.com/support/documentation/application_notes/xapp052.pdf */ @@ -202,6 +202,8 @@ static struct lfsr_taps lfsr_taps[] = { }, }; +#define FIO_LFSR_CRANKS 128 + static uint64_t __lfsr_next(uint64_t v, struct lfsr_taps *lt) { uint64_t xor_mask = 0; @@ -214,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); @@ -235,13 +238,24 @@ static struct lfsr_taps *find_lfsr(uint64_t size) 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; @@ -250,15 +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; } + lfsr_reset(fl, seed); return 0; }