[PATCH] fio: more async fixes
authorJens Axboe <axboe@suse.de>
Fri, 21 Oct 2005 13:22:56 +0000 (15:22 +0200)
committerJens Axboe <axboe@suse.de>
Fri, 21 Oct 2005 13:22:56 +0000 (15:22 +0200)
- Attempt to cancel io on quit
- Catch SIGINT to display stats
- io_submit() EAGAIN fix

fio.c

diff --git a/fio.c b/fio.c
index 8ccf5ccca31839c2193d4a61686d8bba2a72d579..e2130c26257037fcb341a7327d57765ae1ea7929 100644 (file)
--- a/fio.c
+++ b/fio.c
@@ -481,13 +481,14 @@ static void aio_put_iocb(struct thread_data *td, struct iocb *iocb)
        long offset = ((long) iocb - (long) td->aio_iocbs)/ sizeof(struct iocb);
 
        td->aio_iocbs_status[offset] = 0;
+       td->aio_cur_depth--;
 }
 
 static struct iocb *aio_get_iocb(struct thread_data *td, char *buffer,
                                 struct timeval *t)
 {
        struct iocb *iocb = NULL;
-       int i;
+       unsigned int i;
 
        for (i = 0; i < td->aio_depth; i++) {
                if (td->aio_iocbs_status[i] == 0) {
@@ -512,6 +513,26 @@ static struct iocb *aio_get_iocb(struct thread_data *td, char *buffer,
        return iocb;
 }
 
+static int aio_submit(struct thread_data *td, struct iocb *iocb)
+{
+       int ret;
+
+       do {
+               ret = io_submit(*td->aio_ctx, 1, &iocb);
+               if (ret == 1)
+                       return 0;
+
+               if (errno == EINTR)
+                       continue;
+               else if (errno == EAGAIN)
+                       usleep(100);
+               else
+                       break;
+       } while (1);
+
+       return 1;
+}
+
 #define iocb_time(iocb)        ((unsigned long) (iocb)->data)
 
 static void do_async_io(struct thread_data *td)
@@ -544,8 +565,8 @@ static void do_async_io(struct thread_data *td)
 
                iocb = aio_get_iocb(td, buf, &s);
 
-               ret = io_submit(*td->aio_ctx, 1, &iocb);
-               if (ret < 0) {
+               ret = aio_submit(td, iocb);
+               if (ret) {
                        td->error = errno;
                        break;
                }
@@ -573,7 +594,6 @@ static void do_async_io(struct thread_data *td)
                        struct io_event *ev = td->aio_events + i;
 
                        td->io_blocks++;
-                       td->aio_cur_depth--;
 
                        iocb = ev->obj;
 
@@ -609,13 +629,41 @@ static void do_async_io(struct thread_data *td)
        free(ptr);
 }
 
-static void cleanup_aio(struct thread_data *td)
+static void cleanup_pending_aio(struct thread_data *td)
 {
+       struct timespec ts = { .tv_sec = 0, .tv_nsec = 0};
+       unsigned int i;
+       int r;
+
        /*
-        * flush pending events
+        * get immediately available events, if any
         */
+       r = io_getevents(*td->aio_ctx, 0, td->aio_cur_depth, td->aio_events, &ts);
+       if (r > 0) {
+               for (i = 0; i < r; i++)
+                       aio_put_iocb(td, &td->aio_iocbs[i]);
+       }
+
+       /*
+        * now cancel remaining active events
+        */
+       for (i = 0; i < td->aio_depth; i++) {
+               if (td->aio_iocbs_status[i] == 0)
+                       continue;
+
+               r = io_cancel(*td->aio_ctx, &td->aio_iocbs[i], td->aio_events);
+               if (!r)
+                       aio_put_iocb(td, &td->aio_iocbs[i]);
+       }
+
        if (td->aio_cur_depth)
                io_getevents(*td->aio_ctx, td->aio_cur_depth, td->aio_cur_depth, td->aio_events, NULL);
+}
+
+static void cleanup_aio(struct thread_data *td)
+{
+       if (td->aio_cur_depth)
+               cleanup_pending_aio(td);
 
        if (td->aio_ctx) {
                io_destroy(*td->aio_ctx);
@@ -1254,6 +1302,7 @@ static void run_threads(char *argv[])
 
        if (timeout) {
                signal(SIGALRM, sig_handler);
+               signal(SIGINT, sig_handler);
                alarm(timeout);
        }