Initialize global and non-static variables
[fio.git] / init.c
diff --git a/init.c b/init.c
index 23be863141a3ff670d84780eccb52b924ab0cb66..4709ff29146292a41b6994b450b68730ce8a3032 100644 (file)
--- a/init.c
+++ b/init.c
@@ -9,7 +9,9 @@
 #include <string.h>
 #include <errno.h>
 #include <sys/ipc.h>
+#ifndef FIO_NO_HAVE_SHM_H
 #include <sys/shm.h>
+#endif
 #include <sys/types.h>
 #include <sys/stat.h>
 
@@ -20,6 +22,7 @@
 #include "verify.h"
 #include "profile.h"
 #include "server.h"
+#include "idletime.h"
 
 #include "lib/getopt.h"
 
@@ -37,7 +40,7 @@ struct thread_data *threads = NULL;
 
 int exitall_on_terminate = 0;
 int output_format = FIO_OUTPUT_NORMAL;
-int eta_print;
+int eta_print = FIO_ETA_AUTO;
 unsigned long long mlock_size = 0;
 FILE *f_out = NULL;
 FILE *f_err = NULL;
@@ -64,26 +67,6 @@ unsigned int *fio_debug_jobp = NULL;
 static char cmd_optstr[256];
 static int did_arg;
 
-const fio_fp64_t def_percentile_list[FIO_IO_U_LIST_MAX_LEN] = {
-       { .u.f  =  1.00 },
-       { .u.f  =  5.00 },
-       { .u.f  = 10.00 },
-       { .u.f  = 20.00 },
-       { .u.f  = 30.00 },
-       { .u.f  = 40.00 },
-       { .u.f  = 50.00 },
-       { .u.f  = 60.00 },
-       { .u.f  = 70.00 },
-       { .u.f  = 80.00 },
-       { .u.f  = 90.00 },
-       { .u.f  = 95.00 },
-       { .u.f  = 99.00 },
-       { .u.f  = 99.50 },
-       { .u.f  = 99.90 },
-       { .u.f  = 99.95 },
-       { .u.f  = 99.99 },
-};
-
 #define FIO_CLIENT_FLAG                (1 << 16)
 
 /*
@@ -205,6 +188,16 @@ static struct option l_opts[FIO_NR_OPTIONS] = {
                .has_arg        = required_argument,
                .val            = 'C',
        },
+       {
+               .name           = (char *) "cpuclock-test",
+               .has_arg        = no_argument,
+               .val            = 'T',
+       },
+       {
+               .name           = (char *) "idle-prof",
+               .has_arg        = required_argument,
+               .val            = 'I',
+       },
        {
                .name           = NULL,
        },
@@ -317,6 +310,10 @@ static struct thread_data *get_new_job(int global, struct thread_data *parent,
        profile_add_hooks(td);
 
        td->thread_number = thread_number;
+
+       if (!parent || !parent->o.group_reporting)
+               stat_number++;
+
        return td;
 }
 
@@ -411,7 +408,7 @@ static int fixup_options(struct thread_data *td)
        /*
         * only really works with 1 file
         */
-       if (o->zone_size && o->open_files == 1)
+       if (o->zone_size && o->open_files > 1)
                o->zone_size = 0;
 
        /*
@@ -485,17 +482,8 @@ static int fixup_options(struct thread_data *td)
        /*
         * The low water mark cannot be bigger than the iodepth
         */
-       if (o->iodepth_low > o->iodepth || !o->iodepth_low) {
-               /*
-                * syslet work around - if the workload is sequential,
-                * we want to let the queue drain all the way down to
-                * avoid seeking between async threads
-                */
-               if (!strcmp(td->io_ops->name, "syslet-rw") && !td_random(td))
-                       o->iodepth_low = 1;
-               else
-                       o->iodepth_low = o->iodepth;
-       }
+       if (o->iodepth_low > o->iodepth || !o->iodepth_low)
+               o->iodepth_low = o->iodepth;
 
        /*
         * If batch number isn't set, default to the same as iodepth
@@ -558,7 +546,7 @@ static int fixup_options(struct thread_data *td)
                }
        }
 
-#ifndef FIO_HAVE_FDATASYNC
+#ifndef CONFIG_FDATASYNC
        if (o->fdatasync_blocks) {
                log_info("fio: this platform does not support fdatasync()"
                         " falling back to using fsync().  Use the 'fsync'"
@@ -592,6 +580,13 @@ static int fixup_options(struct thread_data *td)
                td->o.compress_percentage = 0;
        }
 
+       /*
+        * Using a non-uniform random distribution excludes usage of
+        * a random map
+        */
+       if (td->o.random_distribution != FIO_RAND_DIST_RANDOM)
+               td->o.norandommap = 1;
+
        return ret;
 }
 
@@ -612,7 +607,7 @@ static char *to_kmg(unsigned int val)
                p++;
        } while (*p);
 
