#include "lib/getrusage.h"
#include "idletime.h"
-static struct fio_mutex *stat_mutex;
+struct fio_mutex *stat_mutex;
void update_rusage_stat(struct thread_data *td)
{
void show_group_stats(struct group_run_stats *rs)
{
char *p1, *p2, *p3, *p4;
- const char *ddir_str[] = { " READ", " WRITE" , " TRIM"};
+ const char *str[] = { " READ", " WRITE" , " TRIM"};
int i;
log_info("\nRun status group %d (all jobs):\n", rs->groupid);
log_info("%s: io=%s, aggrb=%s/s, minb=%s/s, maxb=%s/s,"
" mint=%llumsec, maxt=%llumsec\n",
- rs->unified_rw_rep ? " MIXED" : ddir_str[i],
+ rs->unified_rw_rep ? " MIXED" : str[i],
p1, p2, p3, p4,
(unsigned long long) rs->min_run[i],
(unsigned long long) rs->max_run[i]);
static void show_ddir_status(struct group_run_stats *rs, struct thread_stat *ts,
int ddir)
{
- const char *ddir_str[] = { "read ", "write", "trim" };
+ const char *str[] = { "read ", "write", "trim" };
unsigned long min, max, runt;
unsigned long long bw, iops;
double mean, dev;
iops_p = num2str(iops, 6, 1, 0, 0);
log_info(" %s: io=%s, bw=%s/s, iops=%s, runt=%6llumsec\n",
- rs->unified_rw_rep ? "mixed" : ddir_str[ddir],
+ rs->unified_rw_rep ? "mixed" : str[ddir],
io_p, bw_p, iops_p,
(unsigned long long) ts->runtime[ddir]);
time_t time_p;
char time_buf[64];
- if (!(ts->io_bytes[DDIR_READ] + ts->io_bytes[DDIR_WRITE] +
- ts->io_bytes[DDIR_TRIM]) && !(ts->total_io_u[DDIR_READ] +
- ts->total_io_u[DDIR_WRITE] + ts->total_io_u[DDIR_TRIM]))
+ if (!ddir_rw_sum(ts->io_bytes) && !ddir_rw_sum(ts->total_io_u))
return;
time(&time_p);
io_u_dist[3], io_u_dist[4],
io_u_dist[5], io_u_dist[6]);
log_info(" issued : total=r=%llu/w=%llu/d=%llu,"
- " short=r=%llu/w=%llu/d=%llu\n",
+ " short=r=%llu/w=%llu/d=%llu,"
+ " drop=r=%llu/w=%llu/d=%llu\n",
(unsigned long long) ts->total_io_u[0],
(unsigned long long) ts->total_io_u[1],
(unsigned long long) ts->total_io_u[2],
(unsigned long long) ts->short_io_u[0],
(unsigned long long) ts->short_io_u[1],
- (unsigned long long) ts->short_io_u[2]);
+ (unsigned long long) ts->short_io_u[2],
+ (unsigned long long) ts->drop_io_u[0],
+ (unsigned long long) ts->drop_io_u[1],
+ (unsigned long long) ts->drop_io_u[2]);
if (ts->continue_on_error) {
log_info(" errors : total=%llu, first_error=%d/<%s>\n",
(unsigned long long)ts->total_err_count,
json_object_add_value_int(dir_object, "bw", bw);
json_object_add_value_int(dir_object, "iops", iops);
json_object_add_value_int(dir_object, "runtime", ts->runtime[ddir]);
+ json_object_add_value_int(dir_object, "total_ios", ts->total_io_u[ddir]);
+ json_object_add_value_int(dir_object, "short_ios", ts->short_io_u[ddir]);
+ json_object_add_value_int(dir_object, "drop_ios", ts->drop_io_u[ddir]);
if (!calc_lat(&ts->slat_stat[ddir], &min, &max, &mean, &dev)) {
min = max = 0;
dst->agg[i] += src->agg[i];
}
+ if (!dst->kb_base)
+ dst->kb_base = src->kb_base;
+ if (!dst->unit_base)
+ dst->unit_base = src->unit_base;
}
void sum_thread_stats(struct thread_stat *dst, struct thread_stat *src, int nr)
if (!dst->unified_rw_rep) {
dst->total_io_u[k] += src->total_io_u[k];
dst->short_io_u[k] += src->short_io_u[k];
+ dst->drop_io_u[k] += src->drop_io_u[k];
} else {
dst->total_io_u[0] += src->total_io_u[k];
dst->short_io_u[0] += src->short_io_u[k];
+ dst->drop_io_u[0] += src->drop_io_u[k];
}
}
ts->groupid = -1;
}
-static void __show_run_stats(void)
+void __show_run_stats(void)
{
struct group_run_stats *runstats, *rs;
struct thread_data *td;
fio_mutex_up(stat_mutex);
}
-static void *__show_running_run_stats(void fio_unused *arg)
+void __show_running_run_stats(void)
{
struct thread_data *td;
unsigned long long *rt;
struct timeval tv;
int i;
+ fio_mutex_down(stat_mutex);
+
rt = malloc(thread_number * sizeof(unsigned long long));
fio_gettime(&tv, NULL);
}
for_each_td(td, i) {
+ if (td->runstate >= TD_EXITED)
+ continue;
if (td->rusage_sem) {
td->update_rusage = 1;
fio_mutex_down(td->rusage_sem);
free(rt);
fio_mutex_up(stat_mutex);
- return NULL;
-}
-
-/*
- * Called from signal handler. It _should_ be safe to just run this inline
- * in the sig handler, but we should be disturbing the system less by just
- * creating a thread to do it.
- */
-void show_running_run_stats(void)
-{
- pthread_t thread;
-
- fio_mutex_down(stat_mutex);
-
- if (!pthread_create(&thread, NULL, __show_running_run_stats, NULL)) {
- int err;
-
- err = pthread_detach(thread);
- if (err)
- log_err("fio: DU thread detach failed: %s\n", strerror(err));
-
- return;
- }
-
- fio_mutex_up(stat_mutex);
}
static int status_interval_init;
enum fio_ddir ddir, unsigned int bs,
unsigned long t, uint64_t offset)
{
- const int nr_samples = iolog->nr_samples;
+ uint64_t nr_samples = iolog->nr_samples;
struct io_sample *s;
if (iolog->disabled)
void *new_log;
new_size = 2 * iolog->max_samples * log_entry_sz(iolog);
- new_log = realloc(iolog->log, new_size);
- if (!new_log) {
- log_err("fio: failed extending iolog! Will stop logging.\n");
- iolog->disabled = 1;
- return;
+
+ if (iolog->log_gz && (new_size > iolog->log_gz)) {
+ if (iolog_flush(iolog, 0)) {
+ log_err("fio: failed flushing iolog! Will stop logging.\n");
+ iolog->disabled = 1;
+ return;
+ }
+ nr_samples = iolog->nr_samples;
+ } else {
+ new_log = realloc(iolog->log, new_size);
+ if (!new_log) {
+ log_err("fio: failed extending iolog! Will stop logging.\n");
+ iolog->disabled = 1;
+ return;
+ }
+ iolog->log = new_log;
+ iolog->max_samples <<= 1;
}
- iolog->log = new_log;
- iolog->max_samples <<= 1;
}
s = get_sample(iolog, nr_samples);
s->val = val;
s->time = t;
- s->ddir = ddir;
+ io_sample_set_ddir(iolog, s, ddir);
s->bs = bs;
if (iolog->log_offset) {
for (i = 0; i < 3; i++) {
ts->total_io_u[i] = 0;
ts->short_io_u[i] = 0;
+ ts->drop_io_u[i] = 0;
}
}
fio_mutex_down(stat_mutex);
fio_mutex_remove(stat_mutex);
}
+
+/*
+ * Called from signal handler. Wake up status thread.
+ */
+void show_running_run_stats(void)
+{
+ helper_do_stat = 1;
+ pthread_cond_signal(&helper_cond);
+}