X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=lib%2Flfsr.c;h=b10ba7a7e1b3cfc07609b53f6c68317fa14cb53e;hb=21356fee2727b71ef72b39414955c5e7e98f97c1;hp=a83540494fc1964aebb7d89fad86a730030ab211;hpb=b136e932040242ff2245e5cfc97df82a7fd03ceb;p=fio.git diff --git a/lib/lfsr.c b/lib/lfsr.c index a8354049..b10ba7a7 100644 --- a/lib/lfsr.c +++ b/lib/lfsr.c @@ -108,24 +108,40 @@ static inline void __lfsr_next(struct fio_lfsr *fl, unsigned int spin) } } +/* + * lfsr_next does the following: + * + * a. Return if the number of max values has been exceeded. + * b. Check if we have a spin value that produces a repeating subsequence. + * This is previously calculated in `prepare_spin` and cycle_length should + * be > 0. If we do have such a spin: + * + * i. Decrement the calculated cycle. + * ii. If it reaches zero, add "+1" to the spin and reset the cycle_length + * (we have it cached in the struct fio_lfsr) + * + * In either case, continue with the calculation of the next value. + * c. Check if the calculated value exceeds the desirable range. In this case, + * go back to b, else return. + */ int lfsr_next(struct fio_lfsr *fl, uint64_t *off, uint64_t last) { - int repeat; - unsigned int spin; - - repeat = fl->num_vals % fl->cycle_length; - if (repeat == 0) - spin = fl->spin + 1; - else - spin = fl->spin; + unsigned int spin = fl->spin; - if (fl->num_vals > fl->max_val) + if (fl->num_vals++ > fl->max_val) return 1; - fl->num_vals++; - do { + if (fl->cycle_length) { + fl->cycle_length--; + if (!fl->cycle_length) { + __lfsr_next(fl, fl->spin + 1); + fl->cycle_length = fl->cached_cycle_length; + goto check; + } + } __lfsr_next(fl, spin); +check: ; } while (fl->last_val > fl->max_val); *off = fl->last_val; @@ -183,7 +199,7 @@ int prepare_spin(struct fio_lfsr *fl, unsigned int spin) x = max / (spin + 1); y = max % (spin + 1); - fl->cycle_length = max; /* This is the expected cycle */ + fl->cycle_length = 0; /* No cycle occurs, other than the expected */ fl->spin = spin; for (i = 1; i <= spin; i++) { @@ -192,6 +208,7 @@ int prepare_spin(struct fio_lfsr *fl, unsigned int spin) break; } } + fl->cached_cycle_length = fl->cycle_length; return 0; }