steadystate: cleanups
authorJens Axboe <axboe@fb.com>
Sat, 13 Aug 2016 14:39:57 +0000 (08:39 -0600)
committerJens Axboe <axboe@fb.com>
Mon, 15 Aug 2016 15:44:52 +0000 (09:44 -0600)
- Make this more localized
- Get rid of ->evaluate() pointer, towards making the steadystate_data
  appropriate for wire transfer.
- Move more things to steadystate.[ch]

Signed-off-by: Jens Axboe <axboe@fb.com>
fio.h
init.c
steadystate.c
steadystate.h

diff --git a/fio.h b/fio.h
index 4ab056aaf7467b9784ae358f445e141a2c6d7a1b..d099da82e2653de7c9ad6a501532e1709614d742 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -791,14 +791,6 @@ enum {
        FIO_CPUS_SPLIT,
 };
 
        FIO_CPUS_SPLIT,
 };
 
-enum {
-       FIO_STEADYSTATE_IOPS    = 0,
-       FIO_STEADYSTATE_IOPS_SLOPE,
-       FIO_STEADYSTATE_BW,
-       FIO_STEADYSTATE_BW_SLOPE,
-};
-
-
 extern void exec_trigger(const char *);
 extern void check_trigger_file(void);
 
 extern void exec_trigger(const char *);
 extern void check_trigger_file(void);
 
diff --git a/init.c b/init.c
index e9bf3a2bef5340a98c9e88727d6761ee36938b60..9113865027528f56b1d546c2f29a031c011943db 100644 (file)
--- a/init.c
+++ b/init.c
@@ -81,8 +81,6 @@ unsigned int *fio_debug_jobp = NULL;
 static char cmd_optstr[256];
 static int did_arg;
 
 static char cmd_optstr[256];
 static int did_arg;
 
