2 * blktrace output analysis: generate a timeline & gather statistics
4 * Copyright (C) 2006 Alan D. Brunelle <Alan.Brunelle@hp.com>
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.
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.
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
26 struct rb_node rb_node;
34 struct rb_root root_pid, root_name;
36 static void __destroy(struct rb_node *n, int free_name, int free_pip)
39 struct pn_info *pnp = rb_entry(n, struct pn_info, rb_node);
41 __destroy(n->rb_left, free_name, free_pip);
42 __destroy(n->rb_right, free_name, free_pip);
44 if (free_name) free(pnp->u.name);
47 region_exit(&pnp->pip->regions);
54 struct p_info * __find_process_pid(__u32 pid)
57 struct rb_node *n = root_pid.rb_node;
60 this = rb_entry(n, struct pn_info, rb_node);
61 if (pid < this->u.pid)
63 else if (pid > this->u.pid)
72 struct p_info *__find_process_name(char *name)
76 struct rb_node *n = root_name.rb_node;
79 this = rb_entry(n, struct pn_info, rb_node);
80 cmp = strcmp(name, this->u.name);
92 struct p_info *find_process(__u32 pid, char *name)
96 if (pid != ((__u32)-1) && ((pip = __find_process_pid(pid)) != NULL))
100 return __find_process_name(name);
105 static void insert_pid(struct p_info *that)
107 struct pn_info *this;
108 struct rb_node *parent = NULL;
109 struct rb_node **p = &root_pid.rb_node;
113 this = rb_entry(parent, struct pn_info, rb_node);
115 if (that->pid < this->u.pid)
117 else if (that->pid > this->u.pid)
120 ASSERT(strcmp(that->name, this->pip->name) == 0);
121 return; // Already there
125 this = malloc(sizeof(struct pn_info));
126 this->u.pid = that->pid;
129 rb_link_node(&this->rb_node, parent, p);
130 rb_insert_color(&this->rb_node, &root_pid);
133 static void insert_name(struct p_info *that)
136 struct pn_info *this;
137 struct rb_node *parent = NULL;
138 struct rb_node **p = &root_name.rb_node;
142 this = rb_entry(parent, struct pn_info, rb_node);
143 cmp = strcmp(that->name, this->u.name);
150 return; // Already there...
153 this = malloc(sizeof(struct pn_info));
154 this->u.name = strdup(that->name);
157 rb_link_node(&this->rb_node, parent, p);
158 rb_insert_color(&this->rb_node, &root_name);
161 static void insert(struct p_info *pip)
167 void add_process(__u32 pid, char *name)
169 struct p_info *pip = find_process(pid, name);
172 pip = memset(malloc(sizeof(*pip)), 0, sizeof(*pip));
174 region_init(&pip->regions);
175 pip->last_q = (__u64)-1;
176 pip->name = strdup(name);
182 void pip_update_q(struct io *iop)
185 update_lq(&iop->pip->last_q, &iop->pip->avgs.q2q, iop->t.time);
186 update_qregion(&iop->pip->regions, iop->t.time);
190 void __foreach(struct rb_node *n, void (*f)(struct p_info *, void *), void *arg)
193 __foreach(n->rb_left, f, arg);
194 f(rb_entry(n, struct pn_info, rb_node)->pip, arg);
195 __foreach(n->rb_right, f, arg);
199 void pip_foreach_out(void (*f)(struct p_info *, void *), void *arg)
202 __foreach(root_name.rb_node, f, arg);
205 char *exe, *p, *next, *exes_save = strdup(exes);
208 while (exes_save != NULL) {
210 if ((next = strchr(exes_save, ',')) != NULL) {
217 pip = __find_process_name(exe);
226 __destroy(root_pid.rb_node, 0, 0);
227 __destroy(root_name.rb_node, 1, 1);