(char *) (((unsigned long) (buf) + page_mask) & ~page_mask)
int groupid = 0;
-int thread_number = 0;
-int nr_process = 0;
-int nr_thread = 0;
+unsigned int thread_number = 0;
+unsigned int nr_process = 0;
+unsigned int nr_thread = 0;
int shm_id = 0;
int temp_stall_ts;
unsigned long done_secs = 0;
+/*
+ * Just expose an empty list, if the OS does not support disk util stats
+ */
+#ifndef FIO_HAVE_DISK_UTIL
+FLIST_HEAD(disk_list);
+#endif
+
static struct fio_mutex *startup_mutex;
static struct fio_mutex *writeout_mutex;
static volatile int fio_abort;
#define JOB_START_TIMEOUT (5 * 1000)
+static const char *fio_os_strings[os_nr] = {
+ "Invalid",
+ "Linux",
+ "AIX",
+ "FreeBSD",
+ "HP-UX",
+ "OSX",
+ "NetBSD",
+ "Solaris",
+ "Windows"
+};
+
+static const char *fio_arch_strings[arch_nr] = {
+ "Invalid",
+ "x86-64",
+ "x86",
+ "ppc",
+ "ia64",
+ "s390",
+ "alpha",
+ "sparc",
+ "sparc64",
+ "arm",
+ "sh",
+ "hppa",
+ "generic"
+};
+
+const char *fio_get_os_string(int nr)
+{
+ if (nr < os_nr)
+ return fio_os_strings[nr];
+
+ return NULL;
+}
+
+const char *fio_get_arch_string(int nr)
+{
+ if (nr < arch_nr)
+ return fio_arch_strings[nr];
+
+ return NULL;
+}
+
void td_set_runstate(struct thread_data *td, int runstate)
{
if (td->runstate == runstate)
static void sig_int(int sig)
{
if (threads) {
- log_info("\nfio: terminating on signal %d\n", sig);
- exit_backend = 1;
- fflush(stdout);
- exit_value = 128;
+ if (is_backend)
+ fio_server_got_signal(sig);
+ else {
+ log_info("\nfio: terminating on signal %d\n", sig);
+ fflush(stdout);
+ exit_value = 128;
+ }
+
fio_terminate_threads(TERMINATE_ALL);
}
}
break;
update_io_ticks();
- if (is_backend)
- fio_server_send_status();
- else
+ if (!is_backend)
print_thread_status();
}
__update_tv_cache(td);
}
-static int break_on_this_error(struct thread_data *td, int *retptr)
+static int break_on_this_error(struct thread_data *td, enum fio_ddir ddir,
+ int *retptr)
{
int ret = *retptr;
if (ret < 0 || td->error) {
int err;
- if (!td->o.continue_on_error)
- return 1;
-
if (ret < 0)
err = -ret;
else
err = td->error;
+ if (!(td->o.continue_on_error & td_error_type(ddir, err)))
+ return 1;
+
if (td_non_fatal_error(err)) {
/*
* Continue with the I/Os in case of
break;
}
- if (break_on_this_error(td, &ret))
+ if (break_on_this_error(td, io_u->ddir, &ret))
break;
/*
int min_evts = 0;
struct io_u *io_u;
int ret2, full;
+ enum fio_ddir ddir;
if (td->terminate)
break;
if (!io_u)
break;
+ ddir = io_u->ddir;
+
/*
* Add verification end_io handler, if asked to verify
* a previously written file.
break;
}
- if (break_on_this_error(td, &ret))
+ if (break_on_this_error(td, ddir, &ret))
break;
/*
}
if (td->trim_entries)
- printf("trim entries %ld\n", td->trim_entries);
+ log_err("fio: %d trim entries leaked?\n", td->trim_entries);
if (td->o.fill_device && td->error == ENOSPC) {
td->error = 0;
dprint(FD_MEM, "io_u alloc %p, index %u\n", io_u, i);
if (!(td->io_ops->flags & FIO_NOIO)) {
- io_u->buf = p + max_bs * i;
+ io_u->buf = p;
dprint(FD_MEM, "io_u %p, mem %p\n", io_u, io_u->buf);
if (td_write(td))
io_u->index = i;
io_u->flags = IO_U_F_FREE;
flist_add(&io_u->list, &td->io_u_freelist);
+ p += max_bs;
}
return 0;
memcpy(&td->iops_sample_time, &td->start, sizeof(td->start));
memcpy(&td->tv_cache, &td->start, sizeof(td->start));
- if (td->o.ratemin[0] || td->o.ratemin[1])
- memcpy(&td->lastrate, &td->bw_sample_time,
- sizeof(td->lastrate));
+ if (td->o.ratemin[0] || td->o.ratemin[1]) {
+ memcpy(&td->lastrate[0], &td->bw_sample_time,
+ sizeof(td->bw_sample_time));
+ memcpy(&td->lastrate[1], &td->bw_sample_time,
+ sizeof(td->bw_sample_time));
+ }
if (clear_state)
clear_io_state(td);
if (td->o.write_iolog_file)
write_iolog_close(td);
- options_mem_free(td);
td_set_runstate(td, TD_EXITED);
return (void *) (unsigned long) td->error;
}
/*
* Run over the job map and reap the threads that have exited, if any.
*/
-static void reap_threads(int *nr_running, int *t_rate, int *m_rate)
+static void reap_threads(unsigned int *nr_running, unsigned int *t_rate,
+ unsigned int *m_rate)
{
struct thread_data *td;
- int i, cputhreads, realthreads, pending, status, ret;
+ unsigned int cputhreads, realthreads, pending;
+ int i, status, ret;
/*
* reap exited threads (TD_EXITED -> TD_REAPED)
{
struct thread_data *td;
unsigned long spent;
- int i, todo, nr_running, m_rate, t_rate, nr_started;
+ unsigned int i, todo, nr_running, m_rate, t_rate, nr_started;
if (fio_pin_memory())
return;
nr_thread > 1 ? "s" : "");
if (nr_process) {
if (nr_thread)
- printf(" and ");
+ log_info(" and ");
log_info("%d process%s", nr_process,
nr_process > 1 ? "es" : "");
}
reap_threads(&nr_running, &t_rate, &m_rate);
- if (todo)
- usleep(100000);
+ if (todo) {
+ if (is_backend)
+ fio_server_idle_loop();
+ else
+ usleep(100000);
+ }
}
while (nr_running) {
int exec_run(void)
{
+ struct thread_data *td;
+ int i;
+
if (nr_clients)
return fio_handle_clients();
- if (exec_profile && load_profile(exec_profile))
- return 1;
-
+ if (exec_profile) {
+ if (load_profile(exec_profile))
+ return 1;
+ free(exec_profile);
+ exec_profile = NULL;
+ }
if (!thread_number)
return 0;
if (write_bw_log) {
- setup_log(&agg_io_log[DDIR_READ]);
- setup_log(&agg_io_log[DDIR_WRITE]);
+ setup_log(&agg_io_log[DDIR_READ], 0);
+ setup_log(&agg_io_log[DDIR_WRITE], 0);
}
startup_mutex = fio_mutex_init(0);
}
}
+ for_each_td(td, i)
+ fio_options_free(td);
+
cgroup_kill(cgroup_list);
sfree(cgroup_list);
sfree(cgroup_mnt);