stats: Add a function to report completion latency percentiles
[fio.git] / fio.c
diff --git a/fio.c b/fio.c
index 81854818d6bd81ae3cd503a8eb4e4661d99bfc93..73964214d3468d93a4f0ed72f4ecbd330f57b9c6 100644 (file)
--- a/fio.c
+++ b/fio.c
@@ -102,7 +102,9 @@ static void terminate_threads(int group_id)
                        /*
                         * if the thread is running, just let it exit
                         */
-                       if (td->runstate < TD_RAMP)
+                       if (!td->pid)
+                               continue;
+                       else if (td->runstate < TD_RAMP)
                                kill(td->pid, SIGTERM);
                        else {
                                struct ioengine_ops *ops = td->io_ops;
@@ -548,13 +550,14 @@ sync_done:
 
                /*
                 * if we can queue more, do so. but check if there are
-                * completed io_u's first.
+                * completed io_u's first. Note that we can get BUSY even
+                * without IO queued, if the system is resource starved.
                 */
-               full = queue_full(td) || ret == FIO_Q_BUSY;
+               full = queue_full(td) || (ret == FIO_Q_BUSY && td->cur_depth);
                if (full || !td->o.iodepth_batch_complete) {
                        min_events = min(td->o.iodepth_batch_complete,
                                         td->cur_depth);
-                       if (full && !min_events)
+                       if (full && !min_events && td->o.iodepth_batch_complete != 0)
                                min_events = 1;
 
                        do {
@@ -708,13 +711,15 @@ sync_done:
                        break;
 
                /*
-                * See if we need to complete some commands
+                * See if we need to complete some commands. Note that we
+                * can get BUSY even without IO queued, if the system is
+                * resource starved.
                 */
-               full = queue_full(td) || ret == FIO_Q_BUSY;
+               full = queue_full(td) || (ret == FIO_Q_BUSY && td->cur_depth);
                if (full || !td->o.iodepth_batch_complete) {
                        min_evts = min(td->o.iodepth_batch_complete,
                                        td->cur_depth);
-                       if (full && !min_evts)
+                       if (full && !min_evts && td->o.iodepth_batch_complete != 0)
                                min_evts = 1;
 
                        if (__should_check_rate(td, 0) ||
@@ -1045,10 +1050,11 @@ static void *thread_main(void *data)
        pthread_condattr_t attr;
        int clear_state;
 
-       if (!td->o.use_thread)
+       if (!td->o.use_thread) {
                setsid();
-
-       td->pid = getpid();
+               td->pid = getpid();
+       } else
+               td->pid = gettid();
 
        dprint(FD_PROCESS, "jobs pid=%d started\n", (int) td->pid);
 
@@ -1294,6 +1300,7 @@ static int fork_main(int shmid, int offset)
        struct thread_data *td;
        void *data, *ret;
 
+#ifndef __hpux
        data = shmat(shmid, NULL, 0);
        if (data == (void *) -1) {
                int __err = errno;
@@ -1301,6 +1308,12 @@ static int fork_main(int shmid, int offset)
                perror("shmat");
                return __err;
        }
+#else
+       /*
+        * HP-UX inherits shm mappings?
+        */
+       data = threads;
+#endif
 
        td = data + offset * sizeof(struct thread_data);
        ret = thread_main(td);