Added in running stats for btt
[blktrace.git] / btt / devs.c
index 38007d1e50d67e3fa7bdff150605a1dec97b057c..2f1c6c065e840a98a9b39cbebf3d4601b5d96ec6 100644 (file)
@@ -52,50 +52,6 @@ static void __destroy_heads(struct rb_root *roots)
        free(roots);
 }
 
-#if defined(DEBUG)
-void __dump_rb_node(struct rb_node *n)
-{
-       struct io *iop = rb_entry(n, struct io, rb_node);
-
-       dbg_ping();
-       __dump_iop(stdout, iop, 0);
-       if (n->rb_left)
-               __dump_rb_node(n->rb_left);
-       if (n->rb_right)
-               __dump_rb_node(n->rb_right);
-}
-
-void __dump_rb_tree(struct d_info *dip, enum iop_type type)
-{
-       struct rb_root *roots = dip->heads;
-       struct rb_root *root = &roots[type];
-       struct rb_node *n = root->rb_node;
-
-       if (n) {
-               printf("\tIOP_%c\n", type2c(type));
-               __dump_rb_node(n);
-       }
-}
-
-void dump_rb_trees(void)
-{
-       int i;
-       enum iop_type type;
-       struct d_info *dip;
-       struct list_head *p;
-
-       for (i = 0; i < N_DEV_HASH; i++) {
-               __list_for_each(p, &dev_heads[i]) {
-                       dip = list_entry(p, struct d_info, hash_head);
-                       printf("Trees for %3d,%-3d\n", MAJOR(dip->device),
-                              MINOR(dip->device));
-                       for (type = IOP_Q; type < N_IOP_TYPES; type++)
-                               __dump_rb_tree(dip, type);
-               }
-       }
-}
-#endif
-
 void init_dev_heads(void)
 {
        int i;
@@ -117,23 +73,34 @@ struct d_info *__dip_find(__u32 device)
        return NULL;
 }
 
+void __dip_exit(struct d_info *dip)
+{
+       list_del(&dip->all_head);
+       __destroy_heads(dip->heads);
+       region_exit(&dip->regions);
+       seeki_free(dip->seek_handle);
+       seeki_free(dip->q2q_handle);
+       aqd_free(dip->aqd_handle);
+       plat_free(dip->q2d_plat_handle);
+       plat_free(dip->q2c_plat_handle);
+       plat_free(dip->d2c_plat_handle);
+       bno_dump_free(dip->bno_dump_handle);
+       unplug_hist_free(dip->up_hist_handle);
+       rstat_free(dip->rstat_handle);
+       if (output_all_data)
+               q2d_free(dip->q2d_priv);
+       if (dip->pit_fp)
+               fclose(dip->pit_fp);
+       free(dip);
+}
+
 void dip_exit(void)
 {
-       struct d_info *dip;
        struct list_head *p, *q;
 
        list_for_each_safe(p, q, &all_devs) {
-               dip = list_entry(p, struct d_info, all_head);
-
-               __destroy_heads(dip->heads);
-               region_exit(&dip->regions);
-               seeki_exit(dip->seek_handle);
-               seeki_exit(dip->q2q_handle);
-               bno_dump_exit(dip->bno_dump_handle);
-               unplug_hist_exit(dip->unplug_hist_handle);
-               if (output_all_data)
-                       q2d_release(dip->q2d_priv);
-               free(dip);
+               struct d_info *dip = list_entry(p, struct d_info, all_head);
+               __dip_exit(dip);
        }
 }
 
@@ -146,7 +113,17 @@ static inline char *mkhandle(char *str, __u32 device, char *post)
        return str;
 }
 
-struct d_info *dip_add(__u32 device, struct io *iop)
+static inline FILE *open_pit(char *str)
+{
+       FILE *fp = my_fopen(str, "w");
+
+       if (fp == NULL)
+               perror(str);
+
+       return fp;
+}
+
+struct d_info *dip_alloc(__u32 device, struct io *iop)
 {
        struct d_info *dip = __dip_find(device);
 
@@ -159,19 +136,30 @@ struct d_info *dip_add(__u32 device, struct io *iop)
                region_init(&dip->regions);
                dip->device = device;
                dip->last_q = (__u64)-1;
-               dip->map = dev_map_find(device);
-               dip->bno_dump_handle = bno_dump_init(device);
-               dip->unplug_hist_handle = unplug_hist_init(device);
-               dip->seek_handle = seeki_init(mkhandle(str, device, "_d2d"));
-               dip->q2q_handle = seeki_init(mkhandle(str, device, "_q2q"));
-               latency_init(dip);
+               dip->devmap = dev_map_find(device);
+               dip->bno_dump_handle = bno_dump_alloc(device);
+               dip->up_hist_handle = unplug_hist_alloc(device);
+               dip->seek_handle = seeki_alloc(mkhandle(str, device, "_d2d"));
+               dip->q2q_handle = seeki_alloc(mkhandle(str, device, "_q2q"));
+               dip->aqd_handle = aqd_alloc(mkhandle(str, device, "_aqd"));
+               dip->q2d_plat_handle =
+                               plat_alloc(mkhandle(str, device, "_q2d_plat"));
+               dip->q2c_plat_handle =
+                               plat_alloc(mkhandle(str, device, "_q2c_plat"));
+               dip->d2c_plat_handle =
+                               plat_alloc(mkhandle(str, device, "_d2c_plat"));
+               latency_alloc(dip);
                list_add_tail(&dip->hash_head, &dev_heads[DEV_HASH(device)]);
                list_add_tail(&dip->all_head, &all_devs);
                dip->start_time = BIT_TIME(iop->t.time);
                dip->pre_culling = 1;
+               dip->rstat_handle = rstat_alloc(mkhandle(str, device, ""));
                if (output_all_data)
-                       dip->q2d_priv = q2d_init();
+                       dip->q2d_priv = q2d_alloc();
                n_devs++;
+               if (per_io_trees)
+                       dip->pit_fp = open_pit(mkhandle(per_io_trees,
+                                                         device, "_pit.dat"));
        }
 
        if (dip->pre_culling) {
@@ -184,15 +172,10 @@ struct d_info *dip_add(__u32 device, struct io *iop)
        iop->linked = dip_rb_ins(dip, iop);
        dip->end_time = BIT_TIME(iop->t.time);
 
-#      if defined(DEBUG)
-               if (iop->linked) 
-                       rb_tree_size++;
-#      endif
-
        return dip;
 }
 
