steadystate: cleanups
[fio.git] / steadystate.c
index 85e259a07e041f0b2a3bff0af0557ad6ff2f8c23..6cd7c13f19a83694a98908aadbc05d25fb380cbf 100644 (file)
@@ -4,7 +4,9 @@
 #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;
@@ -55,95 +57,8 @@ void steadystate_alloc(struct thread_data *td)
                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;
@@ -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;
 
-       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)
@@ -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;
+
        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;
@@ -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;
 
-       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 */
@@ -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;
 
-               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));
                }
@@ -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;
+
        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);
+                       }
+               }
+       }
+}
+
+