Merge branch 'master' of ssh://git.kernel.dk/data/git/blktrace
[blktrace.git] / btt / trace_queue.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 static inline void __update_q2c(struct io *q_iop, struct io *c_iop)
24 {
25         __u64 q2c = tdelta(q_iop, c_iop);
26
27         update_q2c(q_iop, q2c);
28         latency_q2c(q_iop->dip, q_iop->t.time, q2c);
29 }
30
31 void run_queue(struct io *q_iop, struct io *c_iop, struct list_head *rmhd)
32 {
33         struct bilink *blp;
34         struct io *a_iop = bilink_first_down(q_iop, &blp);
35
36         if (a_iop) {
37                 run_remap(a_iop, c_iop, rmhd);
38                 biunlink(blp);
39         }
40
41         __update_q2c(q_iop, c_iop);
42         dump_iop(q_iop, 0);
43
44         list_add_tail(&q_iop->f_head, rmhd);
45 }
46
47 int ready_queue(struct io *q_iop, struct io *c_iop)
48 {
49         struct io *a_iop;
50
51         if (!list_empty(&q_iop->down_list))
52                 return 1;
53
54         a_iop = dip_find_sec(q_iop->dip, IOP_A, BIT_START(q_iop));
55         if (!a_iop)
56                 return 1;
57
58         if (!ready_remap(a_iop, c_iop))
59                 return 0;
60
61         ASSERT(q_iop->t.bytes == a_iop->t.bytes);
62         bilink(a_iop, q_iop);
63         dip_rem(a_iop);
64         return 1;
65 }
66
67 void trace_queue(struct io *q_iop)
68 {
69         if (io_setup(q_iop, IOP_Q)) {
70                 update_lq(&last_q, &all_avgs.q2q, q_iop->t.time);
71                 update_qregion(&all_regions, q_iop->t.time);
72                 dip_update_q(q_iop->dip, q_iop);
73                 pip_update_q(q_iop);
74         }
75         else
76                 io_release(q_iop);
77 }