1e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 2e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * blktrace output analysis: generate a timeline & gather statistics 3e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 4e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Copyright (C) 2006 Alan D. Brunelle <Alan.Brunelle@hp.com> 5e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 6e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * This program is free software; you can redistribute it and/or modify 7e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * it under the terms of the GNU General Public License as published by 8e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * the Free Software Foundation; either version 2 of the License, or 9e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * (at your option) any later version. 10e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 11e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * This program is distributed in the hope that it will be useful, 12e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * but WITHOUT ANY WARRANTY; without even the implied warranty of 13e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * GNU General Public License for more details. 15e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 16e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * You should have received a copy of the GNU General Public License 17e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * along with this program; if not, write to the Free Software 18e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 20e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 21e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <string.h> 22e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 23e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include "globals.h" 24e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 25e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct pn_info { 26e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct rb_node rb_node; 27e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct p_info *pip; 28e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat union { 29e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char *name; 30e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __u32 pid; 31e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } u; 32e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}; 33e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 34e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct rb_root root_pid, root_name; 35e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 36e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void __foreach(struct rb_node *n, void (*f)(struct p_info *, void *), 37e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat void *arg) 38e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 39e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (n) { 40e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __foreach(n->rb_left, f, arg); 41e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat f(rb_entry(n, struct pn_info, rb_node)->pip, arg); 42e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __foreach(n->rb_right, f, arg); 43e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 44e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 45e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 46e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void __destroy(struct rb_node *n, int free_name, int free_pip) 47e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 48e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (n) { 49e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct pn_info *pnp = rb_entry(n, struct pn_info, rb_node); 50e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 51e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __destroy(n->rb_left, free_name, free_pip); 52e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __destroy(n->rb_right, free_name, free_pip); 53e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 54e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (free_name) 55e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat free(pnp->u.name); 56e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (free_pip) { 57e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat free(pnp->pip->name); 58e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat region_exit(&pnp->pip->regions); 59e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat free(pnp->pip); 60e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 61e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat free(pnp); 62e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 63e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 64e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 65e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct p_info * __find_process_pid(__u32 pid) 66e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 67e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct pn_info *this; 68e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct rb_node *n = root_pid.rb_node; 69e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 70e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (n) { 71e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat this = rb_entry(n, struct pn_info, rb_node); 72e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (pid < this->u.pid) 73e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat n = n->rb_left; 74e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else if (pid > this->u.pid) 75e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat n = n->rb_right; 76e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else 77e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return this->pip; 78e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 79e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 80e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return NULL; 81e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 82e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 83e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct p_info *__find_process_name(char *name) 84e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 85e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int cmp; 86e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct pn_info *this; 87e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct rb_node *n = root_name.rb_node; 88e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 89e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (n) { 90e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat this = rb_entry(n, struct pn_info, rb_node); 91e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat cmp = strcmp(name, this->u.name); 92e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (cmp < 0) 93e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat n = n->rb_left; 94e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else if (cmp > 0) 95e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat n = n->rb_right; 96e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else 97e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return this->pip; 98e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 99e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 100e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return NULL; 101e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 102e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 103e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void insert_pid(struct p_info *that, __u32 pid) 104e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 105e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct pn_info *this; 106e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct rb_node *parent = NULL; 107e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct rb_node **p = &root_pid.rb_node; 108e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 109e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (*p) { 110e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat parent = *p; 111e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat this = rb_entry(parent, struct pn_info, rb_node); 112e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 113e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (pid < this->u.pid) 114e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat p = &(*p)->rb_left; 115e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else if (pid > this->u.pid) 116e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat p = &(*p)->rb_right; 117e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else 118e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return; // Already there 119e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 120e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 121e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat this = malloc(sizeof(struct pn_info)); 122e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat this->u.pid = pid; 123e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat this->pip = that; 124e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 125e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat rb_link_node(&this->rb_node, parent, p); 126e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat rb_insert_color(&this->rb_node, &root_pid); 127e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 128e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 129e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void insert_name(struct p_info *that) 130e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 131e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int cmp; 132e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct pn_info *this; 133e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct rb_node *parent = NULL; 134e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct rb_node **p = &root_name.rb_node; 135e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 136e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (*p) { 137e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat parent = *p; 138e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat this = rb_entry(parent, struct pn_info, rb_node); 139e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat cmp = strcmp(that->name, this->u.name); 140e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 141e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (cmp < 0) 142e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat p = &(*p)->rb_left; 143e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else if (cmp > 0) 144e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat p = &(*p)->rb_right; 145e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else 146e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return; // Already there... 147e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 148e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 149e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat this = malloc(sizeof(struct pn_info)); 150e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat this->u.name = strdup(that->name); 151e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat this->pip = that; 152e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 153e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat rb_link_node(&this->rb_node, parent, p); 154e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat rb_insert_color(&this->rb_node, &root_name); 155e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 156e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 157e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void insert(struct p_info *pip) 158e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 159e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat insert_pid(pip, pip->pid); 160e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat insert_name(pip); 161e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 162e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 163e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline struct p_info *pip_alloc(void) 164e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 165e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return memset(malloc(sizeof(struct p_info)), 0, sizeof(struct p_info)); 166e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 167e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 168e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct p_info *find_process(__u32 pid, char *name) 169e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 170e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct p_info *pip; 171e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 172e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (pid != ((__u32)-1)) { 173e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if ((pip = __find_process_pid(pid)) != NULL) 174e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return pip; 175e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else if (name) { 176e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pip = __find_process_name(name); 177e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 178e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (pip && pid != pip->pid) { 179e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /* 180e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * This is a process with the same name 181e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * as another, but a different PID. 182e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 183e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * We'll store a reference in the PID 184e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * tree... 185e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 186e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat insert_pid(pip, pid); 187e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 188e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return pip; 189e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 190e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 191e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /* 192e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * We're here because we have a pid, and no name, but 193e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * we didn't find a process ... 194e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 195e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * We'll craft one using the pid... 196e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 197e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 198e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat name = alloca(256); 199e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat sprintf(name, "pid%09u", pid); 200e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat process_alloc(pid, name); 201e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return __find_process_pid(pid); 202e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 203e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 204e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return __find_process_name(name); 205e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 206e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 207e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid process_alloc(__u32 pid, char *name) 208e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 209e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct p_info *pip = find_process(pid, name); 210e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 211e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (pip == NULL) { 212e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pip = pip_alloc(); 213e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pip->pid = pid; 214e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat region_init(&pip->regions); 215e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pip->last_q = (__u64)-1; 216e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pip->name = strdup(name); 217e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 218e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat insert(pip); 219e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 220e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 221e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 222e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid pip_update_q(struct io *iop) 223e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 224e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (iop->pip) { 225e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (remapper_dev(iop->dip->device)) 226e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat update_lq(&iop->pip->last_q, &iop->pip->avgs.q2q_dm, 227e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat iop->t.time); 228e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else 229e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat update_lq(&iop->pip->last_q, &iop->pip->avgs.q2q, 230e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat iop->t.time); 231e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat update_qregion(&iop->pip->regions, iop->t.time); 232e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 233e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 234e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 235e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid pip_foreach_out(void (*f)(struct p_info *, void *), void *arg) 236e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 237e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (exes == NULL) 238e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __foreach(root_name.rb_node, f, arg); 239e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else { 240e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct p_info *pip; 241e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char *exe, *p, *next, *exes_save = strdup(exes); 242e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 243e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat p = exes_save; 244e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (exes_save != NULL) { 245e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat exe = exes_save; 246e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if ((next = strchr(exes_save, ',')) != NULL) { 247e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *next = '\0'; 248e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat exes_save = next+1; 249e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } else 250e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat exes_save = NULL; 251e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 252e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pip = __find_process_name(exe); 253e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (pip) 254e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat f(pip, arg); 255e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 256e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 257e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 258e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 259e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid pip_exit(void) 260e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 261e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __destroy(root_pid.rb_node, 0, 0); 262e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __destroy(root_name.rb_node, 1, 1); 263e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 264