* Copyright (C) 2005 Jens Axboe <axboe@suse.de>
* Copyright (C) 2006 Jens Axboe <axboe@kernel.dk>
*
+ * The license below covers all files distributed with fio unless otherwise
+ * noted in the file itself.
+ *
* This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
int thread_number = 0;
int shm_id = 0;
int temp_stall_ts;
-char *fio_inst_prefix = _INST_PREFIX;
+const char *fio_inst_prefix = _INST_PREFIX;
static volatile int startup_sem;
ret = td_io_queue(td, io_u);
if (ret) {
+ td_verror(td, io_u->error);
put_io_u(td, io_u);
- td_verror(td, ret);
return 1;
}
ret = td_io_getevents(td, 1, td->cur_depth, NULL);
if (ret < 0) {
- td_verror(td, -ret);
+ td_verror(td, ret);
return 1;
}
ret = td_io_queue(td, io_u);
if (ret) {
+ td_verror(td, io_u->error);
put_io_u(td, io_u);
- td_verror(td, ret);
break;
}
ret = td_io_queue(td, io_u);
if (ret) {
+ td_verror(td, io_u->error);
put_io_u(td, io_u);
- td_verror(td, ret);
break;
}
gettimeofday(&e, NULL);
usec = utime_since(&s, &e);
- rate_throttle(td, usec, icd.bytes_done[td->ddir]);
+ rate_throttle(td, usec, icd.bytes_done[td->ddir], td->ddir);
if (check_min_rate(td, &e)) {
- if (rate_quit)
+ if (exitall_on_terminate)
terminate_threads(td->groupid);
td_verror(td, ENOMEM);
break;
usec_sleep(td, td->thinktime);
}
- if (!ret) {
+ if (!td->error) {
if (td->cur_depth)
cleanup_pending_aio(td);
free_io_mem(td);
}
+/*
+ * "randomly" fill the buffer contents
+ */
+static void fill_rand_buf(struct io_u *io_u, int max_bs)
+{
+ int *ptr = io_u->buf;
+
+ while ((void *) ptr - io_u->buf < max_bs) {
+ *ptr = rand() * 0x9e370001;
+ ptr++;
+ }
+}
+
static int init_io_u(struct thread_data *td)
{
struct io_u *io_u;
+ unsigned int max_bs;
int i, max_units;
char *p;
else
max_units = td->iodepth;
- td->orig_buffer_size = td->max_bs * max_units + MASK;
+ max_bs = max(td->max_bs[DDIR_READ], td->max_bs[DDIR_WRITE]);
+ td->orig_buffer_size = max_bs * max_units + MASK;
if (allocate_io_mem(td))
return 1;
memset(io_u, 0, sizeof(*io_u));
INIT_LIST_HEAD(&io_u->list);
- io_u->buf = p + td->max_bs * i;
+ io_u->buf = p + max_bs * i;
+ if (td_write(td) || td_rw(td))
+ fill_rand_buf(io_u, max_bs);
+
io_u->index = i;
list_add(&io_u->list, &td->io_u_freelist);
}
FILE *f;
int ret;
+ if (td->io_ops->flags & FIO_CPUIO)
+ return 0;
+
sprintf(tmp, "%s/queue/scheduler", td->sysfs_root);
f = fopen(tmp, "r+");
finish_log(td, td->slat_log, "slat");
if (td->clat_log)
finish_log(td, td->clat_log, "clat");
- if (td->write_iolog)
+ if (td->write_iolog_file)
write_iolog_close(td);
if (td->exec_postrun)
system(td->exec_postrun);
static void reap_threads(int *nr_running, int *t_rate, int *m_rate)
{
struct thread_data *td;
- int i, cputhreads;
+ int i, cputhreads, pending;
/*
* reap exited threads (TD_EXITED -> TD_REAPED)
*/
- cputhreads = 0;
+ pending = cputhreads = 0;
for_each_td(td, i) {
/*
* ->io_ops is NULL for a thread that has closed its
if (td->io_ops && td->io_ops->flags & FIO_CPUIO)
cputhreads++;
- if (td->runstate != TD_EXITED)
+ if (td->runstate != TD_EXITED) {
+ if (td->runstate < TD_RUNNING)
+ pending++;
+
continue;
+ }
td_set_runstate(td, TD_REAPED);
(*t_rate) -= td->rate;
}
- if (*nr_running == cputhreads)
+ if (*nr_running == cputhreads && !pending)
terminate_threads(TERMINATE_ALL);
}