projects
/
fio.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
use interpolation for more accurate percentile calculation
[fio.git]
/
stat.c
diff --git
a/stat.c
b/stat.c
index 3a014d6c1aa8f8e7f10690bf09caba68396e52d8..a308eb88455725192aca3d530d7234247792cde9 100644
(file)
--- a/
stat.c
+++ b/
stat.c
@@
-1,10
+1,7
@@
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
-#include <sys/types.h>
#include <sys/stat.h>
#include <sys/stat.h>
-#include <dirent.h>
-#include <libgen.h>
#include <math.h>
#include "fio.h"
#include <math.h>
#include "fio.h"
@@
-18,9
+15,9
@@
#include "helper_thread.h"
#include "smalloc.h"
#include "helper_thread.h"
#include "smalloc.h"
-#define LOG_MSEC_SLACK 1
0
+#define LOG_MSEC_SLACK 1
-struct fio_
mutex *stat_mutex
;
+struct fio_
sem *stat_sem
;
void clear_rusage_stat(struct thread_data *td)
{
void clear_rusage_stat(struct thread_data *td)
{
@@
-135,7
+132,7
@@
static int double_cmp(const void *a, const void *b)
return cmp;
}
return cmp;
}
-unsigned int calc_clat_percentiles(u
nsigned in
t *io_u_plat, unsigned long long nr,
+unsigned int calc_clat_percentiles(u
int64_
t *io_u_plat, unsigned long long nr,
fio_fp64_t *plist, unsigned long long **output,
unsigned long long *maxv, unsigned long long *minv)
{
fio_fp64_t *plist, unsigned long long **output,
unsigned long long *maxv, unsigned long long *minv)
{
@@
-198,7
+195,7
@@
unsigned int calc_clat_percentiles(unsigned int *io_u_plat, unsigned long long n
/*
* Find and display the p-th percentile of clat
*/
/*
* Find and display the p-th percentile of clat
*/
-static void show_clat_percentiles(u
nsigned in
t *io_u_plat, unsigned long long nr,
+static void show_clat_percentiles(u
int64_
t *io_u_plat, unsigned long long nr,
fio_fp64_t *plist, unsigned int precision,
const char *pre, struct buf_output *out)
{
fio_fp64_t *plist, unsigned int precision,
const char *pre, struct buf_output *out)
{
@@
-323,7
+320,7
@@
void show_group_stats(struct group_run_stats *rs, struct buf_output *out)
}
}
}
}
-void stat_calc_dist(u
nsigned in
t *map, unsigned long total, double *io_u_dist)
+void stat_calc_dist(u
int64_
t *map, unsigned long total, double *io_u_dist)
{
int i;
{
int i;
@@
-342,7
+339,7
@@
void stat_calc_dist(unsigned int *map, unsigned long total, double *io_u_dist)
}
static void stat_calc_lat(struct thread_stat *ts, double *dst,
}
static void stat_calc_lat(struct thread_stat *ts, double *dst,
- u
nsigned in
t *src, int nr)
+ u
int64_
t *src, int nr)
{
unsigned long total = ddir_rw_sum(ts->total_io_u);
int i;
{
unsigned long total = ddir_rw_sum(ts->total_io_u);
int i;
@@
-365,7
+362,7
@@
static void stat_calc_lat(struct thread_stat *ts, double *dst,
* To keep the terse format unaltered, add all of the ns latency
* buckets to the first us latency bucket
*/
* To keep the terse format unaltered, add all of the ns latency
* buckets to the first us latency bucket
*/
-void stat_calc_lat_nu(struct thread_stat *ts, double *io_u_lat_u)
+
static
void stat_calc_lat_nu(struct thread_stat *ts, double *io_u_lat_u)
{
unsigned long ntotal = 0, total = ddir_rw_sum(ts->total_io_u);
int i;
{
unsigned long ntotal = 0, total = ddir_rw_sum(ts->total_io_u);
int i;
@@
-673,7
+670,6
@@
static int calc_block_percentiles(int nr_block_infos, uint32_t *block_infos,
if (len > 1)
qsort((void *)plist, len, sizeof(plist[0]), double_cmp);
if (len > 1)
qsort((void *)plist, len, sizeof(plist[0]), double_cmp);
- nr_uninit = 0;
/* Start only after the uninit entries end */
for (nr_uninit = 0;
nr_uninit < nr_block_infos
/* Start only after the uninit entries end */
for (nr_uninit = 0;
nr_uninit < nr_block_infos
@@
-854,12
+850,13
@@
static void show_thread_status_normal(struct thread_stat *ts,
io_u_dist[1], io_u_dist[2],
io_u_dist[3], io_u_dist[4],
io_u_dist[5], io_u_dist[6]);
io_u_dist[1], io_u_dist[2],
io_u_dist[3], io_u_dist[4],
io_u_dist[5], io_u_dist[6]);
- log_buf(out, " issued rwt
: total=%llu,%llu,%llu,
"
- " short=%llu,%llu,%llu,"
- " dropped=%llu,%llu,%llu\n",
+ log_buf(out, " issued rwt
s: total=%llu,%llu,%llu,%llu
"
+ " short=%llu,%llu,%llu,
0
"
+ " dropped=%llu,%llu,%llu
,0
\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->total_io_u[0],
(unsigned long long) ts->total_io_u[1],
(unsigned long long) ts->total_io_u[2],
+ (unsigned long long) ts->total_io_u[3],
(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[0],
(unsigned long long) ts->short_io_u[1],
(unsigned long long) ts->short_io_u[2],
@@
-1048,6
+1045,7
@@
static void add_ddir_status_json(struct thread_stat *ts,
tmp_object = json_create_object();
json_object_add_value_object(dir_object, "lat_ns", tmp_object);
tmp_object = json_create_object();
json_object_add_value_object(dir_object, "lat_ns", tmp_object);
+ json_object_add_value_int(dir_object, "total_ios", ts->total_io_u[DDIR_SYNC]);
json_object_add_value_int(tmp_object, "min", min);
json_object_add_value_int(tmp_object, "max", max);
json_object_add_value_float(tmp_object, "mean", mean);
json_object_add_value_int(tmp_object, "min", min);
json_object_add_value_int(tmp_object, "max", max);
json_object_add_value_float(tmp_object, "mean", mean);
@@
-1224,7
+1222,7
@@
static void show_thread_status_terse_all(struct thread_stat *ts,
}
static void json_add_job_opts(struct json_object *root, const char *name,
}
static void json_add_job_opts(struct json_object *root, const char *name,
- struct flist_head *opt_list
, bool num_jobs
)
+ struct flist_head *opt_list)
{
struct json_object *dir_object;
struct flist_head *entry;
{
struct json_object *dir_object;
struct flist_head *entry;
@@
-1240,8
+1238,6
@@
static void json_add_job_opts(struct json_object *root, const char *name,
const char *pos = "";
p = flist_entry(entry, struct print_option, list);
const char *pos = "";
p = flist_entry(entry, struct print_option, list);
- if (!num_jobs && !strcmp(p->name, "numjobs"))
- continue;
if (p->value)
pos = p->value;
json_object_add_value_string(dir_object, p->name, pos);
if (p->value)
pos = p->value;
json_object_add_value_string(dir_object, p->name, pos);
@@
-1275,7
+1271,7
@@
static struct json_object *show_thread_status_json(struct thread_stat *ts,
}
if (opt_list)
}
if (opt_list)
- json_add_job_opts(root, "job options", opt_list
, true
);
+ json_add_job_opts(root, "job options", opt_list);
add_ddir_status_json(ts, rs, DDIR_READ, root);
add_ddir_status_json(ts, rs, DDIR_WRITE, root);
add_ddir_status_json(ts, rs, DDIR_READ, root);
add_ddir_status_json(ts, rs, DDIR_WRITE, root);
@@
-1292,6
+1288,7
@@
static struct json_object *show_thread_status_json(struct thread_stat *ts,
usr_cpu = 0;
sys_cpu = 0;
}
usr_cpu = 0;
sys_cpu = 0;
}
+ json_object_add_value_int(root, "job_runtime", ts->total_run_time);
json_object_add_value_float(root, "usr_cpu", usr_cpu);
json_object_add_value_float(root, "sys_cpu", sys_cpu);
json_object_add_value_int(root, "ctx", ts->ctx);
json_object_add_value_float(root, "usr_cpu", usr_cpu);
json_object_add_value_float(root, "sys_cpu", sys_cpu);
json_object_add_value_int(root, "ctx", ts->ctx);
@@
-1402,7
+1399,7
@@
static struct json_object *show_thread_status_json(struct thread_stat *ts,
if (ts->ss_dur) {
struct json_object *data;
struct json_array *iops, *bw;
if (ts->ss_dur) {
struct json_object *data;
struct json_array *iops, *bw;
- int
i, j, k
;
+ int
j, k, l
;
char ss_buf[64];
snprintf(ss_buf, sizeof(ss_buf), "%s%s:%f%s",
char ss_buf[64];
snprintf(ss_buf, sizeof(ss_buf), "%s%s:%f%s",
@@
-1438,8
+1435,8
@@
static struct json_object *show_thread_status_json(struct thread_stat *ts,
j = ts->ss_head;
else
j = ts->ss_head == 0 ? ts->ss_dur - 1 : ts->ss_head - 1;
j = ts->ss_head;
else
j = ts->ss_head == 0 ? ts->ss_dur - 1 : ts->ss_head - 1;
- for (
i = 0; i < ts->ss_dur; i
++) {
- k = (j +
i
) % ts->ss_dur;
+ for (
l = 0; l < ts->ss_dur; l
++) {
+ k = (j +
l
) % ts->ss_dur;
json_array_add_value_int(bw, ts->ss_bw_data[k]);
json_array_add_value_int(iops, ts->ss_iops_data[k]);
}
json_array_add_value_int(bw, ts->ss_bw_data[k]);
json_array_add_value_int(iops, ts->ss_iops_data[k]);
}
@@
-1609,6
+1606,8
@@
void sum_thread_stats(struct thread_stat *dst, struct thread_stat *src,
}
}
}
}
+ dst->total_io_u[DDIR_SYNC] += src->total_io_u[DDIR_SYNC];
+
for (k = 0; k < DDIR_RWDIR_CNT; k++) {
int m;
for (k = 0; k < DDIR_RWDIR_CNT; k++) {
int m;
@@
-1647,6
+1646,7
@@
void init_thread_stat(struct thread_stat *ts)
ts->bw_stat[j].min_val = -1UL;
ts->iops_stat[j].min_val = -1UL;
}
ts->bw_stat[j].min_val = -1UL;
ts->iops_stat[j].min_val = -1UL;
}
+ ts->sync_stat.min_val = -1UL;
ts->groupid = -1;
}
ts->groupid = -1;
}
@@
-1857,13
+1857,14
@@
void __show_run_stats(void)
char time_buf[32];
struct timeval now;
unsigned long long ms_since_epoch;
char time_buf[32];
struct timeval now;
unsigned long long ms_since_epoch;
+ time_t tv_sec;
gettimeofday(&now, NULL);
ms_since_epoch = (unsigned long long)(now.tv_sec) * 1000 +
(unsigned long long)(now.tv_usec) / 1000;
gettimeofday(&now, NULL);
ms_since_epoch = (unsigned long long)(now.tv_sec) * 1000 +
(unsigned long long)(now.tv_usec) / 1000;
- os_ctime_r((const time_t *) &now.tv_sec, time_buf,
-
sizeof(time_buf));
+ tv_sec = now.tv_sec;
+
os_ctime_r(&tv_sec, time_buf,
sizeof(time_buf));
if (time_buf[strlen(time_buf) - 1] == '\n')
time_buf[strlen(time_buf) - 1] = '\0';
if (time_buf[strlen(time_buf) - 1] == '\n')
time_buf[strlen(time_buf) - 1] = '\0';
@@
-1873,7
+1874,7
@@
void __show_run_stats(void)
json_object_add_value_int(root, "timestamp_ms", ms_since_epoch);
json_object_add_value_string(root, "time", time_buf);
global = get_global_options();
json_object_add_value_int(root, "timestamp_ms", ms_since_epoch);
json_object_add_value_string(root, "time", time_buf);
global = get_global_options();
- json_add_job_opts(root, "global options", &global->opt_list
, false
);
+ json_add_job_opts(root, "global options", &global->opt_list);
array = json_create_array();
json_object_add_value_array(root, "jobs", array);
}
array = json_create_array();
json_object_add_value_array(root, "jobs", array);
}
@@
-1934,19
+1935,14
@@
void __show_run_stats(void)
buf_output_free(out);
}
buf_output_free(out);
}
+ fio_idle_prof_cleanup();
+
log_info_flush();
free(runstats);
free(threadstats);
free(opt_lists);
}
log_info_flush();
free(runstats);
free(threadstats);
free(opt_lists);
}
-void show_run_stats(void)
-{
- fio_mutex_down(stat_mutex);
- __show_run_stats();
- fio_mutex_up(stat_mutex);
-}
-
void __show_running_run_stats(void)
{
struct thread_data *td;
void __show_running_run_stats(void)
{
struct thread_data *td;
@@
-1954,7
+1950,7
@@
void __show_running_run_stats(void)
struct timespec ts;
int i;
struct timespec ts;
int i;
- fio_
mutex_down(stat_mutex
);
+ fio_
sem_down(stat_sem
);
rt = malloc(thread_number * sizeof(unsigned long long));
fio_gettime(&ts, NULL);
rt = malloc(thread_number * sizeof(unsigned long long));
fio_gettime(&ts, NULL);
@@
-1980,7
+1976,7
@@
void __show_running_run_stats(void)
continue;
if (td->rusage_sem) {
td->update_rusage = 1;
continue;
if (td->rusage_sem) {
td->update_rusage = 1;
- fio_
mutex
_down(td->rusage_sem);
+ fio_
sem
_down(td->rusage_sem);
}
td->update_rusage = 0;
}
}
td->update_rusage = 0;
}
@@
-1997,7
+1993,7
@@
void __show_running_run_stats(void)
}
free(rt);
}
free(rt);
- fio_
mutex_up(stat_mutex
);
+ fio_
sem_up(stat_sem
);
}
static bool status_interval_init;
}
static bool status_interval_init;
@@
-2212,12
+2208,14
@@
static struct io_logs *get_cur_log(struct io_log *iolog)
* submissions, flag 'td' as needing a log regrow and we'll take
* care of it on the submission side.
*/
* submissions, flag 'td' as needing a log regrow and we'll take
* care of it on the submission side.
*/
- if (
iolog->td->o.io_submit_mode == IO_MODE_OFFLOAD
||
+ if (
(iolog->td && iolog->td->o.io_submit_mode == IO_MODE_OFFLOAD)
||
!per_unit_log(iolog))
return regrow_log(iolog);
!per_unit_log(iolog))
return regrow_log(iolog);
- iolog->td->flags |= TD_F_REGROW_LOGS;
- assert(iolog->pending->nr_samples < iolog->pending->max_samples);
+ if (iolog->td)
+ iolog->td->flags |= TD_F_REGROW_LOGS;
+ if (iolog->pending)
+ assert(iolog->pending->nr_samples < iolog->pending->max_samples);
return iolog->pending;
}
return iolog->pending;
}
@@
-2287,6
+2285,8
@@
void reset_io_stats(struct thread_data *td)
}
}
}
}
+ ts->total_io_u[DDIR_SYNC] = 0;
+
for (i = 0; i < FIO_IO_U_MAP_NR; i++) {
ts->io_u_map[i] = 0;
ts->io_u_submit[i] = 0;
for (i = 0; i < FIO_IO_U_MAP_NR; i++) {
ts->io_u_map[i] = 0;
ts->io_u_submit[i] = 0;
@@
-2335,9
+2335,11
@@
static void _add_stat_to_log(struct io_log *iolog, unsigned long elapsed,
__add_stat_to_log(iolog, ddir, elapsed, log_max);
}
__add_stat_to_log(iolog, ddir, elapsed, log_max);
}
-static long add_log_sample(struct thread_data *td, struct io_log *iolog,
- union io_sample_data data, enum fio_ddir ddir,
- unsigned int bs, uint64_t offset)
+static unsigned long add_log_sample(struct thread_data *td,
+ struct io_log *iolog,
+ union io_sample_data data,
+ enum fio_ddir ddir, unsigned int bs,
+ uint64_t offset)
{
unsigned long elapsed, this_window;
{
unsigned long elapsed, this_window;
@@
-2368,7
+2370,7
@@
static long add_log_sample(struct thread_data *td, struct io_log *iolog,
if (elapsed < iolog->avg_last[ddir])
return iolog->avg_last[ddir] - elapsed;
else if (this_window < iolog->avg_msec) {
if (elapsed < iolog->avg_last[ddir])
return iolog->avg_last[ddir] - elapsed;
else if (this_window < iolog->avg_msec) {
-
int
diff = iolog->avg_msec - this_window;
+
unsigned long
diff = iolog->avg_msec - this_window;
if (inline_log(iolog) || diff > LOG_MSEC_SLACK)
return diff;
if (inline_log(iolog) || diff > LOG_MSEC_SLACK)
return diff;
@@
-2455,7
+2457,7
@@
void add_clat_sample(struct thread_data *td, enum fio_ddir ddir,
this_window = elapsed - hw->hist_last;
if (this_window >= iolog->hist_msec) {
this_window = elapsed - hw->hist_last;
if (this_window >= iolog->hist_msec) {
- u
nsigned in
t *io_u_plat;
+ u
int64_
t *io_u_plat;
struct io_u_plat_entry *dst;
/*
struct io_u_plat_entry *dst;
/*
@@
-2465,7
+2467,7
@@
void add_clat_sample(struct thread_data *td, enum fio_ddir ddir,
* located in iolog.c after printing this sample to the
* log file.
*/
* located in iolog.c after printing this sample to the
* log file.
*/
- io_u_plat = (u
nsigned in
t *) td->ts.io_u_plat[ddir];
+ io_u_plat = (u
int64_
t *) td->ts.io_u_plat[ddir];
dst = malloc(sizeof(struct io_u_plat_entry));
memcpy(&(dst->io_u_plat), io_u_plat,
FIO_IO_U_PLAT_NR * sizeof(unsigned int));
dst = malloc(sizeof(struct io_u_plat_entry));
memcpy(&(dst->io_u_plat), io_u_plat,
FIO_IO_U_PLAT_NR * sizeof(unsigned int));
@@
-2557,7
+2559,7
@@
static int __add_samples(struct thread_data *td, struct timespec *parent_tv,
{
unsigned long spent, rate;
enum fio_ddir ddir;
{
unsigned long spent, rate;
enum fio_ddir ddir;
- unsigned
int
next, next_log;
+ unsigned
long
next, next_log;
next_log = avg_time;
next_log = avg_time;
@@
-2682,7
+2684,7
@@
int calc_log_samples(void)
void stat_init(void)
{
void stat_init(void)
{
- stat_
mutex = fio_mutex_init(FIO_MUTEX
_UNLOCKED);
+ stat_
sem = fio_sem_init(FIO_SEM
_UNLOCKED);
}
void stat_exit(void)
}
void stat_exit(void)
@@
-2691,8
+2693,8
@@
void stat_exit(void)
* When we have the mutex, we know out-of-band access to it
* have ended.
*/
* When we have the mutex, we know out-of-band access to it
* have ended.
*/
- fio_
mutex_down(stat_mutex
);
- fio_
mutex_remove(stat_mutex
);
+ fio_
sem_down(stat_sem
);
+ fio_
sem_remove(stat_sem
);
}
/*
}
/*