[PATCH] Add for_each_td()
[fio.git] / fio.c
diff --git a/fio.c b/fio.c
index 2b760ddd4beb0c56244637a626284b6faa47d9f8..624c9598cf0a3cd7eb84753a40d609850248b0de 100644 (file)
--- a/fio.c
+++ b/fio.c
@@ -56,11 +56,10 @@ static volatile int startup_sem;
 
 static void terminate_threads(int group_id)
 {
+       struct thread_data *td;
        int i;
 
-       for (i = 0; i < thread_number; i++) {
-               struct thread_data *td = &threads[i];
-
+       for_each_td(td, i) {
                if (group_id == TERMINATE_ALL || groupid == td->groupid) {
                        td->terminate = 1;
                        td->start_delay = 0;
@@ -277,7 +276,7 @@ static int get_rw_ddir(struct thread_data *td)
                 * Check if it's time to seed a new data direction.
                 */
                if (elapsed >= td->rwmixcycle) {
-                       int v;
+                       unsigned int v;
                        long r;
 
                        r = os_random_long(&td->rwmix_state);
@@ -422,7 +421,7 @@ static inline void td_set_runstate(struct thread_data *td, int runstate)
 
 static struct fio_file *get_next_file(struct thread_data *td)
 {
-       int old_next_file = td->next_file;
+       unsigned int old_next_file = td->next_file;
        struct fio_file *f;
 
        do {
@@ -563,7 +562,16 @@ void do_verify(struct thread_data *td)
        struct io_u *io_u, *v_io_u = NULL;
        struct io_completion_data icd;
        struct fio_file *f;
-       int ret;
+       int ret, i;
+
+       /*
+        * sync io first and invalidate cache, to make sure we really
+        * read from disk.
+        */
+       for_each_file(td, f, i) {
+               td_io_sync(td, f);
+               file_invalidate_cache(td, f);
+       }
 
        td_set_runstate(td, TD_VERIFYING);
 
@@ -679,14 +687,14 @@ static void do_io(struct thread_data *td)
        struct timeval s, e;
        unsigned long usec;
        struct fio_file *f;
-       int i;
+       int i, ret = 0;
 
        td_set_runstate(td, TD_RUNNING);
 
        while (td->this_io_bytes[td->ddir] < td->io_size) {
                struct timespec ts = { .tv_sec = 0, .tv_nsec = 0};
                struct timespec *timeout;
-               int ret, min_evts = 0;
+               int min_evts = 0;
                struct io_u *io_u;
 
                if (td->terminate)
@@ -719,9 +727,10 @@ static void do_io(struct thread_data *td)
                        min_evts = 1;
                }
 
+
                ret = td_io_getevents(td, min_evts, td->cur_depth, timeout);
                if (ret < 0) {
-                       td_verror(td, ret);
+                       td_verror(td, -ret);
                        break;
                } else if (!ret)
                        continue;
@@ -759,13 +768,15 @@ static void do_io(struct thread_data *td)
                        td_io_sync(td, f);
        }
 
-       if (td->cur_depth)
-               cleanup_pending_aio(td);
+       if (!ret) {
+               if (td->cur_depth)
+                       cleanup_pending_aio(td);
 
-       if (should_fsync(td) && td->end_fsync) {
-               td_set_runstate(td, TD_FSYNCING);
-               for_each_file(td, f, i)
-                       td_io_sync(td, f);
+               if (should_fsync(td) && td->end_fsync) {
+                       td_set_runstate(td, TD_FSYNCING);
+                       for_each_file(td, f, i)
+                               td_io_sync(td, f);
+               }
        }
 }
 
@@ -1078,15 +1089,19 @@ static void *fork_main(int shmid, int offset)
  */
 static void reap_threads(int *nr_running, int *t_rate, int *m_rate)
 {
+       struct thread_data *td;
        int i, cputhreads;
 
        /*
         * reap exited threads (TD_EXITED -> TD_REAPED)
         */
-       for (i = 0, cputhreads = 0; i < thread_number; i++) {
-               struct thread_data *td = &threads[i];
-
-               if (td->io_ops->flags & FIO_CPUIO)
+       cputhreads = 0;
+       for_each_td(td, i) {
+               /*
+                * ->io_ops is NULL for a thread that has closed its
+                * io engine
+                */
+               if (td->io_ops && td->io_ops->flags & FIO_CPUIO)
                        cputhreads++;
 
                if (td->runstate != TD_EXITED)
@@ -1178,9 +1193,7 @@ static void run_threads(void)
        nr_started = 0;
        m_rate = t_rate = 0;
 
-       for (i = 0; i < thread_number; i++) {
-               td = &threads[i];
-
+       for_each_td(td, i) {
                print_status_init(td->thread_number - 1);
 
                init_disk_util(td);
@@ -1209,9 +1222,7 @@ static void run_threads(void)
                /*
                 * create threads (TD_NOT_CREATED -> TD_CREATED)
                 */
-               for (i = 0; i < thread_number; i++) {
-                       td = &threads[i];
-
+               for_each_td(td, i) {
                        if (td->runstate != TD_NOT_CREATED)
                                continue;
 
@@ -1300,9 +1311,7 @@ static void run_threads(void)
                /*
                 * start created threads (TD_INITIALIZED -> TD_RUNNING).
                 */
-               for (i = 0; i < thread_number; i++) {
-                       td = &threads[i];
-
+               for_each_td(td, i) {
                        if (td->runstate != TD_INITIALIZED)
                                continue;