-       snprintf(buf, 31, "%u%c", val, *p);
+       snprintf(buf, 32, "%u%c", val, *p);
        return buf;
 }
 
@@ -647,44 +642,44 @@ static int exists_and_not_file(const char *filename)
 
 static void td_fill_rand_seeds_os(struct thread_data *td)
 {
-       os_random_seed(td->rand_seeds[0], &td->bsrange_state);
-       os_random_seed(td->rand_seeds[1], &td->verify_state);
-       os_random_seed(td->rand_seeds[2], &td->rwmix_state);
+       os_random_seed(td->rand_seeds[FIO_RAND_BS_OFF], &td->bsrange_state);
+       os_random_seed(td->rand_seeds[FIO_RAND_VER_OFF], &td->verify_state);
+       os_random_seed(td->rand_seeds[FIO_RAND_MIX_OFF], &td->rwmix_state);
 
        if (td->o.file_service_type == FIO_FSERVICE_RANDOM)
-               os_random_seed(td->rand_seeds[3], &td->next_file_state);
+               os_random_seed(td->rand_seeds[FIO_RAND_FILE_OFF], &td->next_file_state);
 
-       os_random_seed(td->rand_seeds[5], &td->file_size_state);
-       os_random_seed(td->rand_seeds[6], &td->trim_state);
+       os_random_seed(td->rand_seeds[FIO_RAND_FILE_SIZE_OFF], &td->file_size_state);
+       os_random_seed(td->rand_seeds[FIO_RAND_TRIM_OFF], &td->trim_state);
 
        if (!td_random(td))
                return;
 
        if (td->o.rand_repeatable)
-               td->rand_seeds[4] = FIO_RANDSEED * td->thread_number;
+               td->rand_seeds[FIO_RAND_BLOCK_OFF] = FIO_RANDSEED * td->thread_number;
 
-       os_random_seed(td->rand_seeds[4], &td->random_state);
+       os_random_seed(td->rand_seeds[FIO_RAND_BLOCK_OFF], &td->random_state);
 }
 
 static void td_fill_rand_seeds_internal(struct thread_data *td)
 {
-       init_rand_seed(&td->__bsrange_state, td->rand_seeds[0]);
-       init_rand_seed(&td->__verify_state, td->rand_seeds[1]);
-       init_rand_seed(&td->__rwmix_state, td->rand_seeds[2]);
+       init_rand_seed(&td->__bsrange_state, td->rand_seeds[FIO_RAND_BS_OFF]);
+       init_rand_seed(&td->__verify_state, td->rand_seeds[FIO_RAND_VER_OFF]);
+       init_rand_seed(&td->__rwmix_state, td->rand_seeds[FIO_RAND_MIX_OFF]);
 
        if (td->o.file_service_type == FIO_FSERVICE_RANDOM)
-               init_rand_seed(&td->__next_file_state, td->rand_seeds[3]);
+               init_rand_seed(&td->__next_file_state, td->rand_seeds[FIO_RAND_FILE_OFF]);
 
-       init_rand_seed(&td->__file_size_state, td->rand_seeds[5]);
-       init_rand_seed(&td->__trim_state, td->rand_seeds[6]);
+       init_rand_seed(&td->__file_size_state, td->rand_seeds[FIO_RAND_FILE_SIZE_OFF]);
+       init_rand_seed(&td->__trim_state, td->rand_seeds[FIO_RAND_TRIM_OFF]);
 
        if (!td_random(td))
                return;
 
        if (td->o.rand_repeatable)
-               td->rand_seeds[4] = FIO_RANDSEED * td->thread_number;
+               td->rand_seeds[FIO_RAND_BLOCK_OFF] = FIO_RANDSEED * td->thread_number;
 
-       init_rand_seed(&td->__random_state, td->rand_seeds[4]);
+       init_rand_seed(&td->__random_state, td->rand_seeds[FIO_RAND_BLOCK_OFF]);
 }
 
 void td_fill_rand_seeds(struct thread_data *td)
@@ -694,10 +689,9 @@ void td_fill_rand_seeds(struct thread_data *td)
        else
                td_fill_rand_seeds_internal(td);
 
-       init_rand_seed(&td->buf_state, td->rand_seeds[7]);
+       init_rand_seed(&td->buf_state, td->rand_seeds[FIO_RAND_BUF_OFF]);
 }
 
