spelling and grammar fixes for btreplay.tex
[blktrace.git] / btt / inlines.h
CommitLineData
63eba147
JA
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 */
63eba147 21
ae6d30f4
AB
22static inline int remapper_dev(__u32 dev)
23{
24 int mjr = MAJOR(dev);
25 return mjr == 9 || mjr == 253 || mjr == 254;
26}
27
69040794 28static inline void region_init(struct region_info *reg)
63eba147 29{
69040794
AB
30 INIT_LIST_HEAD(&reg->qranges);
31 INIT_LIST_HEAD(&reg->cranges);
63eba147
JA
32}
33
69040794 34static inline void __region_exit(struct list_head *range_head)
63eba147 35{
69040794
AB
36 struct list_head *p, *q;
37 struct range_info *rip;
38
39 list_for_each_safe(p, q, range_head) {
40 rip = list_entry(p, struct range_info, head);
41 free(rip);
63eba147 42 }
69040794 43}
63eba147 44
69040794
AB
45static inline void region_exit(struct region_info *reg)
46{
47 __region_exit(&reg->qranges);
48 __region_exit(&reg->cranges);
63eba147
JA
49}
50
69040794 51static inline void update_range(struct list_head *head_p, __u64 time)
63eba147 52{
69040794
AB
53 struct range_info *rip;
54
55 if (!list_empty(head_p)) {
56 rip = list_entry(head_p->prev, struct range_info, head);
57
58 if (time < rip->end)
59 return;
60
61 if (BIT_TIME(time - rip->end) < range_delta) {
62 rip->end = time;
63 return;
64 }
65 }
66
67 rip = malloc(sizeof(*rip));
68 rip->start = rip->end = time;
69 list_add_tail(&rip->head, head_p);
63eba147
JA
70}
71
e71e4b78 72static inline void update_qregion(struct region_info *reg, __u64 time)
63eba147 73{
69040794 74 update_range(&reg->qranges, time);
63eba147
JA
75}
76
e71e4b78 77static inline void update_cregion(struct region_info *reg, __u64 time)
63eba147 78{
69040794 79 update_range(&reg->cranges, time);
63eba147
JA
80}
81
e71e4b78 82static inline void avg_update(struct avg_info *ap, __u64 t)
63eba147
JA
83{
84 if (ap->n++ == 0)
85 ap->min = ap->total = ap->max = t;
86 else {
87 if (t < ap->min)
88 ap->min = t;
89 else if (t > ap->max)
90 ap->max = t;
91 ap->total += t;
92 }
93}
94
d76c5b81
AB
95static inline void avg_update_n(struct avg_info *ap, __u64 t, int n)
96{
97 if (ap->n == 0) {
98 ap->min = ap->max = t;
99 ap->total = (n * t);
100 }
101 else {
102 if (t < ap->min)
103 ap->min = t;
104 else if (t > ap->max)
105 ap->max = t;
106 ap->total += (n * t);
107 }
108
109 ap->n += n;
110}
111
6eb42155
ADB
112static inline void avg_unupdate(struct avg_info *ap, __u64 t)
113{
114 ap->n--;
115 ap->total -= t;
116}
117
e71e4b78 118static inline void update_lq(__u64 *last_q, struct avg_info *avg, __u64 time)
63eba147
JA
119{
120 if (*last_q != ((__u64)-1))
095181f2 121 avg_update(avg, (time > *last_q) ? time - *last_q : 1);
63eba147
JA
122 *last_q = time;
123}
124
e71e4b78 125static inline void dip_update_q(struct d_info *dip, struct io *iop)
63eba147 126{
ae6d30f4
AB
127 if (remapper_dev(dip->device))
128 update_lq(&dip->last_q, &dip->avgs.q2q_dm, iop->t.time);
129 else
130 update_lq(&dip->last_q, &dip->avgs.q2q, iop->t.time);
63eba147
JA
131 update_qregion(&dip->regions, iop->t.time);
132}
133
6eb42155 134static inline struct io *io_alloc(void)
63eba147 135{
8b10aae0 136 struct io *iop = malloc(sizeof(*iop));
c8b0b334 137
095181f2 138 memset(iop, 0, sizeof(struct io));
8b10aae0 139 list_add_tail(&iop->a_head, &all_ios);
095181f2
JA
140
141 return iop;
63eba147
JA
142}
143
6eb42155 144static inline void io_free(struct io *iop)
63eba147 145{
8b10aae0
AB
146 list_del(&iop->a_head);
147 free(iop);
63eba147
JA
148}
149
69040794
AB
150static inline void io_free_all(void)
151{
152 struct io *iop;
153 struct list_head *p, *q;
154
8b10aae0
AB
155 list_for_each_safe(p, q, &all_ios) {
156 iop = list_entry(p, struct io, a_head);
69040794
AB
157 free(iop);
158 }
159}
160
095181f2 161static inline int io_setup(struct io *iop, enum iop_type type)
63eba147
JA
162{
163 iop->type = type;
095181f2
JA
164 iop->dip = dip_add(iop->t.device, iop);
165 if (iop->linked) {
166 iop->pip = find_process(iop->t.pid, NULL);
095181f2
JA
167 iop->bytes_left = iop->t.bytes;
168 }
169
170 return iop->linked;
63eba147
JA
171}
172
6eb42155 173static inline void io_release(struct io *iop)
63eba147 174{
095181f2 175 if (iop->linked)
6eb42155 176 dip_rem(iop);
8b10aae0 177 if (iop->pdu)
6eb42155 178 free(iop->pdu);
d76c5b81 179
6eb42155 180 io_free(iop);
63eba147
JA
181}
182
183#define UPDATE_AVGS(_avg, _iop, _pip, _time) do { \
184 avg_update(&all_avgs. _avg , _time); \
185 avg_update(&_iop->dip->avgs. _avg , _time); \
186 if (_pip) avg_update(&_pip->avgs. _avg , _time); \
187 } while (0)
188
d76c5b81
AB
189#define UPDATE_AVGS_N(_avg, _iop, _pip, _time, _n) do { \
190 avg_update_n(&all_avgs. _avg , _time, _n); \
191 avg_update_n(&_iop->dip->avgs. _avg , _time, _n); \
192 if (_pip) avg_update_n(&_pip->avgs. _avg , _time,_n); \
193 } while (0)
194
6eb42155
ADB
195#define UNUPDATE_AVGS(_avg, _iop, _pip, _time) do { \
196 avg_unupdate(&all_avgs. _avg , _time); \
197 avg_unupdate(&_iop->dip->avgs. _avg , _time); \
198 if (_pip) avg_unupdate(&_pip->avgs. _avg , _time); \
199 } while (0)
200
e71e4b78 201static inline void update_q2c(struct io *iop, __u64 c_time)
63eba147 202{
ae6d30f4
AB
203 if (remapper_dev(iop->dip->device))
204 UPDATE_AVGS(q2c_dm, iop, iop->pip, c_time);
205 else
206 UPDATE_AVGS(q2c, iop, iop->pip, c_time);
63eba147
JA
207}
208
e71e4b78 209static inline void update_q2a(struct io *iop, __u64 a_time)
63eba147 210{
ae6d30f4
AB
211 if (remapper_dev(iop->dip->device))
212 UPDATE_AVGS(q2a_dm, iop, iop->pip, a_time);
213 else
214 UPDATE_AVGS(q2a, iop, iop->pip, a_time);
215}
216
217static inline void update_q2g(struct io *iop, __u64 g_time)
218{
ae6d30f4
AB
219 UPDATE_AVGS(q2g, iop, iop->pip, g_time);
220}
221
354db430
AB
222static inline void update_s2g(struct io *iop, __u64 g_time)
223{
224 UPDATE_AVGS(s2g, iop, iop->pip, g_time);
225}
226
ae6d30f4
AB
227static inline void unupdate_q2g(struct io *iop, __u64 g_time)
228{
229 UNUPDATE_AVGS(q2g, iop, iop->pip, g_time);
230}
231
232static inline void update_g2i(struct io *iop, __u64 i_time)
233{
ae6d30f4
AB
234 UPDATE_AVGS(g2i, iop, iop->pip, i_time);
235}
236
237static inline void unupdate_g2i(struct io *iop, __u64 i_time)
238{
239 UNUPDATE_AVGS(g2i, iop, iop->pip, i_time);
63eba147
JA
240}
241
ae6d30f4 242static inline void update_q2m(struct io *iop, __u64 m_time)
63eba147 243{
ae6d30f4 244 UPDATE_AVGS(q2m, iop, iop->pip, m_time);
63eba147
JA
245}
246
ae6d30f4 247static inline void unupdate_q2m(struct io *iop, __u64 m_time)
d76c5b81 248{
ae6d30f4 249 UNUPDATE_AVGS(q2m, iop, iop->pip, m_time);
d76c5b81
AB
250}
251
e71e4b78 252static inline void update_i2d(struct io *iop, __u64 d_time)
63eba147
JA
253{
254 UPDATE_AVGS(i2d, iop, iop->pip, d_time);
255}
256
6eb42155
ADB
257static inline void unupdate_i2d(struct io *iop, __u64 d_time)
258{
259 UNUPDATE_AVGS(i2d, iop, iop->pip, d_time);
260}
261
ae6d30f4
AB
262static inline void update_m2d(struct io *iop, __u64 d_time)
263{
ae6d30f4
AB
264 UPDATE_AVGS(m2d, iop, iop->pip, d_time);
265}
266
267static inline void unupdate_m2d(struct io *iop, __u64 d_time)
268{
269 UNUPDATE_AVGS(m2d, iop, iop->pip, d_time);
270}
271
4c48f14e 272static inline void update_d2c(struct io *iop, __u64 c_time)
63eba147 273{
4c48f14e 274 UPDATE_AVGS(d2c, iop, iop->pip, c_time);
63eba147
JA
275}
276
e71e4b78 277static inline void update_blks(struct io *iop)
63eba147
JA
278{
279 __u64 nblks = iop->t.bytes >> 9;
280 avg_update(&all_avgs.blks, nblks);
281 avg_update(&iop->dip->avgs.blks, nblks);
282 if (iop->pip)
283 avg_update(&iop->pip->avgs.blks, nblks);
284}
6eb42155
ADB
285
286static inline struct rb_root *__get_root(struct d_info *dip, enum iop_type type)
287{
288 struct rb_root *roots = dip->heads;
289 return &roots[type];
290}
291
095181f2 292static inline int dip_rb_ins(struct d_info *dip, struct io *iop)
6eb42155 293{
095181f2 294 return rb_insert(__get_root(dip, iop->type), iop);
6eb42155
ADB
295}
296
297static inline void dip_rb_rem(struct io *iop)
298{
299 rb_erase(&iop->rb_node, __get_root(iop->dip, iop->type));
300}
301
8b10aae0
AB
302static inline void dip_rb_fe(struct d_info *dip, enum iop_type type,
303 struct io *iop,
304 void (*fnc)(struct io *iop, struct io *this),
6eb42155
ADB
305 struct list_head *head)
306{
307 rb_foreach(__get_root(dip, type)->rb_node, iop, fnc, head);
308}
309
8b10aae0 310static inline struct io *dip_rb_find_sec(struct d_info *dip,
6eb42155
ADB
311 enum iop_type type, __u64 sec)
312{
313 return rb_find_sec(__get_root(dip, type), sec);
314}
095181f2 315
4c48f14e 316static inline __u64 tdelta(__u64 from, __u64 to)
095181f2 317{
4c48f14e 318 return (from < to) ? (to - from) : 1;
095181f2 319}
d76c5b81 320
d76c5b81
AB
321static inline int type2c(enum iop_type type)
322{
323 int c;
324
325 switch (type) {
326 case IOP_Q: c = 'Q'; break;
327 case IOP_X: c = 'X'; break;
328 case IOP_A: c = 'A'; break;
329 case IOP_I: c = 'I'; break;
330 case IOP_M: c = 'M'; break;
331 case IOP_D: c = 'D'; break;
332 case IOP_C: c = 'C'; break;
333 case IOP_R: c = 'R'; break;
4c48f14e 334 case IOP_G: c = 'G'; break;
d76c5b81
AB
335 default : c = '?'; break;
336 }
337
338 return c;
339}
340
4c48f14e 341static inline int histo_idx(__u64 nbytes)
d76c5b81 342{
4c48f14e
AB
343 int idx = (nbytes >> 9) - 1;
344 return min(idx, N_HIST_BKTS-1);
d76c5b81
AB
345}
346
4c48f14e 347static inline void update_q_histo(__u64 nbytes)
d76c5b81 348{
4c48f14e 349 q_histo[histo_idx(nbytes)]++;
d76c5b81
AB
350}
351
4c48f14e 352static inline void update_d_histo(__u64 nbytes)
d76c5b81 353{
4c48f14e 354 d_histo[histo_idx(nbytes)]++;
d76c5b81
AB
355}
356
4c48f14e 357static inline struct io *io_first_list(struct list_head *head)
d76c5b81 358{
4c48f14e 359 if (list_empty(head))
d76c5b81 360 return NULL;
d76c5b81 361
4c48f14e 362 return list_entry(head->next, struct io, f_head);
d76c5b81
AB
363}
364
4c48f14e 365static inline void __dump_iop(FILE *ofp, struct io *iop, int extra_nl)
d76c5b81 366{
4c48f14e
AB
367 fprintf(ofp, "%5d.%09lu %3d,%-3d %c %10llu+%-4u\n",
368 (int)SECONDS(iop->t.time),
369 (unsigned long)NANO_SECONDS(iop->t.time),
370 MAJOR(iop->t.device), MINOR(iop->t.device), type2c(iop->type),
371 (unsigned long long)iop->t.sector, t_sec(&iop->t));
372 if (extra_nl) fprintf(ofp, "\n");
d76c5b81 373}
fa0ab85d 374
4c48f14e 375static inline void __dump_iop2(FILE *ofp, struct io *a_iop, struct io *l_iop)
fa0ab85d 376{
4c48f14e
AB
377 fprintf(ofp, "%5d.%09lu %3d,%-3d %c %10llu+%-4u <- (%3d,%-3d) %10llu\n",
378 (int)SECONDS(a_iop->t.time),
379 (unsigned long)NANO_SECONDS(a_iop->t.time),
8b10aae0
AB
380 MAJOR(a_iop->t.device), MINOR(a_iop->t.device),
381 type2c(a_iop->type), (unsigned long long)a_iop->t.sector,
382 t_sec(&a_iop->t), MAJOR(l_iop->t.device),
4c48f14e 383 MINOR(l_iop->t.device), (unsigned long long)l_iop->t.sector);
c8b0b334 384}