-void dip_rem(struct io *iop)
+void iop_rem_dip(struct io *iop)
 {
        if (iop->linked) {
                dip_rb_rem(iop);
@@ -200,7 +183,7 @@ void dip_rem(struct io *iop)
        }
 }
 
-void dip_foreach(struct io *iop, enum iop_type type, 
+void dip_foreach(struct io *iop, enum iop_type type,
                 void (*fnc)(struct io *iop, struct io *this), int rm_after)
 {
        if (rm_after) {
@@ -211,11 +194,10 @@ void dip_foreach(struct io *iop, enum iop_type type,
                dip_rb_fe(iop->dip, type, iop, fnc, &head);
                list_for_each_safe(p, q, &head) {
                        this = list_entry(p, struct io, f_head);
-                       LIST_DEL(&this->f_head);
+                       list_del(&this->f_head);
                        io_release(this);
                }
-       }
-       else
+       } else
                dip_rb_fe(iop->dip, type, iop, fnc, NULL);
 }
 
@@ -235,8 +217,7 @@ void dip_foreach_out(void (*func)(struct d_info *, void *), void *arg)
                struct list_head *p;
                __list_for_each(p, &all_devs)
                        func(list_entry(p, struct d_info, all_head), arg);
-       }
-       else {
+       } else {
                int i;
                struct d_info *dip;
                unsigned int mjr, mnr;
@@ -244,10 +225,7 @@ void dip_foreach_out(void (*func)(struct d_info *, void *), void *arg)
 
                while (p && ((i = sscanf(p, "%u,%u", &mjr, &mnr)) == 2)) {
                        dip = __dip_find((__u32)((mjr << MINORBITS) | mnr));
-                       ASSERT(dip);
-
                        func(dip, arg);
-
                        p = strchr(p, ';');
                        if (p) p++;
                }
@@ -258,10 +236,16 @@ void dip_plug(__u32 dev, double cur_time)
 {
        struct d_info *dip = __dip_find(dev);
 
-       if (!dip || dip->is_plugged) return;
+       if (dip && !dip->is_plugged) {
+               dip->is_plugged = 1;
+               dip->last_plug = cur_time;
+       }
+}
 
-       dip->is_plugged = 1;
-       dip->last_plug = cur_time;
+static inline void unplug(struct d_info *dip, double cur_time)
+{
+       dip->is_plugged = 0;
+       dip->plugged_time += (cur_time - dip->last_plug);
 }
 
 void dip_unplug(__u32 dev, double cur_time, __u64 nios_up)
@@ -270,19 +254,30 @@ void dip_unplug(__u32 dev, double cur_time, __u64 nios_up)
 
        if (dip && dip->is_plugged) {
                dip->nplugs++;
-               dip->plugged_time += (cur_time - dip->last_plug);
-               dip->is_plugged = 0;
                dip->nios_up += nios_up;
+               unplug(dip, cur_time);
        }
 }
 
-void dip_unplug_tm(__u32 dev, __u64 nios_up)
+void dip_unplug_tm(__u32 dev, double cur_time, __u64 nios_up)
 {
        struct d_info *dip = __dip_find(dev);
 
        if (dip && dip->is_plugged) {
-               dip->n_timer_unplugs++;
                dip->nios_upt += nios_up;
                dip->nplugs_t++;
+               unplug(dip, cur_time);
+       }
+}
+
+void dip_cleanup(void)
+{
+       struct list_head *p, *q;
+
+       list_for_each_safe(p, q, &all_devs) {
+               struct d_info *dip = list_entry(p, struct d_info, all_head);
+
+               if (dip->n_qs == 0 && dip->n_ds == 0)
+                       __dip_exit(dip);
        }
 }