-
 /*
  * Initializes the ioengine configured for a job, if it has not been done so
  * already.
@@ -754,6 +748,44 @@ int ioengine_load(struct thread_data *td)
        return 0;
 }
 
+static void init_flags(struct thread_data *td)
+{
+       struct thread_options *o = &td->o;
+
+       if (o->verify_backlog)
+               td->flags |= TD_F_VER_BACKLOG;
+       if (o->trim_backlog)
+               td->flags |= TD_F_TRIM_BACKLOG;
+       if (o->read_iolog_file)
+               td->flags |= TD_F_READ_IOLOG;
+       if (o->refill_buffers)
+               td->flags |= TD_F_REFILL_BUFFERS;
+       if (o->scramble_buffers)
+               td->flags |= TD_F_SCRAMBLE_BUFFERS;
+       if (o->verify != VERIFY_NONE)
+               td->flags |= TD_F_VER_NONE;
+}
+
+static int setup_random_seeds(struct thread_data *td)
+{
+       unsigned long seed;
+       unsigned int i;
+
+       if (!td->o.rand_repeatable)
+               return init_random_state(td, td->rand_seeds, sizeof(td->rand_seeds));
+
+       for (seed = 0x89, i = 0; i < 4; i++)
+               seed *= 0x9e370001UL;
+
+       for (i = 0; i < FIO_RAND_NR_OFFS; i++) {
+               td->rand_seeds[i] = seed;
+               seed *= 0x9e370001UL;
+       }
+
+       td_fill_rand_seeds(td);
+       return 0;
+}
+
 /*
  * Adds a job to the list of things todo. Sanitizes the various options
  * to make sure we don't have conflicts, and initializes various
@@ -774,6 +806,8 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num)
        if (td == &def_thread)
                return 0;
 
+       init_flags(td);
+
        /*
         * if we are just dumping the output command line, don't add the job
         */
@@ -833,10 +867,8 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num)
        td->mutex = fio_mutex_init(FIO_MUTEX_LOCKED);
 
        td->ts.clat_percentiles = td->o.clat_percentiles;
-       if (td->o.overwrite_plist)
-               memcpy(td->ts.percentile_list, td->o.percentile_list, sizeof(td->o.percentile_list));
-       else
-               memcpy(td->ts.percentile_list, def_percentile_list, sizeof(def_percentile_list));
+       td->ts.percentile_precision = td->o.percentile_precision;
+       memcpy(td->ts.percentile_list, td->o.percentile_list, sizeof(td->o.percentile_list));
 
        for (i = 0; i < DDIR_RWDIR_CNT; i++) {
                td->ts.clat_stat[i].min_val = ULONG_MAX;
@@ -854,7 +886,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num)
        td->groupid = groupid;
        prev_group_jobs++;
 
-       if (init_random_state(td, td->rand_seeds, sizeof(td->rand_seeds))) {
+       if (setup_random_seeds(td)) {
                td_verror(td, errno, "init_random_state");
                goto err;
        }
@@ -1222,6 +1254,7 @@ static void usage(const char *name)
        printf("  --terse-version=x\tSet terse version output format to 'x'\n");
        printf("  --version\t\tPrint version info and exit\n");
        printf("  --help\t\tPrint this page\n");
+       printf("  --cpuclock-test\tPerform test/validation of CPU clock\n");
        printf("  --cmdhelp=cmd\t\tPrint command help, \"all\" for all of"
                " them\n");
        printf("  --enghelp=engine\tPrint ioengine help, or list"
@@ -1241,8 +1274,11 @@ static void usage(const char *name)
        printf("  --server=args\t\tStart a backend fio server\n");
        printf("  --daemonize=pidfile\tBackground fio server, write pid to file\n");
        printf("  --client=hostname\tTalk to remote backend fio server at hostname\n");
+       printf("  --idle-prof=option\tReport cpu idleness on a system or percpu basis\n"
+               "\t\t\t(option=system,percpu) or run unit work\n"
+               "\t\t\tcalibration only (option=calibrate)\n");
        printf("\nFio was written by Jens Axboe <jens.axboe@oracle.com>");
-       printf("\n                 Jens Axboe <jaxboe@fusionio.com>\n");
+       printf("\n                   Jens Axboe <jaxboe@fusionio.com>\n");
 }
 
 #ifdef FIO_INC_DEBUG
@@ -1562,6 +1598,14 @@ int parse_cmd_line(int argc, char *argv[])
                case 'D':
                        pid_file = strdup(optarg);
                        break;
+               case 'I':
+                       if ((ret = fio_idle_prof_parse_opt(optarg))) {
+                               /* exit on error and calibration only */
+                               do_exit++;
+                               if (ret == -1) 
+                                       exit_val = 1;
+                       }
+                       break;
                case 'C':
                        if (is_backend) {
                                log_err("fio: can't be both client and server\n");
@@ -1588,6 +1632,13 @@ int parse_cmd_line(int argc, char *argv[])
                                optind++;
                        }
                        break;
+               case 'T':
+                       do_exit++;
+                       exit_val = fio_monotonic_clocktest();
+                       break;
+               case '?':
+                       log_err("%s: unrecognized option '%s'\n", argv[0],
+                                                       argv[optind - 1]);
                default:
                        do_exit++;
                        exit_val = 1;