#include "server.h"
static pthread_t disk_util_thread;
+static struct fio_mutex *disk_thread_mutex;
static struct fio_mutex *startup_mutex;
static struct fio_mutex *writeout_mutex;
static struct flist_head *cgroup_list;
static int exit_value;
static volatile int fio_abort;
-struct io_log *agg_io_log[2];
+struct io_log *agg_io_log[DDIR_RWDIR_CNT];
int groupid = 0;
unsigned int thread_number = 0;
{
int ret = 0;
- if (bytes_done[0])
- ret |= __check_min_rate(td, now, 0);
- if (bytes_done[1])
- ret |= __check_min_rate(td, now, 1);
+ if (bytes_done[DDIR_READ])
+ ret |= __check_min_rate(td, now, DDIR_READ);
+ if (bytes_done[DDIR_WRITE])
+ ret |= __check_min_rate(td, now, DDIR_WRITE);
+ if (bytes_done[DDIR_TRIM])
+ ret |= __check_min_rate(td, now, DDIR_TRIM);
return ret;
}
unsigned long long bytes;
if (td_rw(td))
- bytes = td->this_io_bytes[0] + td->this_io_bytes[1];
+ bytes = td->this_io_bytes[DDIR_READ] + td->this_io_bytes[DDIR_WRITE];
else if (td_write(td))
- bytes = td->this_io_bytes[1];
+ bytes = td->this_io_bytes[DDIR_WRITE];
+ else if (td_read(td))
+ bytes = td->this_io_bytes[DDIR_READ];
else
- bytes = td->this_io_bytes[0];
+ bytes = td->this_io_bytes[DDIR_TRIM];
return bytes >= td->o.size;
}
(!flist_empty(&td->trim_list)) || !io_bytes_exceeded(td) ||
td->o.time_based) {
struct timeval comp_time;
- unsigned long bytes_done[2] = { 0, 0 };
+ unsigned long bytes_done[DDIR_RWDIR_CNT] = { 0, 0, 0 };
int min_evts = 0;
struct io_u *io_u;
int ret2, full;
requeue_io_u(td, &io_u);
} else {
sync_done:
- if (__should_check_rate(td, 0) ||
- __should_check_rate(td, 1))
+ if (__should_check_rate(td, DDIR_READ) ||
+ __should_check_rate(td, DDIR_WRITE) ||
+ __should_check_rate(td, DDIR_TRIM))
fio_gettime(&comp_time, NULL);
ret = io_u_sync_complete(td, io_u, bytes_done);
if (full && !min_evts)
min_evts = 1;
- if (__should_check_rate(td, 0) ||
- __should_check_rate(td, 1))
+ if (__should_check_rate(td, DDIR_READ) ||
+ __should_check_rate(td, DDIR_WRITE) ||
+ __should_check_rate(td, DDIR_TRIM))
fio_gettime(&comp_time, NULL);
do {
if (ret < 0)
break;
- if (!(bytes_done[0] + bytes_done[1]))
+ if (!(bytes_done[DDIR_READ] + bytes_done[DDIR_WRITE]
+ + bytes_done[DDIR_TRIM]))
continue;
if (!in_ramp_time(td) && should_check_rate(td, bytes_done)) {
if (td->o.thinktime) {
unsigned long long b;
- b = td->io_blocks[0] + td->io_blocks[1];
+ b = td->io_blocks[DDIR_READ] + td->io_blocks[DDIR_WRITE] +
+ td->io_blocks[DDIR_TRIM];
if (!(b % td->o.thinktime_blocks)) {
int left;
/*
* stop job if we failed doing any IO
*/
- if ((td->this_io_bytes[0] + td->this_io_bytes[1]) == 0)
+ if ((td->this_io_bytes[DDIR_READ] + td->this_io_bytes[DDIR_WRITE] +
+ td->this_io_bytes[DDIR_TRIM]) == 0)
td->done = 1;
}
max_units = td->o.iodepth;
max_bs = max(td->o.max_bs[DDIR_READ], td->o.max_bs[DDIR_WRITE]);
+ max_bs = max(td->o.max_bs[DDIR_TRIM], max_bs);
min_write = td->o.min_bs[DDIR_WRITE];
td->orig_buffer_size = (unsigned long long) max_bs
* (unsigned long long) max_units;
return 1;
}
- io_done = td->io_bytes[DDIR_READ] + td->io_bytes[DDIR_WRITE]
- + td->io_skip_bytes;
+ io_done = td->io_bytes[DDIR_READ] + td->io_bytes[DDIR_WRITE] +
+ td->io_bytes[DDIR_TRIM] + td->io_skip_bytes;
if (io_done < td->o.size)
return 1;
}
}
- if (td->o.cgroup_weight && cgroup_setup(td, cgroup_list, &cgroup_mnt))
+ if (td->o.cgroup && cgroup_setup(td, cgroup_list, &cgroup_mnt))
goto err;
errno = 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[0], &td->bw_sample_time,
+ if (td->o.ratemin[DDIR_READ] || td->o.ratemin[DDIR_WRITE] ||
+ td->o.ratemin[DDIR_TRIM]) {
+ memcpy(&td->lastrate[DDIR_READ], &td->bw_sample_time,
sizeof(td->bw_sample_time));
- memcpy(&td->lastrate[1], &td->bw_sample_time,
+ memcpy(&td->lastrate[DDIR_WRITE], &td->bw_sample_time,
+ sizeof(td->bw_sample_time));
+ memcpy(&td->lastrate[DDIR_TRIM], &td->bw_sample_time,
sizeof(td->bw_sample_time));
}
elapsed = utime_since_now(&td->start);
td->ts.runtime[DDIR_WRITE] += elapsed;
}
+ if (td_trim(td) && td->io_bytes[DDIR_TRIM]) {
+ elapsed = utime_since_now(&td->start);
+ td->ts.runtime[DDIR_TRIM] += elapsed;
+ }
if (td->error || td->terminate)
break;
}
update_rusage_stat(td);
- td->ts.runtime[0] = (td->ts.runtime[0] + 999) / 1000;
- td->ts.runtime[1] = (td->ts.runtime[1] + 999) / 1000;
+ td->ts.runtime[DDIR_READ] = (td->ts.runtime[DDIR_READ] + 999) / 1000;
+ td->ts.runtime[DDIR_WRITE] = (td->ts.runtime[DDIR_WRITE] + 999) / 1000;
+ td->ts.runtime[DDIR_TRIM] = (td->ts.runtime[DDIR_TRIM] + 999) / 1000;
td->ts.total_run_time = mtime_since_now(&td->epoch);
- td->ts.io_bytes[0] = td->io_bytes[0];
- td->ts.io_bytes[1] = td->io_bytes[1];
+ td->ts.io_bytes[DDIR_READ] = td->io_bytes[DDIR_READ];
+ td->ts.io_bytes[DDIR_WRITE] = td->io_bytes[DDIR_WRITE];
+ td->ts.io_bytes[DDIR_TRIM] = td->io_bytes[DDIR_TRIM];
fio_mutex_down(writeout_mutex);
if (td->bw_log) {
continue;
reaped:
(*nr_running)--;
- (*m_rate) -= (td->o.ratemin[0] + td->o.ratemin[1]);
- (*t_rate) -= (td->o.rate[0] + td->o.rate[1]);
+ (*m_rate) -= (td->o.ratemin[DDIR_READ] + td->o.ratemin[DDIR_WRITE] +
+ td->o.ratemin[DDIR_TRIM]);
+ (*t_rate) -= (td->o.rate[DDIR_READ] + td->o.rate[DDIR_WRITE] +
+ td->o.rate[DDIR_TRIM]);
if (!td->pid)
pending--;
td_set_runstate(td, TD_RUNNING);
nr_running++;
nr_started--;
- m_rate += td->o.ratemin[0] + td->o.ratemin[1];
- t_rate += td->o.rate[0] + td->o.rate[1];
+ m_rate += td->o.ratemin[DDIR_READ] +
+ td->o.ratemin[DDIR_WRITE] + td->o.ratemin[DDIR_TRIM];
+ t_rate += td->o.rate[DDIR_READ] +
+ td->o.rate[DDIR_WRITE] + td->o.rate[DDIR_TRIM];
todo--;
fio_mutex_up(td->mutex);
}
fio_unpin_memory();
}
+void wait_for_disk_thread_exit(void)
+{
+ fio_mutex_down(disk_thread_mutex);
+}
+
static void *disk_thread_main(void *data)
{
+ int ret = 0;
+
fio_mutex_up(startup_mutex);
- while (threads) {
+ while (threads && !ret) {
usleep(DISK_UTIL_MSEC * 1000);
if (!threads)
break;
- update_io_ticks();
+ ret = update_io_ticks();
if (!is_backend)
print_thread_status();
}
+ fio_mutex_up(disk_thread_mutex);
return NULL;
}
{
int ret;
+ setup_disk_util();
+
+ disk_thread_mutex = fio_mutex_init(FIO_MUTEX_LOCKED);
+
ret = pthread_create(&disk_util_thread, NULL, disk_thread_main, NULL);
if (ret) {
+ fio_mutex_remove(disk_thread_mutex);
log_err("Can't create disk util thread: %s\n", strerror(ret));
return 1;
}
ret = pthread_detach(disk_util_thread);
if (ret) {
+ fio_mutex_remove(disk_thread_mutex);
log_err("Can't detatch disk util thread: %s\n", strerror(ret));
return 1;
}
if (write_bw_log) {
setup_log(&agg_io_log[DDIR_READ], 0);
setup_log(&agg_io_log[DDIR_WRITE], 0);
+ setup_log(&agg_io_log[DDIR_TRIM], 0);
}
- startup_mutex = fio_mutex_init(0);
+ startup_mutex = fio_mutex_init(FIO_MUTEX_LOCKED);
if (startup_mutex == NULL)
return 1;
- writeout_mutex = fio_mutex_init(1);
+ writeout_mutex = fio_mutex_init(FIO_MUTEX_UNLOCKED);
if (writeout_mutex == NULL)
return 1;
__finish_log(agg_io_log[DDIR_READ], "agg-read_bw.log");
__finish_log(agg_io_log[DDIR_WRITE],
"agg-write_bw.log");
+ __finish_log(agg_io_log[DDIR_TRIM],
+ "agg-write_bw.log");
}
}
fio_mutex_remove(startup_mutex);
fio_mutex_remove(writeout_mutex);
+ fio_mutex_remove(disk_thread_mutex);
return exit_value;
}