crc/test.c: fix include of time.h
[fio.git] / backend.c
index 5e7a388b9d5f2d5c43022485305ec3868231311a..e0f8aa76f584dc8f978c1f2649fae5292f563718 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -182,7 +182,11 @@ static int __check_min_rate(struct thread_data *td, struct timeval *now,
                                                                ratemin);
                                return 1;
                        } else {
-                               rate = ((bytes - td->rate_bytes[ddir]) * 1000) / spent;
+                               if (spent)
+                                       rate = ((bytes - td->rate_bytes[ddir]) * 1000) / spent;
+                               else
+                                       rate = 0;
+
                                if (rate < ratemin ||
                                    bytes < td->rate_bytes[ddir]) {
                                        log_err("%s: min rate %u not met, got"
@@ -200,7 +204,11 @@ static int __check_min_rate(struct thread_data *td, struct timeval *now,
                                                td->o.name, rate_iops);
                                return 1;
                        } else {
-                               rate = ((iops - td->rate_blocks[ddir]) * 1000) / spent;
+                               if (spent)
+                                       rate = ((iops - td->rate_blocks[ddir]) * 1000) / spent;
+                               else
+                                       rate = 0;
+
                                if (rate < rate_iops_min ||
                                    iops < td->rate_blocks[ddir]) {
                                        log_err("%s: min iops rate %u not met,"
@@ -637,7 +645,7 @@ static unsigned int exceeds_number_ios(struct thread_data *td)
 
 static int io_bytes_exceeded(struct thread_data *td)
 {
-       unsigned long long bytes;
+       unsigned long long bytes, limit;
 
        if (td_rw(td))
                bytes = td->this_io_bytes[DDIR_READ] + td->this_io_bytes[DDIR_WRITE];
@@ -648,7 +656,12 @@ static int io_bytes_exceeded(struct thread_data *td)
        else
                bytes = td->this_io_bytes[DDIR_TRIM];
 
-       return bytes >= td->o.size || exceeds_number_ios(td);
+       if (td->o.io_limit)
+               limit = td->o.io_limit;
+       else
+               limit = td->o.size;
+
+       return bytes >= limit || exceeds_number_ios(td);
 }
 
 /*
@@ -1110,12 +1123,14 @@ static int switch_ioscheduler(struct thread_data *td)
        /*
         * Read back and check that the selected scheduler is now the default.
         */
-       ret = fread(tmp, 1, sizeof(tmp), f);
+       ret = fread(tmp, sizeof(tmp), 1, f);
        if (ferror(f) || ret < 0) {
                td_verror(td, errno, "fread");
                fclose(f);
                return 1;
        }
+       tmp[sizeof(tmp) - 1] = '\0';
+
 
        sprintf(tmp2, "[%s]", td->o.ioscheduler);
        if (!strstr(tmp, tmp2)) {
@@ -1131,6 +1146,8 @@ static int switch_ioscheduler(struct thread_data *td)
 
 static int keep_running(struct thread_data *td)
 {
+       unsigned long long limit;
+
        if (td->done)
                return 0;
        if (td->o.time_based)
@@ -1142,14 +1159,19 @@ static int keep_running(struct thread_data *td)
        if (exceeds_number_ios(td))
                return 0;
 
-       if (td->o.size != -1ULL && ddir_rw_sum(td->io_bytes) < td->o.size) {
+       if (td->o.io_limit)
+               limit = td->o.io_limit;
+       else
+               limit = td->o.size;
+
+       if (limit != -1ULL && ddir_rw_sum(td->io_bytes) < limit) {
                uint64_t diff;
 
                /*
                 * If the difference is less than the minimum IO size, we
                 * are done.
                 */
-               diff = td->o.size - ddir_rw_sum(td->io_bytes);
+               diff = limit - ddir_rw_sum(td->io_bytes);
                if (diff < td_max_bs(td))
                        return 0;
 
@@ -1223,120 +1245,6 @@ static uint64_t do_dry_run(struct thread_data *td)
        return bytes_done[DDIR_WRITE] + bytes_done[DDIR_TRIM];
 }
 
-static int write_this_log(struct thread_data *td, struct io_log *log,
-                         const char *log_file, const char *name, int try)
-{
-       int ret;
-
-       if (!log)
-               return 0;
-
-       if (log_file)
-               ret = finish_log_named(td, log, log_file, name, try);
-       else
-               ret = finish_log(td, log, name, try);
-
-       return ret;
-}
-
-static int write_iops_log(struct thread_data *td, struct thread_options *o,
-                         int try)
-{
-       return write_this_log(td, td->iops_log, o->iops_log_file, "iops", try);
-}
-
-static int write_slat_log(struct thread_data *td, struct thread_options *o,
-                         int try)
-{
-       return write_this_log(td, td->slat_log, o->lat_log_file, "slat", try);
-}
-
-static int write_clat_log(struct thread_data *td, struct thread_options *o,
-                         int try)
-{
-       return write_this_log(td, td->clat_log, o->lat_log_file, "clat" , try);
-}
-
-static int write_lat_log(struct thread_data *td, struct thread_options *o,
-                        int try)
-{
-       return write_this_log(td, td->lat_log, o->lat_log_file, "lat", try);
-}
-
-static int write_bandw_log(struct thread_data *td, struct thread_options *o,
-                       int try)
-{
-       return write_this_log(td, td->bw_log, o->bw_log_file, "bw", try);
-}
-
-enum {
-       BW_LOG_MASK     = 1,
-       LAT_LOG_MASK    = 2,
-       SLAT_LOG_MASK   = 4,
-       CLAT_LOG_MASK   = 8,
-       IOPS_LOG_MASK   = 16,
-
-       ALL_LOG_MASK    = 31,
-       ALL_LOG_NR      = 5,
-};
-
-static void writeout_logs(struct thread_data *td)
-{
-       struct thread_options *o = &td->o;
-       unsigned int log_mask = ALL_LOG_MASK;
-       unsigned int log_left = ALL_LOG_NR;
-       int old_state;
-
-       old_state = td_bump_runstate(td, TD_FINISHING);
-
-       finalize_logs(td);
-
-       while (log_left) {
-               int ret, prev_log_left = log_left;
-
-               if (log_mask & BW_LOG_MASK) {
-                       ret = write_bandw_log(td, o, log_left != 1);
-                       if (!ret) {
-                               log_left--;
-                               log_mask &= ~BW_LOG_MASK;
-                       }
-               }
-               if (log_mask & LAT_LOG_MASK) {
-                       ret = write_lat_log(td, o, log_left != 1);
-                       if (!ret) {
-                               log_left--;
-                               log_mask &= ~LAT_LOG_MASK;
-                       }
-               }
-               if (log_mask & SLAT_LOG_MASK) {
-                       ret = write_slat_log(td, o, log_left != 1);
-                       if (!ret) {
-                               log_left--;
-                               log_mask &= ~SLAT_LOG_MASK;
-                       }
-               }
-               if (log_mask & CLAT_LOG_MASK) {
-                       ret = write_clat_log(td, o, log_left != 1);
-                       if (!ret) {
-                               log_left--;
-                               log_mask &= ~CLAT_LOG_MASK;
-                       }
-               }
-               if (log_mask & IOPS_LOG_MASK) {
-                       ret = write_iops_log(td, o, log_left != 1);
-                       if (!ret) {
-                               log_left--;
-                               log_mask &= ~IOPS_LOG_MASK;
-                       }
-               }
-
-               if (prev_log_left == log_left)
-                       usleep(5000);
-       }
-
-       td_restore_runstate(td, old_state);
-}
-
 /*
  * Entry point for the thread based jobs. The process based jobs end up
  * here as well, after a little setup.
@@ -1603,7 +1511,7 @@ static void *thread_main(void *data)
 
        fio_unpin_memory(td);
 
-       writeout_logs(td);
+       fio_writeout_logs(td);
 
        if (o->exec_postrun)
                exec_string(o, o->exec_postrun, (const char *)"postrun");