steadystate: add free helper
[fio.git] / backend.c
index f003761deac2f989f563a2f2af6cfb3135138fe5..6c805c7f1e2b87cd23c6adb509de73d3698a2238 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -18,7 +18,7 @@
  *
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
  */
 #include <unistd.h>
@@ -499,7 +499,6 @@ int io_queue_event(struct thread_data *td, struct io_u *io_u, int *ret,
                        if (ddir_rw(io_u->ddir))
                                td->ts.short_io_u[io_u->ddir]++;
 
-                       f = io_u->file;
                        if (io_u->offset == f->real_file_size)
                                goto sync_done;
 
@@ -617,6 +616,19 @@ static bool in_flight_overlap(struct io_u_queue *q, struct io_u *io_u)
        return overlap;
 }
 
+static int io_u_submit(struct thread_data *td, struct io_u *io_u)
+{
+       /*
+        * Check for overlap if the user asked us to, and we have
+        * at least one IO in flight besides this one.
+        */
+       if (td->o.serialize_overlap && td->cur_depth > 1 &&
+           in_flight_overlap(&td->io_u_all, io_u))
+               return FIO_Q_BUSY;
+
+       return td_io_queue(td, io_u);
+}
+
 /*
  * The main verify engine. Runs over the writes we previously submitted,
  * reads the blocks back in, and checks the crc/md5 of the data.
@@ -747,13 +759,7 @@ static void do_verify(struct thread_data *td, uint64_t verify_bytes)
                if (!td->o.disable_slat)
                        fio_gettime(&io_u->start_time, NULL);
 
-               if (td->o.serialize_overlap && td->cur_depth > 0) {
-                       if (in_flight_overlap(&td->io_u_all, io_u))
-                               ret = FIO_Q_BUSY;
-                       else
-                               ret = td_io_queue(td, io_u);
-               } else
-                       ret = td_io_queue(td, io_u);
+               ret = io_u_submit(td, io_u);
 
                if (io_queue_event(td, io_u, &ret, ddir, NULL, 1, NULL))
                        break;
@@ -1020,13 +1026,7 @@ static void do_io(struct thread_data *td, uint64_t *bytes_done)
                                td->rate_next_io_time[ddir] = usec_for_io(td, ddir);
 
                } else {
-                       if (td->o.serialize_overlap && td->cur_depth > 0) {
-                               if (in_flight_overlap(&td->io_u_all, io_u))
-                                       ret = FIO_Q_BUSY;
-                               else
-                                       ret = td_io_queue(td, io_u);
-                       } else
-                               ret = td_io_queue(td, io_u);
+                       ret = io_u_submit(td, io_u);
 
                        if (should_check_rate(td))
                                td->rate_next_io_time[ddir] = usec_for_io(td, ddir);
@@ -1203,9 +1203,9 @@ static int init_io_u(struct thread_data *td)
                data_xfer = 0;
 
        err = 0;
-       err += io_u_rinit(&td->io_u_requeues, td->o.iodepth);
-       err += io_u_qinit(&td->io_u_freelist, td->o.iodepth);
-       err += io_u_qinit(&td->io_u_all, td->o.iodepth);
+       err += !io_u_rinit(&td->io_u_requeues, td->o.iodepth);
+       err += !io_u_qinit(&td->io_u_freelist, td->o.iodepth);
+       err += !io_u_qinit(&td->io_u_all, td->o.iodepth);
 
        if (err) {
                log_err("fio: failed setting up IO queues\n");
@@ -1390,6 +1390,8 @@ static bool keep_running(struct thread_data *td)
 
        if (td->done)
                return false;
+       if (td->terminate)
+               return false;
        if (td->o.time_based)
                return true;
        if (td->o.loops) {
@@ -1502,7 +1504,7 @@ static void *thread_main(void *data)
        struct sk_out *sk_out = fd->sk_out;
        uint64_t bytes_done[DDIR_RWDIR_CNT];
        int deadlock_loop_cnt;
-       int clear_state;
+       bool clear_state, did_some_io;
        int ret;
 
        sk_out_assign(sk_out);
@@ -1690,16 +1692,14 @@ static void *thread_main(void *data)
        if (td_io_init(td))
                goto err;
 
-       if (init_random_map(td))
+       if (!init_random_map(td))
                goto err;
 
        if (o->exec_prerun && exec_string(o, o->exec_prerun, (const char *)"prerun"))
                goto err;
 
-       if (o->pre_read) {
-               if (pre_read_files(td) < 0)
-                       goto err;
-       }
+       if (o->pre_read && !pre_read_files(td))
+               goto err;
 
        fio_verify_init(td);
 
@@ -1723,7 +1723,8 @@ static void *thread_main(void *data)
        }
 
        memset(bytes_done, 0, sizeof(bytes_done));
-       clear_state = 0;
+       clear_state = false;
+       did_some_io = false;
 
        while (keep_running(td)) {
                uint64_t verify_bytes;
@@ -1762,7 +1763,7 @@ static void *thread_main(void *data)
                if (td->runstate >= TD_EXITED)
                        break;
 
-               clear_state = 1;
+               clear_state = true;
 
                /*
                 * Make sure we've successfully updated the rusage stats
@@ -1801,6 +1802,9 @@ static void *thread_main(void *data)
                    td_ioengine_flagged(td, FIO_UNIDIR))
                        continue;
 
+               if (ddir_rw_sum(bytes_done))
+                       did_some_io = true;
+
                clear_io_state(td, 0);
 
                fio_gettime(&td->start, NULL);
@@ -1827,6 +1831,7 @@ static void *thread_main(void *data)
         * (Are we not missing other flags that can be ignored ?)
         */
        if ((td->o.size || td->o.io_size) && !ddir_rw_sum(bytes_done) &&
+           !did_some_io && !td->o.create_only &&
            !(td_ioengine_flagged(td, FIO_NOIO) ||
              td_ioengine_flagged(td, FIO_DISKLESSIO)))
                log_err("%s: No I/O performed by %s, "
@@ -1922,11 +1927,7 @@ static void reap_threads(unsigned int *nr_running, uint64_t *t_rate,
        for_each_td(td, i) {
                int flags = 0;
 
-               /*
-                * ->io_ops is NULL for a thread that has closed its
-                * io engine
-                */
-               if (td->io_ops && !strcmp(td->io_ops->name, "cpuio"))
+                if (!strcmp(td->o.ioengine, "cpuio"))
                        cputhreads++;
                else
                        realthreads++;
@@ -2041,7 +2042,10 @@ static bool __check_trigger_file(void)
 static bool trigger_timedout(void)
 {
        if (trigger_timeout)
-               return time_since_genesis() >= trigger_timeout;
+               if (time_since_genesis() >= trigger_timeout) {
+                       trigger_timeout = 0;
+                       return true;
+               }
 
        return false;
 }
@@ -2050,7 +2054,7 @@ void exec_trigger(const char *cmd)
 {
        int ret;
 
-       if (!cmd)
+       if (!cmd || cmd[0] == '\0')
                return;
 
        ret = system(cmd);
@@ -2314,6 +2318,7 @@ reap:
                                        nr_started--;
                                        break;
                                }
+                               fd = NULL;
                                ret = pthread_detach(td->thread);
                                if (ret)
                                        log_err("pthread_detach: %s",
@@ -2336,6 +2341,7 @@ reap:
                                fio_terminate_threads(TERMINATE_ALL);
                                fio_abort = 1;
                                nr_started--;
+                               free(fd);
                                break;
                        }
                        dprint(FD_MUTEX, "done waiting on startup_mutex\n");
@@ -2474,12 +2480,7 @@ int fio_backend(struct sk_out *sk_out)
        }
 
        for_each_td(td, i) {
-               if (td->ss.dur) {
-                       if (td->ss.iops_data != NULL) {
-                               free(td->ss.iops_data);
-                               free(td->ss.bw_data);
-                       }
-               }
+               steadystate_free(td);
                fio_options_free(td);
                if (td->rusage_sem) {
                        fio_mutex_remove(td->rusage_sem);