t/axmap: add a few more overlap test cases
[fio.git] / stat.c
diff --git a/stat.c b/stat.c
index a980a1d2819b356647e8ae6bb131e17f92940339..a308eb88455725192aca3d530d7234247792cde9 100644 (file)
--- a/stat.c
+++ b/stat.c
@@ -1,10 +1,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <sys/time.h>
-#include <sys/types.h>
 #include <sys/stat.h>
-#include <dirent.h>
-#include <libgen.h>
 #include <math.h>
 
 #include "fio.h"
@@ -18,9 +15,9 @@
 #include "helper_thread.h"
 #include "smalloc.h"
 
-#define LOG_MSEC_SLACK 10
+#define LOG_MSEC_SLACK 1
 
-struct fio_mutex *stat_mutex;
+struct fio_sem *stat_sem;
 
 void clear_rusage_stat(struct thread_data *td)
 {
@@ -135,7 +132,7 @@ static int double_cmp(const void *a, const void *b)
        return cmp;
 }
 
-unsigned int calc_clat_percentiles(unsigned int *io_u_plat, unsigned long long nr,
+unsigned int calc_clat_percentiles(uint64_t *io_u_plat, unsigned long long nr,
                                   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
  */
-static void show_clat_percentiles(unsigned int *io_u_plat, unsigned long long nr,
+static void show_clat_percentiles(uint64_t *io_u_plat, unsigned long long nr,
                                  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(unsigned int *map, unsigned long total, double *io_u_dist)
+void stat_calc_dist(uint64_t *map, unsigned long total, double *io_u_dist)
 {
        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,
-                         unsigned int *src, int nr)
+                         uint64_t *src, int nr)
 {
        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
  */
-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;
@@ -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);
 
-       nr_uninit = 0;
        /* Start only after the uninit entries end */
        for (nr_uninit = 0;
             nr_uninit < nr_block_infos
@@ -1226,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,
-                             struct flist_head *opt_list, bool num_jobs)
+                             struct flist_head *opt_list)
 {
        struct json_object *dir_object;
        struct flist_head *entry;
@@ -1242,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);
-               if (!num_jobs && !strcmp(p->name, "numjobs"))
-                       continue;
                if (p->value)
                        pos = p->value;
                json_object_add_value_string(dir_object, p->name, pos);
@@ -1277,7 +1271,7 @@ static struct json_object *show_thread_status_json(struct thread_stat *ts,
        }
 
        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);
@@ -1294,6 +1288,7 @@ static struct json_object *show_thread_status_json(struct thread_stat *ts,
                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);
@@ -1404,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;
-               int i, j, k;
+               int j, k, l;
                char ss_buf[64];
 
                snprintf(ss_buf, sizeof(ss_buf), "%s%s:%f%s",
@@ -1440,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;
-               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]);
                }
@@ -1862,13 +1857,14 @@ void __show_run_stats(void)
                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;
 
-               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';
 
@@ -1878,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_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);
        }
@@ -1939,19 +1935,14 @@ void __show_run_stats(void)
                buf_output_free(out);
        }
 
+       fio_idle_prof_cleanup();
+
        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;
@@ -1959,7 +1950,7 @@ void __show_running_run_stats(void)
        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);
@@ -1985,7 +1976,7 @@ void __show_running_run_stats(void)
                        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;
        }
@@ -2002,7 +1993,7 @@ void __show_running_run_stats(void)
        }
 
        free(rt);
-       fio_mutex_up(stat_mutex);
+       fio_sem_up(stat_sem);
 }
 
 static bool status_interval_init;
@@ -2217,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.
         */
-       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);
 
-       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;
 }
 
@@ -2342,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);
 }
 
-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;
 
@@ -2375,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) {
-               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;
@@ -2462,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) {
-                       unsigned int *io_u_plat;
+                       uint64_t *io_u_plat;
                        struct io_u_plat_entry *dst;
 
                        /*
@@ -2472,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.
                         */
-                       io_u_plat = (unsigned int *) td->ts.io_u_plat[ddir];
+                       io_u_plat = (uint64_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));
@@ -2564,7 +2559,7 @@ static int __add_samples(struct thread_data *td, struct timespec *parent_tv,
 {
        unsigned long spent, rate;
        enum fio_ddir ddir;
-       unsigned int next, next_log;
+       unsigned long next, next_log;
 
        next_log = avg_time;
 
@@ -2689,7 +2684,7 @@ int calc_log_samples(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)
@@ -2698,8 +2693,8 @@ void stat_exit(void)
         * 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);
 }
 
 /*