+static bool steadystate_slope(uint64_t iops, uint64_t bw,
+ struct thread_data *td)
+{
+ int i, j;
+ double result;
+ struct steadystate_data *ss = &td->ss;
+ uint64_t new_val;
+
+ ss->bw_data[ss->tail] = bw;
+ ss->iops_data[ss->tail] = iops;
+
+ if (ss->state & __FIO_SS_IOPS)
+ new_val = iops;
+ else
+ new_val = bw;
+
+ if (ss->state & __FIO_SS_BUFFER_FULL || ss->tail - ss->head == ss->dur - 1) {
+ if (!(ss->state & __FIO_SS_BUFFER_FULL)) {
+ /* first time through */
+ for(i = 0, ss->sum_y = 0; i < ss->dur; i++) {
+ if (ss->state & __FIO_SS_IOPS)
+ ss->sum_y += ss->iops_data[i];
+ else
+ ss->sum_y += ss->bw_data[i];
+ j = (ss->head + i) % ss->dur;
+ if (ss->state & __FIO_SS_IOPS)
+ ss->sum_xy += i * ss->iops_data[j];
+ else
+ ss->sum_xy += i * ss->bw_data[j];
+ }
+ ss->state |= __FIO_SS_BUFFER_FULL;
+ } else { /* easy to update the sums */
+ ss->sum_y -= ss->oldest_y;
+ ss->sum_y += new_val;
+ ss->sum_xy = ss->sum_xy - ss->sum_y + ss->dur * new_val;
+ }
+
+ if (ss->state & __FIO_SS_IOPS)
+ ss->oldest_y = ss->iops_data[ss->head];
+ else
+ ss->oldest_y = ss->bw_data[ss->head];
+
+ /*
+ * calculate slope as (sum_xy - sum_x * sum_y / n) / (sum_(x^2)
+ * - (sum_x)^2 / n) This code assumes that all x values are
+ * equally spaced when they are often off by a few milliseconds.
+ * This assumption greatly simplifies the calculations.
+ */
+ ss->slope = (ss->sum_xy - (double) ss->sum_x * ss->sum_y / ss->dur) /
+ (ss->sum_x_sq - (double) ss->sum_x * ss->sum_x / ss->dur);
+ if (ss->state & __FIO_SS_PCT)
+ ss->criterion = 100.0 * ss->slope / (ss->sum_y / ss->dur);
+ else
+ ss->criterion = ss->slope;
+
+ dprint(FD_STEADYSTATE, "sum_y: %llu, sum_xy: %llu, slope: %f, "
+ "criterion: %f, limit: %f\n",
+ (unsigned long long) ss->sum_y,
+ (unsigned long long) ss->sum_xy,
+ ss->slope, ss->criterion, ss->limit);
+
+ result = ss->criterion * (ss->criterion < 0.0 ? -1.0 : 1.0);
+ if (result < ss->limit)
+ return true;
+ }
+
+ ss->tail = (ss->tail + 1) % ss->dur;
+ if (ss->tail <= ss->head)
+ ss->head = (ss->head + 1) % ss->dur;
+
+ return false;
+}
+
+static bool steadystate_deviation(uint64_t iops, uint64_t bw,
+ struct thread_data *td)