tausworthe Strong 2^88 cycle random number generator
lfsr Linear feedback shift register generator
+ tausworthe64 Strong 64-bit 2^258 cycle random number
+ generator
Tausworthe is a strong random number generator, but it
requires tracking on the side if we want to ensure that
if (is_backend) {
void *data;
+ int ver;
ret = fio_server_get_verify_state(td->o.name,
- td->thread_number - 1, &data);
+ td->thread_number - 1, &data, &ver);
if (!ret)
- verify_convert_assign_state(td, data);
+ verify_convert_assign_state(td, data, ver);
} else
ret = verify_load_state(td, "local");
}
buf = malloc(CHUNK);
- init_rand_seed(&state, 0x8989);
+ init_rand_seed(&state, 0x8989, 0);
fill_random_buf(&state, buf, CHUNK);
for (i = 0; t[i].name; i++) {
static unsigned long long get_rand_file_size(struct thread_data *td)
{
unsigned long long ret, sized;
+ uint64_t frand_max;
unsigned long r;
+ frand_max = rand_max(&td->file_size_state);
r = __rand(&td->file_size_state);
sized = td->o.file_size_high - td->o.file_size_low;
- ret = (unsigned long long) ((double) sized * (r / (FRAND_MAX + 1.0)));
+ ret = (unsigned long long) ((double) sized * (r / (frand_max + 1.0)));
ret += td->o.file_size_low;
ret -= (ret % td->o.rw_min_bs);
return ret;
.B lfsr
Linear feedback shift register generator
.TP
+.B tausworthe64
+Strong 64-bit 2^258 cycle random number generator
+.TP
.RE
.P
Tausworthe is a strong random number generator, but it requires tracking on the
enum {
FIO_RAND_GEN_TAUSWORTHE = 0,
FIO_RAND_GEN_LFSR,
+ FIO_RAND_GEN_TAUSWORTHE64,
};
enum {
static unsigned long long get_rand_start_delay(struct thread_data *td)
{
unsigned long long delayrange;
+ uint64_t frand_max;
unsigned long r;
delayrange = td->o.start_delay_high - td->o.start_delay;
+ frand_max = rand_max(&td->delay_state);
r = __rand(&td->delay_state);
- delayrange = (unsigned long long) ((double) delayrange * (r / (FRAND_MAX + 1.0)));
+ delayrange = (unsigned long long) ((double) delayrange * (r / (frand_max + 1.0)));
delayrange += td->o.start_delay;
return delayrange;
return 1;
}
-static void td_fill_rand_seeds_internal(struct thread_data *td)
+static void td_fill_rand_seeds_internal(struct thread_data *td, int use64)
{
- init_rand_seed(&td->bsrange_state, td->rand_seeds[FIO_RAND_BS_OFF]);
- init_rand_seed(&td->verify_state, td->rand_seeds[FIO_RAND_VER_OFF]);
- init_rand_seed(&td->rwmix_state, td->rand_seeds[FIO_RAND_MIX_OFF]);
+ init_rand_seed(&td->bsrange_state, td->rand_seeds[FIO_RAND_BS_OFF], use64);
+ init_rand_seed(&td->verify_state, td->rand_seeds[FIO_RAND_VER_OFF], use64);
+ init_rand_seed(&td->rwmix_state, td->rand_seeds[FIO_RAND_MIX_OFF], use64);
if (td->o.file_service_type == FIO_FSERVICE_RANDOM)
- init_rand_seed(&td->next_file_state, td->rand_seeds[FIO_RAND_FILE_OFF]);
+ init_rand_seed(&td->next_file_state, td->rand_seeds[FIO_RAND_FILE_OFF], use64);
- init_rand_seed(&td->file_size_state, td->rand_seeds[FIO_RAND_FILE_SIZE_OFF]);
- init_rand_seed(&td->trim_state, td->rand_seeds[FIO_RAND_TRIM_OFF]);
- init_rand_seed(&td->delay_state, td->rand_seeds[FIO_RAND_START_DELAY]);
+ init_rand_seed(&td->file_size_state, td->rand_seeds[FIO_RAND_FILE_SIZE_OFF], use64);
+ init_rand_seed(&td->trim_state, td->rand_seeds[FIO_RAND_TRIM_OFF], use64);
+ init_rand_seed(&td->delay_state, td->rand_seeds[FIO_RAND_START_DELAY], use64);
if (!td_random(td))
return;
if (td->o.rand_repeatable)
td->rand_seeds[FIO_RAND_BLOCK_OFF] = FIO_RANDSEED * td->thread_number;
- init_rand_seed(&td->random_state, td->rand_seeds[FIO_RAND_BLOCK_OFF]);
- init_rand_seed(&td->seq_rand_state[DDIR_READ], td->rand_seeds[FIO_RAND_SEQ_RAND_READ_OFF]);
- init_rand_seed(&td->seq_rand_state[DDIR_WRITE], td->rand_seeds[FIO_RAND_SEQ_RAND_WRITE_OFF]);
- init_rand_seed(&td->seq_rand_state[DDIR_TRIM], td->rand_seeds[FIO_RAND_SEQ_RAND_TRIM_OFF]);
+ init_rand_seed(&td->random_state, td->rand_seeds[FIO_RAND_BLOCK_OFF], use64);
+ init_rand_seed(&td->seq_rand_state[DDIR_READ], td->rand_seeds[FIO_RAND_SEQ_RAND_READ_OFF], use64);
+ init_rand_seed(&td->seq_rand_state[DDIR_WRITE], td->rand_seeds[FIO_RAND_SEQ_RAND_WRITE_OFF], use64);
+ init_rand_seed(&td->seq_rand_state[DDIR_TRIM], td->rand_seeds[FIO_RAND_SEQ_RAND_TRIM_OFF], use64);
}
void td_fill_rand_seeds(struct thread_data *td)
{
+ int use64;
+
if (td->o.allrand_repeatable) {
unsigned int i;
+ i;
}
- td_fill_rand_seeds_internal(td);
+ if (td->o.random_generator == FIO_RAND_GEN_TAUSWORTHE64)
+ use64 = 1;
+ else
+ use64 = 0;
+
+ td_fill_rand_seeds_internal(td, use64);
- init_rand_seed(&td->buf_state, td->rand_seeds[FIO_RAND_BUF_OFF]);
+ init_rand_seed(&td->buf_state, td->rand_seeds[FIO_RAND_BUF_OFF], use64);
frand_copy(&td->buf_state_prev, &td->buf_state);
- init_rand_seed(&td->dedupe_state, td->rand_seeds[FIO_DEDUPE_OFF]);
+ init_rand_seed(&td->dedupe_state, td->rand_seeds[FIO_DEDUPE_OFF], use64);
}
/*
{
uint64_t r;
- if (td->o.random_generator == FIO_RAND_GEN_TAUSWORTHE) {
- uint64_t lastb;
+ if (td->o.random_generator == FIO_RAND_GEN_TAUSWORTHE ||
+ td->o.random_generator == FIO_RAND_GEN_TAUSWORTHE64) {
+ uint64_t frand_max, lastb;
lastb = last_block(td, f, ddir);
if (!lastb)
return 1;
+ frand_max = rand_max(&td->random_state);
r = __rand(&td->random_state);
dprint(FD_RANDOM, "off rand %llu\n", (unsigned long long) r);
- *b = lastb * (r / ((uint64_t) FRAND_MAX + 1.0));
+ *b = lastb * (r / ((uint64_t) frand_max + 1.0));
} else {
uint64_t off = 0;
return 0;
if (td->runstate != TD_VERIFYING)
return 0;
- if (td->o.random_generator == FIO_RAND_GEN_TAUSWORTHE)
+ if (td->o.random_generator == FIO_RAND_GEN_TAUSWORTHE ||
+ td->o.random_generator == FIO_RAND_GEN_TAUSWORTHE64)
return 0;
return 1;
static int should_do_random(struct thread_data *td, enum fio_ddir ddir)
{
+ uint64_t frand_max;
unsigned int v;
unsigned long r;
if (td->o.perc_rand[ddir] == 100)
return 1;
+ frand_max = rand_max(&td->seq_rand_state[ddir]);
r = __rand(&td->seq_rand_state[ddir]);
- v = 1 + (int) (100.0 * (r / (FRAND_MAX + 1.0)));
+ v = 1 + (int) (100.0 * (r / (frand_max + 1.0)));
return v <= td->o.perc_rand[ddir];
}
int ddir = io_u->ddir;
unsigned int buflen = 0;
unsigned int minbs, maxbs;
+ uint64_t frand_max;
unsigned long r;
assert(ddir_rw(ddir));
if (!io_u_fits(td, io_u, minbs))
return 0;
+ frand_max = rand_max(&td->bsrange_state);
do {
r = __rand(&td->bsrange_state);
if (!td->o.bssplit_nr[ddir]) {
buflen = 1 + (unsigned int) ((double) maxbs *
- (r / (FRAND_MAX + 1.0)));
+ (r / (frand_max + 1.0)));
if (buflen < minbs)
buflen = minbs;
} else {
buflen = bsp->bs;
perc += bsp->perc;
- if ((r <= ((FRAND_MAX / 100L) * perc)) &&
+ if ((r <= ((frand_max / 100L) * perc)) &&
io_u_fits(td, io_u, buflen))
break;
}
static inline enum fio_ddir get_rand_ddir(struct thread_data *td)
{
+ uint64_t frand_max = rand_max(&td->rwmix_state);
unsigned int v;
unsigned long r;
r = __rand(&td->rwmix_state);
- v = 1 + (int) (100.0 * (r / (FRAND_MAX + 1.0)));
+ v = 1 + (int) (100.0 * (r / (frand_max + 1.0)));
if (v <= td->o.rwmix[DDIR_READ])
return DDIR_READ;
enum fio_file_flags goodf,
enum fio_file_flags badf)
{
+ uint64_t frand_max = rand_max(&td->next_file_state);
struct fio_file *f;
int fno;
r = __rand(&td->next_file_state);
fno = (unsigned int) ((double) td->o.nr_files
- * (r / (FRAND_MAX + 1.0)));
+ * (r / (frand_max + 1.0)));
f = td->files[fno];
if (fio_file_done(f))
*/
static struct frand_state *get_buf_state(struct thread_data *td)
{
+ uint64_t frand_max;
unsigned int v;
unsigned long r;
return &td->buf_state;
}
+ frand_max = rand_max(&td->dedupe_state);
r = __rand(&td->dedupe_state);
- v = 1 + (int) (100.0 * (r / (FRAND_MAX + 1.0)));
+ v = 1 + (int) (100.0 * (r / (frand_max + 1.0)));
if (v <= td->o.dedupe_percentage)
return &td->buf_state_prev;
return 0;
r = __rand(&gs->r);
- vr = gs->stddev * (r / (FRAND_MAX + 1.0));
+ vr = gs->stddev * (r / (FRAND32_MAX + 1.0));
return vr - gs->stddev / 2;
}
unsigned int seed)
{
memset(gs, 0, sizeof(*gs));
- init_rand_seed(&gs->r, seed);
+ init_rand_seed(&gs->r, seed, 0);
gs->nranges = nranges;
if (dev != 0.0) {
int arch_random;
-static inline int __seed(unsigned int x, unsigned int m)
+static inline uint64_t __seed(uint64_t x, uint64_t m)
{
return (x < m) ? x + m : x;
}
-static void __init_rand(struct frand_state *state, unsigned int seed)
+static void __init_rand32(struct taus88_state *state, unsigned int seed)
{
int cranks = 6;
state->s3 = __seed(LCG(state->s2, seed), 15);
while (cranks--)
- __rand(state);
+ __rand32(state);
}
-void init_rand(struct frand_state *state)
+static void __init_rand64(struct taus258_state *state, uint64_t seed)
{
- __init_rand(state, 1);
+ int cranks = 6;
+
+#define LCG64(x, seed) ((x) * 6906969069ULL ^ (seed))
+
+ state->s1 = __seed(LCG64((2^31) + (2^17) + (2^7), seed), 1);
+ state->s2 = __seed(LCG64(state->s1, seed), 7);
+ state->s3 = __seed(LCG64(state->s2, seed), 15);
+ state->s4 = __seed(LCG64(state->s3, seed), 33);
+ state->s5 = __seed(LCG64(state->s4, seed), 49);
+
+ while (cranks--)
+ __rand64(state);
}
-void init_rand_seed(struct frand_state *state, unsigned int seed)
+void init_rand(struct frand_state *state, int use64)
{
- __init_rand(state, seed);
+ state->use64 = use64;
+
+ if (!use64)
+ __init_rand32(&state->state32, 1);
+ else
+ __init_rand64(&state->state64, 1);
+}
+
+void init_rand_seed(struct frand_state *state, unsigned int seed, int use64)
+{
+ state->use64 = use64;
+
+ if (!use64)
+ __init_rand32(&state->state32, seed);
+ else
+ __init_rand64(&state->state64, seed);
}
void __fill_random_buf(void *buf, unsigned int len, unsigned long seed)
#ifndef FIO_RAND_H
#define FIO_RAND_H
+#include <inttypes.h>
#include "../arch/arch.h"
-#define FRAND_MAX (-1U)
+#define FRAND32_MAX (-1U)
+#define FRAND64_MAX (-1ULL)
-struct frand_state {
+struct taus88_state {
unsigned int s1, s2, s3;
};
-static inline void frand_copy(struct frand_state *dst,
- struct frand_state *src)
+struct taus258_state {
+ uint64_t s1, s2, s3, s4, s5;
+};
+
+struct frand_state {
+ unsigned int use64;
+ union {
+ struct taus88_state state32;
+ struct taus258_state state64;
+ };
+};
+
+struct frand64_state {
+ uint64_t s1, s2, s3, s4, s5;
+};
+
+static inline uint64_t rand_max(struct frand_state *state)
+{
+ if (state->use64)
+ return FRAND64_MAX;
+ else
+ return FRAND32_MAX;
+}
+
+static inline void __frand32_copy(struct taus88_state *dst,
+ struct taus88_state *src)
+{
+ dst->s1 = src->s1;
+ dst->s2 = src->s2;
+ dst->s3 = src->s3;
+}
+
+static inline void __frand64_copy(struct taus258_state *dst,
+ struct taus258_state *src)
{
dst->s1 = src->s1;
dst->s2 = src->s2;
dst->s3 = src->s3;
+ dst->s4 = src->s4;
+ dst->s5 = src->s5;
}
-static inline unsigned int __rand(struct frand_state *state)
+static inline void frand_copy(struct frand_state *dst, struct frand_state *src)
+{
+ if (src->use64)
+ __frand64_copy(&dst->state64, &src->state64);
+ else
+ __frand32_copy(&dst->state32, &src->state32);
+
+ dst->use64 = src->use64;
+}
+
+static inline unsigned int __rand32(struct taus88_state *state)
{
#define TAUSWORTHE(s,a,b,c,d) ((s&c)<<d) ^ (((s <<a) ^ s)>>b)
return (state->s1 ^ state->s2 ^ state->s3);
}
-extern void init_rand(struct frand_state *);
-extern void init_rand_seed(struct frand_state *, unsigned int seed);
+static inline uint64_t __rand64(struct taus258_state *state)
+{
+ uint64_t xval;
+
+ xval = ((state->s1 << 1) ^ state->s1) >> 53;
+ state->s1 = ((state->s1 & 18446744073709551614ULL) << 10) ^ xval;
+
+ xval = ((state->s2 << 24) ^ state->s2) >> 50;
+ state->s2 = ((state->s2 & 18446744073709551104ULL) << 5) ^ xval;
+
+ xval = ((state->s3 << 3) ^ state->s3) >> 23;
+ state->s3 = ((state->s3 & 18446744073709547520ULL) << 29) ^ xval;
+
+ xval = ((state->s4 << 5) ^ state->s4) >> 24;
+ state->s4 = ((state->s4 & 18446744073709420544ULL) << 23) ^ xval;
+
+ xval = ((state->s5 << 3) ^ state->s5) >> 33;
+ state->s5 = ((state->s5 & 18446744073701163008ULL) << 8) ^ xval;
+
+ return (state->s1 ^ state->s2 ^ state->s3 ^ state->s4 ^ state->s5);
+}
+
+static inline uint64_t __rand(struct frand_state *state)
+{
+ if (state->use64)
+ return __rand64(&state->state64);
+ else
+ return __rand32(&state->state32);
+}
+
+extern void init_rand(struct frand_state *, int);
+extern void init_rand_seed(struct frand_state *, unsigned int seed, int);
extern void __fill_random_buf(void *buf, unsigned int len, unsigned long seed);
extern unsigned long fill_random_buf(struct frand_state *, void *buf, unsigned int len);
extern void __fill_random_buf_percentage(unsigned long, void *, unsigned int, unsigned int, unsigned int, char *, unsigned int);
memset(zs, 0, sizeof(*zs));
zs->nranges = nranges;
- init_rand_seed(&zs->rand, seed);
+ init_rand_seed(&zs->rand, seed, 0);
zs->rand_off = __rand(&zs->rand);
}
alpha = 1.0 / (1.0 - zs->theta);
eta = (1.0 - pow(2.0 / n, 1.0 - zs->theta)) / (1.0 - zs->zeta2 / zs->zetan);
- rand_uni = (double) __rand(&zs->rand) / (double) FRAND_MAX;
+ rand_uni = (double) __rand(&zs->rand) / (double) FRAND32_MAX;
rand_z = rand_uni * zs->zetan;
if (rand_z < 1.0)
unsigned long long pareto_next(struct zipf_state *zs)
{
- double rand = (double) __rand(&zs->rand) / (double) FRAND_MAX;
+ double rand = (double) __rand(&zs->rand) / (double) FRAND32_MAX;
unsigned long long n = zs->nranges - 1;
return (__hash_u64(n * pow(rand, zs->pareto_pow)) + zs->rand_off) % zs->nranges;
.oval = FIO_RAND_GEN_LFSR,
.help = "Variable length LFSR",
},
+ {
+ .ival = "tausworthe64",
+ .oval = FIO_RAND_GEN_TAUSWORTHE64,
+ .help = "64-bit Tausworthe variant",
+ },
},
.category = FIO_OPT_C_IO,
.group = FIO_OPT_G_RANDOM,
}
int fio_server_get_verify_state(const char *name, int threadnumber,
- void **datap)
+ void **datap, int *version)
{
struct thread_io_list *s;
struct cmd_sendfile out;
* the header, and the thread_io_list checksum
*/
s = rep->data + sizeof(struct verify_state_hdr);
- if (verify_state_hdr(rep->data, s))
+ if (verify_state_hdr(rep->data, s, version))
goto fail;
/*
extern void fio_server_send_gs(struct group_run_stats *);
extern void fio_server_send_du(void);
extern void fio_server_idle_loop(void);
-extern int fio_server_get_verify_state(const char *, int, void **);
+extern int fio_server_get_verify_state(const char *, int, void **, int *);
extern int fio_recv_data(int sk, void *p, unsigned int len);
extern int fio_send_data(int sk, const void *p, unsigned int len);
int io_u_should_trim(struct thread_data *td, struct io_u *io_u)
{
unsigned long long val;
+ uint64_t frand_max;
unsigned long r;
if (!td->o.trim_percentage)
return 0;
+ frand_max = rand_max(&td->trim_state);
r = __rand(&td->trim_state);
- val = (FRAND_MAX / 100ULL);
+ val = (frand_max / 100ULL);
val *= (unsigned long long) td->o.trim_percentage;
return r <= val;
s->depth = cpu_to_le64((uint64_t) td->o.iodepth);
s->numberio = cpu_to_le64((uint64_t) td->io_issues[DDIR_WRITE]);
s->index = cpu_to_le64((uint64_t) i);
- s->rand.s[0] = cpu_to_le32(td->random_state.s1);
- s->rand.s[1] = cpu_to_le32(td->random_state.s2);
- s->rand.s[2] = cpu_to_le32(td->random_state.s3);
- s->rand.s[3] = 0;
+ if (td->random_state.use64) {
+ s->rand.state64.s[0] = cpu_to_le64(td->random_state.state64.s1);
+ s->rand.state64.s[1] = cpu_to_le64(td->random_state.state64.s2);
+ s->rand.state64.s[2] = cpu_to_le64(td->random_state.state64.s3);
+ s->rand.state64.s[3] = cpu_to_le64(td->random_state.state64.s4);
+ s->rand.state64.s[4] = cpu_to_le64(td->random_state.state64.s5);
+ s->rand.state64.s[5] = 0;
+ s->rand.use64 = cpu_to_le64((uint64_t)1);
+ } else {
+ s->rand.state32.s[0] = cpu_to_le32(td->random_state.state32.s1);
+ s->rand.state32.s[1] = cpu_to_le32(td->random_state.state32.s2);
+ s->rand.state32.s[2] = cpu_to_le32(td->random_state.state32.s3);
+ s->rand.state32.s[3] = 0;
+ s->rand.use64 = 0;
+ }
s->name[sizeof(s->name) - 1] = '\0';
strncpy((char *) s->name, td->o.name, sizeof(s->name) - 1);
next = io_list_next(s);
free(td->vstate);
}
-void verify_convert_assign_state(struct thread_data *td,
- struct thread_io_list *s)
+static struct thread_io_list *convert_v1_list(struct thread_io_list_v1 *s)
{
+ struct thread_io_list *til;
int i;
- s->no_comps = le64_to_cpu(s->no_comps);
- s->depth = le64_to_cpu(s->depth);
- s->numberio = le64_to_cpu(s->numberio);
+ til = malloc(__thread_io_list_sz(s->no_comps));
+ til->no_comps = s->no_comps;
+ til->depth = s->depth;
+ til->numberio = s->numberio;
+ til->index = s->index;
+ memcpy(til->name, s->name, sizeof(til->name));
+
+ til->rand.use64 = 0;
for (i = 0; i < 4; i++)
- s->rand.s[i] = le32_to_cpu(s->rand.s[i]);
+ til->rand.state32.s[i] = s->rand.s[i];
+
for (i = 0; i < s->no_comps; i++)
- s->offsets[i] = le64_to_cpu(s->offsets[i]);
+ til->offsets[i] = s->offsets[i];
+
+ return til;
+}
+
+void verify_convert_assign_state(struct thread_data *td, void *p, int version)
+{
+ struct thread_io_list *til;
+ int i;
+
+ if (version == 1) {
+ struct thread_io_list_v1 *s = p;
+
+ s->no_comps = le64_to_cpu(s->no_comps);
+ s->depth = le64_to_cpu(s->depth);
+ s->numberio = le64_to_cpu(s->numberio);
+ for (i = 0; i < 4; i++)
+ s->rand.s[i] = le32_to_cpu(s->rand.s[i]);
+ for (i = 0; i < s->no_comps; i++)
+ s->offsets[i] = le64_to_cpu(s->offsets[i]);
+
+ til = convert_v1_list(s);
+ free(s);
+ } else {
+ struct thread_io_list *s = p;
+
+ s->no_comps = le64_to_cpu(s->no_comps);
+ s->depth = le64_to_cpu(s->depth);
+ s->numberio = le64_to_cpu(s->numberio);
+ s->rand.use64 = le64_to_cpu(s->rand.use64);
+
+ if (s->rand.use64) {
+ for (i = 0; i < 6; i++)
+ s->rand.state64.s[i] = le64_to_cpu(s->rand.state64.s[i]);
+ } else {
+ for (i = 0; i < 4; i++)
+ s->rand.state32.s[i] = le32_to_cpu(s->rand.state32.s[i]);
+ }
+ for (i = 0; i < s->no_comps; i++)
+ s->offsets[i] = le64_to_cpu(s->offsets[i]);
+
+ til = p;
+ }
- td->vstate = s;
+ td->vstate = til;
}
-int verify_state_hdr(struct verify_state_hdr *hdr, struct thread_io_list *s)
+int verify_state_hdr(struct verify_state_hdr *hdr, struct thread_io_list *s,
+ int *version)
{
uint64_t crc;
hdr->size = le64_to_cpu(hdr->size);
hdr->crc = le64_to_cpu(hdr->crc);
- if (hdr->version != VSTATE_HDR_VERSION)
+ if (hdr->version != VSTATE_HDR_VERSION ||
+ hdr->version != VSTATE_HDR_VERSION_V1)
return 1;
crc = fio_crc32c((void *)s, hdr->size);
if (crc != hdr->crc)
return 1;
+ *version = hdr->version;
return 0;
}
int verify_load_state(struct thread_data *td, const char *prefix)
{
- struct thread_io_list *s = NULL;
struct verify_state_hdr hdr;
+ void *s = NULL;
uint64_t crc;
ssize_t ret;
int fd;
hdr.size = le64_to_cpu(hdr.size);
hdr.crc = le64_to_cpu(hdr.crc);
- if (hdr.version != VSTATE_HDR_VERSION) {
+ if (hdr.version != VSTATE_HDR_VERSION &&
+ hdr.version != VSTATE_HDR_VERSION_V1) {
log_err("fio: bad version in verify state header\n");
goto err;
}
goto err;
}
- crc = fio_crc32c((void *)s, hdr.size);
+ crc = fio_crc32c(s, hdr.size);
if (crc != hdr.crc) {
log_err("fio: verify state is corrupt\n");
goto err;
close(fd);
- verify_convert_assign_state(td, s);
+ verify_convert_assign_state(td, s, hdr.version);
return 0;
err:
if (s)
extern int verify_async_init(struct thread_data *);
extern void verify_async_exit(struct thread_data *);
-struct thread_rand_state {
+struct thread_rand32_state {
uint32_t s[4];
};
+struct thread_rand64_state {
+ uint64_t s[6];
+};
+
+struct thread_rand_state {
+ uint64_t use64;
+ union {
+ struct thread_rand32_state state32;
+ struct thread_rand64_state state64;
+ };
+};
+
/*
* For dumping current write state
*/
uint64_t offsets[0];
};
+struct thread_io_list_v1 {
+ uint64_t no_comps;
+ uint64_t depth;
+ uint64_t numberio;
+ uint64_t index;
+ struct thread_rand32_state rand;
+ uint8_t name[64];
+ uint64_t offsets[0];
+};
+
struct all_io_list {
uint64_t threads;
struct thread_io_list state[0];
};
-#define VSTATE_HDR_VERSION 0x01
+#define VSTATE_HDR_VERSION_V1 0x01
+#define VSTATE_HDR_VERSION 0x02
struct verify_state_hdr {
uint64_t version;
extern int verify_load_state(struct thread_data *, const char *);
extern void verify_free_state(struct thread_data *);
extern int verify_state_should_stop(struct thread_data *, struct io_u *);
-extern void verify_convert_assign_state(struct thread_data *, struct thread_io_list *);
-extern int verify_state_hdr(struct verify_state_hdr *, struct thread_io_list *);
+extern void verify_convert_assign_state(struct thread_data *, void *, int);
+extern int verify_state_hdr(struct verify_state_hdr *, struct thread_io_list *,
+ int *);
+
+static inline size_t __thread_io_list_sz(uint64_t depth)
+{
+ return sizeof(struct thread_io_list) + depth * sizeof(uint64_t);
+}
static inline size_t thread_io_list_sz(struct thread_io_list *s)
{
- return sizeof(*s) + le64_to_cpu(s->depth) * sizeof(uint64_t);
+ return __thread_io_list_sz(le64_to_cpu(s->depth));
}
static inline struct thread_io_list *io_list_next(struct thread_io_list *s)