Added in running stats for btt
[blktrace.git] / btt / trace_complete.c
index d8e7b5a9541442e136272386f194c7bdb6dcaf22..d34fbd0caa8ad04e5984ec0c672a868698ee46f9 100644 (file)
  */
 #include "globals.h"
 
-LIST_HEAD(pending_cs);
-
-static void gen_c_list(struct io *c_iop, struct list_head *c_head)
+static inline void __out(FILE *ofp, __u64 tm, enum iop_type type,
+                                       __u64 sec, __u32 nsec, int indent)
 {
-       struct io *iop;
-       struct list_head *p;
-
-       __list_for_each(p, &pending_cs) {
-               iop = list_entry(p, struct io, c_pending);
-               if (iop->t.device == c_iop->t.device)
-                       continue;
-               if (dip_find_sec(iop->dip, IOP_D, BIT_START(iop)) == NULL)
-                       continue;
-
-               __link(iop, c_iop);
-               if (ready_complete(iop, c_iop))
-                       list_add_tail(&iop->f_head, c_head);
-               __unlink(iop, c_iop);
+       if (tm != (__u64)-1) {
+               if (indent)
+                       fprintf(ofp, "         ");
+               fprintf(ofp, "%5d.%09lu %c %10llu+%-4u\n",
+                       (int)SECONDS(tm), (unsigned long)NANO_SECONDS(tm),
+                       type2c(type), (unsigned long long)sec, nsec);
        }
 }
 
-static void run_comp(struct io *c_iop, struct io *top, struct list_head *rmhd)
+static void display_io_track(FILE *ofp, struct io *iop)
 {
-       struct io *d_iop = dip_find_sec(c_iop->dip, IOP_D, BIT_START(c_iop));
-
-       update_blks(c_iop);
-       if (d_iop) {
-               __u64 d2c = tdelta(d_iop, c_iop);
-
-               update_d2c(d_iop, d2c);
-               latency_d2c(d_iop->dip, c_iop->t.time, d2c);
-               iostat_complete(d_iop, c_iop);
-
-               __link(d_iop, c_iop);
-               run_issue(d_iop, top, rmhd);
-               __unlink(d_iop, c_iop);
-       }
-       else {
-               LIST_HEAD(head);
-               struct io *iop;
-               struct list_head *p, *q;
-
-               gen_c_list(c_iop, &head);
-               list_for_each_safe(p, q, &head) {
-                       iop = list_entry(p, struct io, f_head);
-                       LIST_DEL(&iop->f_head);
-
-                       dump_level++;
-                       __link(iop, c_iop);
-                       run_comp(iop, top, rmhd);
-                       __unlink(iop, c_iop);
-                       dump_level--;
-               }
-       }
-       dump_iop(per_io_ofp, c_iop, NULL, 0);
-       LIST_DEL(&c_iop->c_pending);
-       list_add_tail(&c_iop->f_head, rmhd);
+       fprintf(ofp, "%3d,%-3d: ", MAJOR(iop->t.device), MINOR(iop->t.device));
+       __out(ofp, iop->t.time, IOP_Q, iop->t.sector, t_sec(&iop->t), 0);
+
+       if (iop->g_time != (__u64)-1)
+               __out(ofp, iop->g_time, IOP_G, iop->t.sector, t_sec(&iop->t),1);
+       if (iop->i_time != (__u64)-1)
+               __out(ofp, iop->i_time, IOP_I, iop->t.sector, t_sec(&iop->t),1);
+       if (iop->m_time != (__u64)-1)
+               __out(ofp, iop->m_time, IOP_M, iop->t.sector, t_sec(&iop->t),1);
+
+       __out(ofp, iop->d_time, IOP_D, iop->d_sec, iop->d_nsec, 1);
+       __out(ofp, iop->c_time, IOP_C, iop->c_sec, iop->c_nsec, 1);
+       fprintf(ofp, "\n");
 }
 
-static int ready_comp(struct io *c_iop, 
-                               __attribute__((__unused__)) struct io *top)
+static void handle_complete(struct io *c_iop)
 {
        LIST_HEAD(head);
-       struct io *iop;
        struct list_head *p, *q;
-       __u64 bl = c_iop->bytes_left;
+       __u64 d_time = (__u64)-1;
+       FILE *pit_fp = c_iop->dip->pit_fp;
+       double cur = BIT_TIME(c_iop->t.time);
 
-       gen_c_list(c_iop, &head);
+       update_blks(c_iop);
+       update_cregion(&all_regions, c_iop->t.time);
+       update_cregion(&c_iop->dip->regions, c_iop->t.time);
+       if (c_iop->pip)
+               update_cregion(&c_iop->pip->regions, c_iop->t.time);
+       aqd_complete(c_iop->dip->aqd_handle, cur);
+       rstat_add(c_iop->dip->rstat_handle, cur, c_iop->t.bytes >> 9);
+
+       dip_foreach_list(c_iop, IOP_Q, &head);
        list_for_each_safe(p, q, &head) {
-               iop = list_entry(p, struct io, f_head);
-               LIST_DEL(&iop->f_head);
+               struct io *q_iop = list_entry(p, struct io, f_head);
+               __u64 q2c = tdelta(q_iop->t.time, c_iop->t.time);
 
-               __link(iop, c_iop);
-               if (ready_complete(iop, c_iop))
-                       bl -= iop->bytes_left;
-               __unlink(iop, c_iop);
-       }
+               c_iop->bytes_left -= q_iop->t.bytes;
 
-       return bl == 0;
-}
+               update_q2c(q_iop, q2c);
+               latency_q2c(q_iop->dip, q_iop->t.time, q2c);
 
-void trace_complete(struct io *c_iop)
-{
-       if (!io_setup(c_iop, IOP_C)) {
-               io_release(c_iop);
-               return;
-       }
+               if (q_iop->d_time != (__u64)-1) {
+                       __u64 d2c = tdelta(q_iop->d_time, c_iop->t.time);
 
-       list_add_tail(&c_iop->c_pending, &pending_cs);
-       if (ready_complete(c_iop, c_iop)) {
-               dump_level = 0;
-               run_complete(c_iop);
-       }
-       else 
-               add_retry(c_iop);
-}
+                       update_d2c(q_iop, d2c);
+                       latency_d2c(q_iop->dip, c_iop->t.time, d2c);
+                       iostat_complete(q_iop, c_iop);
 
-int retry_complete(struct io *c_iop)
-{
-       if (!ready_complete(c_iop, c_iop))
-               return 0;
+                       d_time = q_iop->d_time;
+               }
 
-       del_retry(c_iop);
-       run_complete(c_iop);
-       return 1;
-}
+               if (per_io_ofp) {
+                       q_iop->c_time = c_iop->t.time;
+                       q_iop->c_sec = c_iop->t.sector;
+                       q_iop->c_nsec = t_sec(&c_iop->t);
+                       display_io_track(per_io_ofp, q_iop);
+               }
 
-int ready_complete(struct io *c_iop, struct io *top)
-{
-       struct io *d_iop = dip_find_sec(c_iop->dip, IOP_D, BIT_START(c_iop));
+               if (q_iop->dip->pit_fp) {
+                       fprintf(pit_fp, "%d.%09lu ",
+                               (int)SECONDS(q_iop->t.time),
+                               (unsigned long)NANO_SECONDS(q_iop->t.time));
+               }
 
-       if (d_iop) {
-               ASSERT(d_iop->t.bytes == c_iop->bytes_left);
-               return ready_issue(d_iop, top);
+               list_del(&q_iop->f_head);
+               io_release(q_iop);
+       }
+
+       if (per_io_ofp)
+               fprintf(per_io_ofp,
+                       "-----------------------------------------\n");
+
+       if (c_iop->dip->pit_fp) {
+               fprintf(pit_fp, "| %d.%09lu | %d.%09lu\n",
+                       (int)SECONDS(d_time),
+                       (unsigned long)NANO_SECONDS(d_time),
+                       (int)SECONDS(c_iop->t.time),
+                       (unsigned long)NANO_SECONDS(c_iop->t.time));
        }
-       else 
-               return ready_comp(c_iop, top);
 }
 
-void run_complete(struct io *c_iop)
+void trace_complete(struct io *c_iop)
 {
-       LIST_HEAD(rmhd);
+       if (c_iop->t.bytes == 0)
+               return;
 
-       update_cregion(&all_regions, c_iop->t.time);
-       update_cregion(&c_iop->dip->regions, c_iop->t.time);
-       if (c_iop->pip)
-               update_cregion(&c_iop->pip->regions, c_iop->t.time);
+       if (io_setup(c_iop, IOP_C))
+               handle_complete(c_iop);
 
-       run_comp(c_iop, c_iop, &rmhd);
-       if (per_io_ofp) fprintf(per_io_ofp, "\n");
-       release_iops(&rmhd);
+       io_release(c_iop);
 }