-bool steadystate = false;
-
 #define FIO_CLIENT_FLAG                (1 << 16)
 
 /*
 #define FIO_CLIENT_FLAG                (1 << 16)
 
 /*
@@ -1590,13 +1588,10 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num,
                td->ss.ramp_time = o->ss_ramp_time;
                td->ss.pct = o->ss_pct;
 
                td->ss.ramp_time = o->ss_ramp_time;
                td->ss.pct = o->ss_pct;
 
-               if (o->ss == FIO_STEADYSTATE_IOPS_SLOPE || o->ss == FIO_STEADYSTATE_BW_SLOPE) {
+               if (steadystate_check_slope(o))
                        td->ss.check_slope = true;
                        td->ss.check_slope = true;
-                       td->ss.evaluate = &steadystate_slope;
-               } else {
+               else
                        td->ss.check_slope = false;
                        td->ss.check_slope = false;
-                       td->ss.evaluate = &steadystate_deviation;
-               }
 
                if (o->ss == FIO_STEADYSTATE_IOPS || o->ss == FIO_STEADYSTATE_IOPS_SLOPE)
                        td->ss.check_iops = true;
 
                if (o->ss == FIO_STEADYSTATE_IOPS || o->ss == FIO_STEADYSTATE_IOPS_SLOPE)
                        td->ss.check_iops = true;
@@ -1620,8 +1615,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num,
                td->ss.slope = 0.0;
                td->ss.deviation = 0.0;
                td->ts.ss = &td->ss;
                td->ss.slope = 0.0;
                td->ss.deviation = 0.0;
                td->ts.ss = &td->ss;
-       }
-       else
+       } else
                td->ts.ss = NULL;
 
        /*
                td->ts.ss = NULL;
 
        /*
index 85e259a07e041f0b2a3bff0af0557ad6ff2f8c23..6cd7c13f19a83694a98908aadbc05d25fb380cbf 100644 (file)
@@ -4,7 +4,9 @@
 #include "steadystate.h"
 #include "helper_thread.h"
 
 #include "steadystate.h"
 #include "helper_thread.h"
 
-void steadystate_setup()
+bool steadystate = false;
+
+void steadystate_setup(void)
 {
        int i, prev_groupid;
        struct thread_data *td, *prev_td;
 {
        int i, prev_groupid;
        struct thread_data *td, *prev_td;
@@ -55,95 +57,8 @@ void steadystate_alloc(struct thread_data *td)
                td->ss.iops_data[i] = td->ss.bw_data[i] = 0;
 }
 
                td->ss.iops_data[i] = td->ss.bw_data[i] = 0;
 }
 
-void steadystate_check()
-{
-       int i, j, ddir, prev_groupid, group_ramp_time_over = 0;
-       unsigned long rate_time;
-       struct thread_data *td, *td2;
-       struct timeval now;
-       unsigned long group_bw = 0, group_iops = 0;
-       unsigned long long td_iops;
-       unsigned long long td_bytes;
-
-       prev_groupid = -1;
-       for_each_td(td, i) {
-               struct steadystate_data *ss = &td->ss;
-
-               if (!ss->dur || td->runstate <= TD_SETTING_UP || td->runstate >= TD_EXITED || ss->attained)
-                       continue;
-
-               td_iops = 0;
-               td_bytes = 0;
-               if (!td->o.group_reporting ||
-                   (td->o.group_reporting && td->groupid != prev_groupid)) {
-                       group_bw = 0;
-                       group_iops = 0;
-                       group_ramp_time_over = 0;
-               }
-               prev_groupid = td->groupid;
-
-               fio_gettime(&now, NULL);
-               if (ss->ramp_time && !ss->ramp_time_over)
-                       /*
-                        * Begin recording data one second after ss->ramp_time
-                        * has elapsed
-                        */
-                       if (utime_since(&td->epoch, &now) >= (ss->ramp_time + 1000000L))
-                               ss->ramp_time_over = 1;
-
-               td_io_u_lock(td);
-               for (ddir = DDIR_READ; ddir < DDIR_RWDIR_CNT; ddir++) {
-                       td_iops += td->io_blocks[ddir];
-                       td_bytes += td->io_bytes[ddir];
-               }
-               td_io_u_unlock(td);
-
-               rate_time = mtime_since(&ss->prev_time, &now);
-               memcpy(&ss->prev_time, &now, sizeof(now));
-
-               /*
-                * Begin monitoring when job starts but don't actually use
-                * data in checking stopping criterion until ss->ramp_time is
-                * over. This ensures that we will have a sane value in
-                * prev_iops/bw the first time through after ss->ramp_time
-                * is done.
-                */
-               if (ss->ramp_time_over) {
-                       group_bw += 1000 * (td_bytes - ss->prev_bytes) / rate_time;
-                       group_iops += 1000 * (td_iops - ss->prev_iops) / rate_time;
-                       ++group_ramp_time_over;
-               }
-               ss->prev_iops = td_iops;
-               ss->prev_bytes = td_bytes;
-
-               if (td->o.group_reporting && !ss->last_in_group)
-                       continue;
-
-               /* don't begin checking criterion until ss->ramp_time is over for at least one thread in group */
-               if (!group_ramp_time_over)
-                       continue;
-
-               dprint(FD_STEADYSTATE, "steadystate_check() thread: %d, groupid: %u, rate_msec: %ld, iops: %lu, bw: %lu, head: %d, tail: %d\n",
-                       i, td->groupid, rate_time, group_iops, group_bw, ss->head, ss->tail);
-
-               if (ss->evaluate(group_iops, group_bw, td))
-               {
-                       if (td->o.group_reporting)
-                               for_each_td(td2, j) {
-                                       if (td2->groupid == td->groupid) {
-                                               td2->ss.attained = 1;
-                                               fio_mark_td_terminate(td2);
-                                       }
-                               }
-                       else {
-                               ss->attained = 1;
-                               fio_mark_td_terminate(td);
-                       }
-               }
-       }
-}
-
-bool steadystate_slope(unsigned long iops, unsigned long bw, struct thread_data *td)
+static bool steadystate_slope(unsigned long iops, unsigned long bw,
+                             struct thread_data *td)
 {
        int i, j;
        double result;
 {
        int i, j;
        double result;
@@ -153,12 +68,9 @@ bool steadystate_slope(unsigned long iops, unsigned long bw, struct thread_data
        ss->bw_data[ss->tail] = bw;
        ss->iops_data[ss->tail] = iops;
 
        ss->bw_data[ss->tail] = bw;
        ss->iops_data[ss->tail] = iops;
 
-       if (ss->tail < ss->head || (ss->tail - ss->head == ss->dur - 1))
-       {
-               if (ss->sum_y == 0)     /* first time through */
-               {
-                       for(i = 0; i < ss->dur; i++)
-                       {
+       if (ss->tail < ss->head || (ss->tail - ss->head == ss->dur - 1)) {
+               if (ss->sum_y == 0) {   /* first time through */
+                       for(i = 0; i < ss->dur; i++) {
                                ss->sum_y += ss->check_iops ? ss->iops_data[i] : ss->bw_data[i];
                                j = ss->head + i;
                                if (j >= ss->dur)
                                ss->sum_y += ss->check_iops ? ss->iops_data[i] : ss->bw_data[i];
                                j = ss->head + i;
                                if (j >= ss->dur)
@@ -193,10 +105,12 @@ bool steadystate_slope(unsigned long iops, unsigned long bw, struct thread_data
        ss->tail = (ss->tail + 1) % ss->dur;
        if (ss->tail <= ss->head)
                ss->head = (ss->head + 1) % ss->dur;
        ss->tail = (ss->tail + 1) % ss->dur;
        if (ss->tail <= ss->head)
                ss->head = (ss->head + 1) % ss->dur;
+
        return false;
 }
 
        return false;
 }
 
-bool steadystate_deviation(unsigned long iops, unsigned long bw, struct thread_data *td)
+static bool steadystate_deviation(unsigned long iops, unsigned long bw,
+                                 struct thread_data *td)
 {
        int i;
        double diff;
 {
        int i;
        double diff;
@@ -207,10 +121,8 @@ bool steadystate_deviation(unsigned long iops, unsigned long bw, struct thread_d
        ss->bw_data[ss->tail] = bw;
        ss->iops_data[ss->tail] = iops;
 
        ss->bw_data[ss->tail] = bw;
        ss->iops_data[ss->tail] = iops;
 
-       if (ss->tail < ss->head || (ss->tail - ss->head == ss->dur - 1))
-       {
-               if (ss->sum_y == 0)     /* first time through */
-               {
+       if (ss->tail < ss->head || (ss->tail - ss->head == ss->dur - 1)) {
+               if (ss->sum_y == 0) {   /* first time through */
                        for(i = 0; i < ss->dur; i++)
                                ss->sum_y += ss->check_iops ? ss->iops_data[i] : ss->bw_data[i];
                } else {                /* easy to update the sum */
                        for(i = 0; i < ss->dur; i++)
                                ss->sum_y += ss->check_iops ? ss->iops_data[i] : ss->bw_data[i];
                } else {                /* easy to update the sum */
@@ -222,8 +134,7 @@ bool steadystate_deviation(unsigned long iops, unsigned long bw, struct thread_d
                mean = (double) ss->sum_y / ss->dur;
                ss->deviation = 0.0;
 
                mean = (double) ss->sum_y / ss->dur;
                ss->deviation = 0.0;
 
-               for (i = 0; i < ss->dur; i++)
-               {
+               for (i = 0; i < ss->dur; i++) {
                        diff = (double) (ss->check_iops ? ss->iops_data[i] : ss->bw_data[i]) - mean;
                        ss->deviation = max(ss->deviation, diff * (diff < 0.0 ? -1.0 : 1.0));
                }
                        diff = (double) (ss->check_iops ? ss->iops_data[i] : ss->bw_data[i]) - mean;
                        ss->deviation = max(ss->deviation, diff * (diff < 0.0 ? -1.0 : 1.0));
                }
@@ -239,5 +150,101 @@ bool steadystate_deviation(unsigned long iops, unsigned long bw, struct thread_d
        ss->tail = (ss->tail + 1) % ss->dur;
        if (ss->tail <= ss->head)
                ss->head = (ss->head + 1) % ss->dur;
        ss->tail = (ss->tail + 1) % ss->dur;
        if (ss->tail <= ss->head)
                ss->head = (ss->head + 1) % ss->dur;
+
        return false;
 }
        return false;
 }
+
+void steadystate_check(void)
+{
+       int i, j, ddir, prev_groupid, group_ramp_time_over = 0;
+       unsigned long rate_time;
+       struct thread_data *td, *td2;
+       struct timeval now;
+       unsigned long group_bw = 0, group_iops = 0;
+       unsigned long long td_iops;
+       unsigned long long td_bytes;
+       bool ret;
+
+       prev_groupid = -1;
+       for_each_td(td, i) {
+               struct steadystate_data *ss = &td->ss;
+
+               if (!ss->dur || td->runstate <= TD_SETTING_UP || td->runstate >= TD_EXITED || ss->attained)
+                       continue;
+
+               td_iops = 0;
+               td_bytes = 0;
+               if (!td->o.group_reporting ||
+                   (td->o.group_reporting && td->groupid != prev_groupid)) {
+                       group_bw = 0;
+                       group_iops = 0;
+                       group_ramp_time_over = 0;
+               }
+               prev_groupid = td->groupid;
+
+               fio_gettime(&now, NULL);
+               if (ss->ramp_time && !ss->ramp_time_over)
+                       /*
+                        * Begin recording data one second after ss->ramp_time
+                        * has elapsed
+                        */
+                       if (utime_since(&td->epoch, &now) >= (ss->ramp_time + 1000000L))
+                               ss->ramp_time_over = 1;
+
+               td_io_u_lock(td);
+               for (ddir = DDIR_READ; ddir < DDIR_RWDIR_CNT; ddir++) {
+                       td_iops += td->io_blocks[ddir];
+                       td_bytes += td->io_bytes[ddir];
+               }
+               td_io_u_unlock(td);
+
+               rate_time = mtime_since(&ss->prev_time, &now);
+               memcpy(&ss->prev_time, &now, sizeof(now));
+
+               /*
+                * Begin monitoring when job starts but don't actually use
+                * data in checking stopping criterion until ss->ramp_time is
+                * over. This ensures that we will have a sane value in
+                * prev_iops/bw the first time through after ss->ramp_time
+                * is done.
+                */
+               if (ss->ramp_time_over) {
+                       group_bw += 1000 * (td_bytes - ss->prev_bytes) / rate_time;
+                       group_iops += 1000 * (td_iops - ss->prev_iops) / rate_time;
+                       ++group_ramp_time_over;
+               }
+               ss->prev_iops = td_iops;
+               ss->prev_bytes = td_bytes;
+
+               if (td->o.group_reporting && !ss->last_in_group)
+                       continue;
+
+               /* don't begin checking criterion until ss->ramp_time is over for at least one thread in group */
+               if (!group_ramp_time_over)
+                       continue;
+
+               dprint(FD_STEADYSTATE, "steadystate_check() thread: %d, groupid: %u, rate_msec: %ld, iops: %lu, bw: %lu, head: %d, tail: %d\n",
+                       i, td->groupid, rate_time, group_iops, group_bw, ss->head, ss->tail);
+
+               if (steadystate_check_slope(&td->o))
+                       ret = steadystate_slope(group_iops, group_bw, td);
+               else
+                       ret = steadystate_deviation(group_iops, group_bw, td);
+
+               if (ret) {
+                       if (td->o.group_reporting) {
+                               for_each_td(td2, j) {
+                                       if (td2->groupid == td->groupid) {
+                                               td2->ss.attained = 1;
+                                               fio_mark_td_terminate(td2);
+                                       }
+                               }
+                       } else {
+                               ss->attained = 1;
+                               fio_mark_td_terminate(td);
+                       }
+               }
+       }
+}
+
+
index 6cd2940908a52bfd1d2729c04171c7c10e9fe4d3..aa31112bf5163ef3784c1266f5f962c7044057e9 100644 (file)
@@ -1,11 +1,13 @@
 #ifndef FIO_STEADYSTATE_H
 #define FIO_STEADYSTATE_H
 
 #ifndef FIO_STEADYSTATE_H
 #define FIO_STEADYSTATE_H
 
+#include "thread_options.h"
+
 extern void steadystate_check(void);
 extern void steadystate_setup(void);
 extern void steadystate_alloc(struct thread_data *);
 extern void steadystate_check(void);
 extern void steadystate_setup(void);
 extern void steadystate_alloc(struct thread_data *);
-extern bool steadystate_deviation(unsigned long, unsigned long, struct thread_data *);
-extern bool steadystate_slope(unsigned long, unsigned long, struct thread_data *);
+
+extern bool steadystate;
 
 /*
  * For steady state detection
 
 /*
  * For steady state detection
@@ -14,7 +16,6 @@ struct steadystate_data {
        double limit;
        unsigned long long dur;
        unsigned long long ramp_time;
        double limit;
        unsigned long long dur;
        unsigned long long ramp_time;
-       bool (*evaluate)(unsigned long, unsigned long, struct thread_data *);
        bool check_iops;
        bool check_slope;
        bool pct;
        bool check_iops;
        bool check_slope;
        bool pct;
@@ -43,4 +44,23 @@ struct steadystate_data {
        unsigned long long prev_bytes;
 };
 
        unsigned long long prev_bytes;
 };
 
+enum {
+       FIO_STEADYSTATE_IOPS    = 0,
+       FIO_STEADYSTATE_IOPS_SLOPE,
+       FIO_STEADYSTATE_BW,
+       FIO_STEADYSTATE_BW_SLOPE,
+};
+
+static inline bool steadystate_check_slope(struct thread_options *o)
+{
+       return o->ss == FIO_STEADYSTATE_IOPS_SLOPE ||
+               o->ss == FIO_STEADYSTATE_BW_SLOPE;
+}
+
+static inline bool steadystate_check_iops(struct thread_options *o)
+{
+       return o->ss == FIO_STEADYSTATE_IOPS ||
+               o->ss == FIO_STEADYSTATE_IOPS_SLOPE;
+}
+
 #endif
 #endif