Merge branch 'improvement/fix-warnings-if-NDEBUG-enabled' of https://github.com/dpron...
[fio.git] / backend.c
index 9ea688fb1f0ca9e7e67cc10479df6d3b9f68e25a..d67a4a07c57ca3582ac40ec461b9b3332a242142 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -93,19 +93,16 @@ static void sig_int(int sig)
 #ifdef WIN32
 static void sig_break(int sig)
 {
-       struct thread_data *td;
-       int i;
-
        sig_int(sig);
 
        /**
         * Windows terminates all job processes on SIGBREAK after the handler
         * returns, so give them time to wrap-up and give stats
         */
-       for_each_td(td, i) {
+       for_each_td(td) {
                while (td->runstate < TD_EXITED)
                        sleep(1);
-       }
+       } end_for_each();
 }
 #endif
 
@@ -857,6 +854,7 @@ static void handle_thinktime(struct thread_data *td, enum fio_ddir ddir,
                             struct timespec *time)
 {
        unsigned long long b;
+       unsigned long long runtime_left;
        uint64_t total;
        int left;
        struct timespec now;
@@ -865,7 +863,7 @@ static void handle_thinktime(struct thread_data *td, enum fio_ddir ddir,
        if (td->o.thinktime_iotime) {
                fio_gettime(&now, NULL);
                if (utime_since(&td->last_thinktime, &now)
-                   >= td->o.thinktime_iotime + td->o.thinktime) {
+                   >= td->o.thinktime_iotime) {
                        stall = true;
                } else if (!fio_option_is_set(&td->o, thinktime_blocks)) {
                        /*
@@ -888,11 +886,24 @@ static void handle_thinktime(struct thread_data *td, enum fio_ddir ddir,
 
        io_u_quiesce(td);
 
+       left = td->o.thinktime_spin;
+       if (td->o.timeout) {
+               runtime_left = td->o.timeout - utime_since_now(&td->epoch);
+               if (runtime_left < (unsigned long long)left)
+                       left = runtime_left;
+       }
+
        total = 0;
-       if (td->o.thinktime_spin)
-               total = usec_spin(td->o.thinktime_spin);
+       if (left)
+               total = usec_spin(left);
 
        left = td->o.thinktime - total;
+       if (td->o.timeout) {
+               runtime_left = td->o.timeout - utime_since_now(&td->epoch);
+               if (runtime_left < (unsigned long long)left)
+                       left = runtime_left;
+       }
+
        if (left)
                total += usec_sleep(td, left);
 
@@ -921,8 +932,10 @@ static void handle_thinktime(struct thread_data *td, enum fio_ddir ddir,
                fio_gettime(time, NULL);
 
        td->last_thinktime_blocks = b;
-       if (td->o.thinktime_iotime)
+       if (td->o.thinktime_iotime) {
+               fio_gettime(&now, NULL);
                td->last_thinktime = now;
+       }
 }
 
 /*
@@ -1024,8 +1037,11 @@ static void do_io(struct thread_data *td, uint64_t *bytes_done)
                }
 
                if (io_u->ddir == DDIR_WRITE && td->flags & TD_F_DO_VERIFY) {
-                       io_u->numberio = td->io_issues[io_u->ddir];
-                       populate_verify_io_u(td, io_u);
+                       if (!(io_u->flags & IO_U_F_PATTERN_DONE)) {
+                               io_u_set(td, io_u, IO_U_F_PATTERN_DONE);
+                               io_u->numberio = td->io_issues[io_u->ddir];
+                               populate_verify_io_u(td, io_u);
+                       }
                }
 
                ddir = io_u->ddir;
@@ -1324,7 +1340,7 @@ int init_io_u_buffers(struct thread_data *td)
         * overflow later. this adjustment may be too much if we get
         * lucky and the allocator gives us an aligned address.
         */
-       if (td->o.odirect || td->o.mem_align || td->o.oatomic ||
+       if (td->o.odirect || td->o.mem_align ||
            td_ioengine_flagged(td, FIO_RAWIO))
                td->orig_buffer_size += page_mask + td->o.mem_align;
 
@@ -1343,7 +1359,7 @@ int init_io_u_buffers(struct thread_data *td)
        if (data_xfer && allocate_io_mem(td))
                return 1;
 
-       if (td->o.odirect || td->o.mem_align || td->o.oatomic ||
+       if (td->o.odirect || td->o.mem_align ||
            td_ioengine_flagged(td, FIO_RAWIO))
                p = PTR_ALIGN(td->orig_buffer, page_mask) + td->o.mem_align;
        else
@@ -1617,7 +1633,7 @@ static void *thread_main(void *data)
        uint64_t bytes_done[DDIR_RWDIR_CNT];
        int deadlock_loop_cnt;
        bool clear_state;
-       int res, ret;
+       int ret;
 
        sk_out_assign(sk_out);
        free(fd);
@@ -1958,13 +1974,23 @@ static void *thread_main(void *data)
         * another thread is checking its io_u's for overlap
         */
        if (td_offload_overlap(td)) {
-               int res = pthread_mutex_lock(&overlap_check);
-               assert(res == 0);
+               int res;
+
+               res = pthread_mutex_lock(&overlap_check);
+               if (res) {
+                       td->error = errno;
+                       goto err;
+               }
        }
        td_set_runstate(td, TD_FINISHING);
        if (td_offload_overlap(td)) {
+               int res;
+
                res = pthread_mutex_unlock(&overlap_check);
-               assert(res == 0);
+               if (res) {
+                       td->error = errno;
+                       goto err;
+               }
        }
 
        update_rusage_stat(td);
@@ -2037,15 +2063,14 @@ err:
 static void reap_threads(unsigned int *nr_running, uint64_t *t_rate,
                         uint64_t *m_rate)
 {
-       struct thread_data *td;
        unsigned int cputhreads, realthreads, pending;
-       int i, status, ret;
+       int status, ret;
 
        /*
         * reap exited threads (TD_EXITED -> TD_REAPED)
         */
        realthreads = pending = cputhreads = 0;
-       for_each_td(td, i) {
+       for_each_td(td) {
                int flags = 0;
 
                if (!strcmp(td->o.ioengine, "cpuio"))
@@ -2138,7 +2163,7 @@ reaped:
                done_secs += mtime_since_now(&td->epoch) / 1000;
                profile_td_exit(td);
                flow_exit_job(td);
-       }
+       } end_for_each();
 
        if (*nr_running == cputhreads && !pending && realthreads)
                fio_terminate_threads(TERMINATE_ALL, TERMINATE_ALL);
@@ -2265,13 +2290,11 @@ static bool waitee_running(struct thread_data *me)
 {
        const char *waitee = me->o.wait_for;
        const char *self = me->o.name;
-       struct thread_data *td;
-       int i;
 
        if (!waitee)
                return false;
 
-       for_each_td(td, i) {
+       for_each_td(td) {
                if (!strcmp(td->o.name, self) || strcmp(td->o.name, waitee))
                        continue;
 
@@ -2281,7 +2304,7 @@ static bool waitee_running(struct thread_data *me)
                                        runstate_to_name(td->runstate));
                        return true;
                }
-       }
+       } end_for_each();
 
        dprint(FD_PROCESS, "%s: %s completed, can run\n", self, waitee);
        return false;
@@ -2305,14 +2328,14 @@ static void run_threads(struct sk_out *sk_out)
        set_sig_handlers();
 
        nr_thread = nr_process = 0;
-       for_each_td(td, i) {
+       for_each_td(td) {
                if (check_mount_writes(td))
                        return;
                if (td->o.use_thread)
                        nr_thread++;
                else
                        nr_process++;
-       }
+       } end_for_each();
 
        if (output_format & FIO_OUTPUT_NORMAL) {
                struct buf_output out;
@@ -2338,7 +2361,7 @@ static void run_threads(struct sk_out *sk_out)
        nr_started = 0;
        m_rate = t_rate = 0;
 
-       for_each_td(td, i) {
+       for_each_td(td) {
                print_status_init(td->thread_number - 1);
 
                if (!td->o.create_serialize)
@@ -2374,7 +2397,7 @@ reap:
                                        td_io_close_file(td, f);
                        }
                }
-       }
+       } end_for_each();
 
        /* start idle threads before io threads start to run */
        fio_idle_prof_start();
@@ -2390,7 +2413,7 @@ reap:
                /*
                 * create threads (TD_NOT_CREATED -> TD_CREATED)
                 */
-               for_each_td(td, i) {
+               for_each_td(td) {
                        if (td->runstate != TD_NOT_CREATED)
                                continue;
 
@@ -2469,7 +2492,7 @@ reap:
 
                                        ret = (int)(uintptr_t)thread_main(fd);
                                        _exit(ret);
-                               } else if (i == fio_debug_jobno)
+                               } else if (__td_index == fio_debug_jobno)
                                        *fio_debug_jobp = pid;
                                free(eo);
                                free(fd);
@@ -2485,7 +2508,7 @@ reap:
                                break;
                        }
                        dprint(FD_MUTEX, "done waiting on startup_sem\n");
-               }
+               } end_for_each();
 
                /*
                 * Wait for the started threads to transition to
@@ -2530,7 +2553,7 @@ reap:
                /*
                 * start created threads (TD_INITIALIZED -> TD_RUNNING).
                 */
-               for_each_td(td, i) {
+               for_each_td(td) {
                        if (td->runstate != TD_INITIALIZED)
                                continue;
 
@@ -2544,7 +2567,7 @@ reap:
                        t_rate += ddir_rw_sum(td->o.rate);
                        todo--;
                        fio_sem_up(td->sem);
-               }
+               } end_for_each();
 
                reap_threads(&nr_running, &t_rate, &m_rate);
 
@@ -2570,9 +2593,7 @@ static void free_disk_util(void)
 
 int fio_backend(struct sk_out *sk_out)
 {
-       struct thread_data *td;
        int i;
-
        if (exec_profile) {
                if (load_profile(exec_profile))
                        return 1;
@@ -2628,7 +2649,7 @@ int fio_backend(struct sk_out *sk_out)
                }
        }
 
-       for_each_td(td, i) {
+       for_each_td(td) {
                struct thread_stat *ts = &td->ts;
 
                free_clat_prio_stats(ts);
@@ -2641,7 +2662,7 @@ int fio_backend(struct sk_out *sk_out)
                }
                fio_sem_remove(td->sem);
                td->sem = NULL;
-       }
+       } end_for_each();
 
        free_disk_util();
        if (cgroup_list) {