Always output seeks averages, even if we are not tracking all ios
[blktrace.git] / btt / trace_issue.c
1 /*
2  * blktrace output analysis: generate a timeline & gather statistics
3  *
4  * Copyright (C) 2006 Alan D. Brunelle <Alan.Brunelle@hp.com>
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21 #include "globals.h"
22
23 struct params {
24         struct io *c_iop;
25         struct list_head *rmhd;
26 };
27
28 void __run_issue(struct io *im_iop, struct io *d_iop, void *param)
29 {
30         struct params *p = param;
31
32         update_i2d(im_iop, tdelta(im_iop, d_iop));
33         run_im(im_iop, p->c_iop, p->rmhd);
34         dump_iop(d_iop, 0);
35         list_add_tail(&d_iop->f_head, p->rmhd);
36 }
37
38 void __run_unissue(struct io *im_iop, struct io *d_iop, void *param)
39 {
40         struct params *p = param;
41
42         unupdate_i2d(im_iop, tdelta(im_iop, d_iop));
43         run_unim(im_iop, p->rmhd);
44         list_add_tail(&d_iop->f_head, p->rmhd);
45 }
46
47 void run_issue(struct io *d_iop, struct io *c_iop, void *param)
48 {
49         struct params p = {
50                 .c_iop = c_iop,
51                 .rmhd = (struct list_head *)param
52         };
53         bilink_for_each_down(__run_issue, d_iop, &p, 1);
54 }
55
56 void run_unissue(struct io *d_iop, struct list_head *rmhd)
57 {
58         struct params p = {
59                 .c_iop = NULL,
60                 .rmhd = rmhd
61         };
62         bilink_for_each_down(__run_unissue, d_iop, &p, 1);
63 }
64
65 int ready_issue(struct io *d_iop, struct io *c_iop)
66 {
67         if (d_iop->bytes_left > 0) {
68                 LIST_HEAD(head);
69                 struct io *im_iop;
70                 struct list_head *p, *q;
71
72                 dip_foreach_list(d_iop, IOP_I, &head);
73                 dip_foreach_list(d_iop, IOP_M, &head);
74                 list_for_each_safe(p, q, &head) {
75                         im_iop = list_entry(p, struct io, f_head);
76                         LIST_DEL(&im_iop->f_head);
77
78                         if (ready_im(im_iop, c_iop)) {
79                                 ASSERT(d_iop->bytes_left >= im_iop->t.bytes);
80                                 bilink(im_iop, d_iop);
81                                 dip_rem(im_iop);
82                                 d_iop->bytes_left -= im_iop->t.bytes;
83                         }
84                 }
85         }
86
87         return d_iop->bytes_left == 0;
88 }
89
90 void trace_issue(struct io *d_iop)
91 {
92         if (io_setup(d_iop, IOP_D)) {
93                 seeki_add(d_iop->dip->seek_handle, d_iop);
94                 iostat_issue(d_iop);
95                 d_iop->dip->n_ds++;
96         }
97         else
98                 io_release(d_iop);
99
100 }