X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=io_u.c;h=9cb68af4691025ff83f50c9d562292d94bfefccc;hp=5331f8efee4d052e0aa555f80839fd9f6e66c191;hb=afe24a5a66350a3828e8965f7b189fc95b8bbf6c;hpb=ac71feb12023e3fadb793cc30636af1c982ce106 diff --git a/io_u.c b/io_u.c index 5331f8ef..9cb68af4 100644 --- a/io_u.c +++ b/io_u.c @@ -169,6 +169,24 @@ static unsigned int get_next_buflen(struct thread_data *td, struct io_u *io_u) return buflen; } +static void set_rwmix_bytes(struct thread_data *td) +{ + unsigned long long rbytes; + unsigned int diff; + + /* + * we do time or byte based switch. this is needed because + * buffered writes may issue a lot quicker than they complete, + * whereas reads do not. + */ + rbytes = td->io_bytes[td->rwmix_ddir] - td->rwmix_bytes; + diff = td->o.rwmixread; + if (td->rwmix_ddir == DDIR_WRITE) + diff = 100 - diff; + + td->rwmix_bytes = td->io_bytes[td->rwmix_ddir] + (rbytes * (100 - diff)) / diff; +} + /* * Return the data direction for the next io_u. If the job is a * mixed read/write workload, check the rwmix cycle and switch if @@ -179,23 +197,34 @@ static enum fio_ddir get_rw_ddir(struct thread_data *td) if (td_rw(td)) { struct timeval now; unsigned long elapsed; + unsigned int cycle; fio_gettime(&now, NULL); elapsed = mtime_since_now(&td->rwmix_switch); + cycle = td->o.rwmixcycle; + if (!td->rwmix_bytes) + cycle /= 10; + /* * Check if it's time to seed a new data direction. */ - if (elapsed >= td->o.rwmixcycle) { + if (elapsed >= cycle && + td->io_bytes[td->rwmix_ddir] >= td->rwmix_bytes) { unsigned int v; long r; r = os_random_long(&td->rwmix_state); v = 1 + (int) (100.0 * (r / (RAND_MAX + 1.0))); - if (v < td->o.rwmixread) + if (v < td->o.rwmixread) { + if (td->rwmix_ddir != DDIR_READ) + set_rwmix_bytes(td); td->rwmix_ddir = DDIR_READ; - else + } else { + if (td->rwmix_ddir != DDIR_WRITE) + set_rwmix_bytes(td); td->rwmix_ddir = DDIR_WRITE; + } memcpy(&td->rwmix_switch, &now, sizeof(now)); } return td->rwmix_ddir;