xref: /titanic_51/usr/src/cmd/latencytop/common/stat.c (revision 15db28971f91c98efb449aebf46024ac72779fa3)
1*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
2*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * CDDL HEADER START
3*15db2897SKrishnendu Sadhukhan - Sun Microsystems  *
4*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * The contents of this file are subject to the terms of the
5*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Common Development and Distribution License (the "License").
6*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * You may not use this file except in compliance with the License.
7*15db2897SKrishnendu Sadhukhan - Sun Microsystems  *
8*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * or http://www.opensolaris.org/os/licensing.
10*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * See the License for the specific language governing permissions
11*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * and limitations under the License.
12*15db2897SKrishnendu Sadhukhan - Sun Microsystems  *
13*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * When distributing Covered Code, include this CDDL HEADER in each
14*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * If applicable, add the following below this CDDL HEADER, with the
16*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * fields enclosed by brackets "[]" replaced with your own identifying
17*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * information: Portions Copyright [yyyy] [name of copyright owner]
18*15db2897SKrishnendu Sadhukhan - Sun Microsystems  *
19*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * CDDL HEADER END
20*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
21*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
22*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Copyright (c) 2008-2009, Intel Corporation.
23*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * All Rights Reserved.
24*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
25*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
26*15db2897SKrishnendu Sadhukhan - Sun Microsystems #include <stdlib.h>
27*15db2897SKrishnendu Sadhukhan - Sun Microsystems #include <stdio.h>
28*15db2897SKrishnendu Sadhukhan - Sun Microsystems #include <memory.h>
29*15db2897SKrishnendu Sadhukhan - Sun Microsystems #include <string.h>
30*15db2897SKrishnendu Sadhukhan - Sun Microsystems #include <limits.h>
31*15db2897SKrishnendu Sadhukhan - Sun Microsystems #include <sys/stat.h>
32*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
33*15db2897SKrishnendu Sadhukhan - Sun Microsystems #include "latencytop.h"
34*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
35*15db2897SKrishnendu Sadhukhan - Sun Microsystems /* Statistics for each process/thread. */
36*15db2897SKrishnendu Sadhukhan - Sun Microsystems typedef struct _lt_stat_collection lt_stat_collection_t;
37*15db2897SKrishnendu Sadhukhan - Sun Microsystems typedef gboolean (*check_child_func_t) (gpointer key,
38*15db2897SKrishnendu Sadhukhan - Sun Microsystems     lt_stat_collection_t *stat, void *user);
39*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
40*15db2897SKrishnendu Sadhukhan - Sun Microsystems typedef struct {
41*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_stat_entry_t lt_grp_summary;
42*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	/* cause_id -> stat entry */
43*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	GHashTable *lt_grp_cidlist;
44*15db2897SKrishnendu Sadhukhan - Sun Microsystems } lt_datagroup_t;
45*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
46*15db2897SKrishnendu Sadhukhan - Sun Microsystems #define	NGROUPS			2
47*15db2897SKrishnendu Sadhukhan - Sun Microsystems #define	GROUP_CAUSE		0
48*15db2897SKrishnendu Sadhukhan - Sun Microsystems #define	GROUP_SOBJ		1
49*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
50*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
51*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * A data collection hierarchy involving three entities - system, process
52*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * and thread. The hierarchic relationship is as follows :
53*15db2897SKrishnendu Sadhukhan - Sun Microsystems  *
54*15db2897SKrishnendu Sadhukhan - Sun Microsystems  *		1 system -> 1 or more processes -> 1 or more threads
55*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
56*15db2897SKrishnendu Sadhukhan - Sun Microsystems struct _lt_stat_collection {
57*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_stat_level_t lt_sc_level;
58*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	unsigned int lt_sc_id;
59*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	char *lt_sc_name;
60*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_datagroup_t lt_sc_groups[NGROUPS];
61*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	/*
62*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	 * The following fields: lt_sc_parent, lt_sc_children and
63*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	 * lt_sc_check_child_func maintain the tree structure.
64*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	 */
65*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_stat_collection_t *lt_sc_parent;		/* Parent node */
66*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	GHashTable *lt_sc_children;	/* pid/tid -> lt_stat_collection_t */
67*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	check_child_func_t lt_sc_check_child_func; /* Release dead children */
68*15db2897SKrishnendu Sadhukhan - Sun Microsystems };
69*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
70*15db2897SKrishnendu Sadhukhan - Sun Microsystems /* Internal data structure to back up a stat_list */
71*15db2897SKrishnendu Sadhukhan - Sun Microsystems typedef struct _lt_stat_list lt_stat_list_t;
72*15db2897SKrishnendu Sadhukhan - Sun Microsystems typedef void (*free_list_func_t)(lt_stat_list_t *);
73*15db2897SKrishnendu Sadhukhan - Sun Microsystems struct _lt_stat_list {
74*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	int lt_sl_entry_count;
75*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_stat_entry_t **lt_sl_entries;
76*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	uint64_t lt_sl_gtotal;
77*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	free_list_func_t lt_sl_free_func;
78*15db2897SKrishnendu Sadhukhan - Sun Microsystems };
79*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
80*15db2897SKrishnendu Sadhukhan - Sun Microsystems /* Root of the collection hierarchy: system level statistics */
81*15db2897SKrishnendu Sadhukhan - Sun Microsystems static lt_stat_collection_t *stat_system = NULL;
82*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
83*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
84*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Data structure to hold synchronization objects.
85*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * We don't use normal "cause table" because this needs to be cleared
86*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * every time we refresh in order to make sure that stale synchronization
87*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * objects don't consume memory.
88*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
89*15db2897SKrishnendu Sadhukhan - Sun Microsystems typedef struct {
90*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	int lt_soi_type;
91*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	unsigned long long lt_soi_addr;
92*15db2897SKrishnendu Sadhukhan - Sun Microsystems } lt_sobj_id_t;
93*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
94*15db2897SKrishnendu Sadhukhan - Sun Microsystems typedef struct {
95*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_sobj_id_t lt_so_oid;
96*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	int lt_so_cause_id;
97*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	char lt_so_string[32];	/* Enough to hold "%s: 0x%llX" */
98*15db2897SKrishnendu Sadhukhan - Sun Microsystems } lt_sobj_t;
99*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
100*15db2897SKrishnendu Sadhukhan - Sun Microsystems static GHashTable *sobj_table = NULL;
101*15db2897SKrishnendu Sadhukhan - Sun Microsystems static int sobj_table_len = 0;
102*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
103*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
104*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Lower 32-bit of the address of synchronization objects is used to hash
105*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * them.
106*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
107*15db2897SKrishnendu Sadhukhan - Sun Microsystems static guint
108*15db2897SKrishnendu Sadhukhan - Sun Microsystems sobj_id_hash(lt_sobj_id_t *id)
109*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
110*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	g_assert(id != NULL);
111*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	return (id->lt_soi_addr & 0xFFFFFFFF);
112*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
113*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
114*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
115*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Test if two synchronization objects are the same.
116*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
117*15db2897SKrishnendu Sadhukhan - Sun Microsystems static gboolean
118*15db2897SKrishnendu Sadhukhan - Sun Microsystems sobj_id_equal(lt_sobj_id_t *a, lt_sobj_id_t *b)
119*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
120*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	g_assert(a != NULL && b != NULL);
121*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	return (a->lt_soi_type == b->lt_soi_type &&
122*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    a->lt_soi_addr == b->lt_soi_addr);
123*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
124*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
125*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
126*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Look up the cause_id of a synchronization object.
127*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Note that this cause_id is only unique in GROUP_SOBJ, and changes after
128*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * a refresh.
129*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
130*15db2897SKrishnendu Sadhukhan - Sun Microsystems static lt_sobj_t *
131*15db2897SKrishnendu Sadhukhan - Sun Microsystems lookup_sobj(lt_sobj_id_t *id)
132*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
133*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	const char *stype_str[] = {
134*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		"None",
135*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		"Mutex",
136*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		"RWLock",
137*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		"CV",
138*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		"Sema",
139*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		"User",
140*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		"User_PI",
141*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		"Shuttle"
142*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	};
143*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	const int stype_str_len =
144*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    sizeof (stype_str) / sizeof (stype_str[0]);
145*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_sobj_t *ret = NULL;
146*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	g_assert(id != NULL);
147*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
148*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (id->lt_soi_type < 0 || id->lt_soi_type >= stype_str_len) {
149*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (NULL);
150*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
151*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
152*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (sobj_table != NULL) {
153*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		ret = (lt_sobj_t *)g_hash_table_lookup(sobj_table, id);
154*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	} else {
155*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		sobj_table = g_hash_table_new_full(
156*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    (GHashFunc)sobj_id_hash, (GEqualFunc)sobj_id_equal,
157*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    NULL, (GDestroyNotify)free);
158*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		lt_check_null(sobj_table);
159*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
160*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
161*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (ret == NULL) {
162*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		ret = (lt_sobj_t *)lt_zalloc(sizeof (lt_sobj_t));
163*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		ret->lt_so_cause_id = ++sobj_table_len;
164*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		(void) snprintf(ret->lt_so_string, sizeof (ret->lt_so_string),
165*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    "%s: 0x%llX", stype_str[id->lt_soi_type], id->lt_soi_addr);
166*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		ret->lt_so_oid.lt_soi_type = id->lt_soi_type;
167*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		ret->lt_so_oid.lt_soi_addr = id->lt_soi_addr;
168*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
169*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		g_hash_table_insert(sobj_table, &ret->lt_so_oid, ret);
170*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
171*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
172*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	return (ret);
173*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
174*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
175*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
176*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Check if a process exists by using /proc/pid
177*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
178*15db2897SKrishnendu Sadhukhan - Sun Microsystems /* ARGSUSED */
179*15db2897SKrishnendu Sadhukhan - Sun Microsystems static gboolean
180*15db2897SKrishnendu Sadhukhan - Sun Microsystems check_process(gpointer key, lt_stat_collection_t *stat, void *user)
181*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
182*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	char name[PATH_MAX];
183*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
184*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	(void) snprintf(name, PATH_MAX, "/proc/%u", stat->lt_sc_id);
185*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	return (lt_file_exist(name) ? FALSE : TRUE);
186*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
187*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
188*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
189*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Check if a thread exists by using /proc/pid/lwp/tid
190*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
191*15db2897SKrishnendu Sadhukhan - Sun Microsystems /* ARGSUSED */
192*15db2897SKrishnendu Sadhukhan - Sun Microsystems static gboolean
193*15db2897SKrishnendu Sadhukhan - Sun Microsystems check_thread(gpointer key, lt_stat_collection_t *stat, void *user)
194*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
195*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	char name[PATH_MAX];
196*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
197*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	g_assert(stat->lt_sc_parent != NULL);
198*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	g_assert(stat->lt_sc_parent->lt_sc_level == LT_LEVEL_PROCESS);
199*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
200*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	(void) snprintf(name, PATH_MAX, "/proc/%u/lwp/%u",
201*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    stat->lt_sc_parent->lt_sc_id, stat->lt_sc_id);
202*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	return (lt_file_exist(name) ? FALSE : TRUE);
203*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
204*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
205*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
206*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Helper function to free a stat node.
207*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
208*15db2897SKrishnendu Sadhukhan - Sun Microsystems static void
209*15db2897SKrishnendu Sadhukhan - Sun Microsystems free_stat(lt_stat_collection_t *stat)
210*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
211*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	int i;
212*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
213*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (stat == NULL) {
214*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return;
215*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
216*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
217*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	for (i = 0; i < NGROUPS; ++i) {
218*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		if (stat->lt_sc_groups[i].lt_grp_cidlist != NULL) {
219*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			g_hash_table_destroy(stat->lt_sc_groups[i].
220*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			    lt_grp_cidlist);
221*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		}
222*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
223*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
224*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (stat->lt_sc_children != NULL) {
225*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		g_hash_table_destroy(stat->lt_sc_children);
226*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
227*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
228*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (stat->lt_sc_name != NULL) {
229*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		free(stat->lt_sc_name);
230*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
231*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
232*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	free(stat);
233*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
234*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
235*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
236*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Helper function to initialize a stat node.
237*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
238*15db2897SKrishnendu Sadhukhan - Sun Microsystems /* ARGSUSED */
239*15db2897SKrishnendu Sadhukhan - Sun Microsystems static void
240*15db2897SKrishnendu Sadhukhan - Sun Microsystems clear_stat(gpointer key, lt_stat_collection_t *stat, void *user)
241*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
242*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	int i;
243*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
244*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	g_assert(stat != NULL);
245*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
246*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	for (i = 0; i < NGROUPS; ++i) {
247*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		if (stat->lt_sc_groups[i].lt_grp_cidlist != NULL) {
248*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			g_hash_table_destroy(stat->lt_sc_groups[i].
249*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			    lt_grp_cidlist);
250*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			stat->lt_sc_groups[i].lt_grp_cidlist = NULL;
251*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		}
252*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
253*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		stat->lt_sc_groups[i].lt_grp_summary.lt_se_data.lt_s_count = 0;
254*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		stat->lt_sc_groups[i].lt_grp_summary.lt_se_data.lt_s_total = 0;
255*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		stat->lt_sc_groups[i].lt_grp_summary.lt_se_data.lt_s_max = 0;
256*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
257*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
258*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (stat->lt_sc_children != NULL) {
259*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		g_hash_table_foreach_remove(stat->lt_sc_children,
260*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    (GHRFunc)stat->lt_sc_check_child_func, NULL);
261*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		g_hash_table_foreach(stat->lt_sc_children,
262*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    (GHFunc)clear_stat, NULL);
263*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
264*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
265*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
266*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
267*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Update a collection with the given value.
268*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Recursively update parents in the hierarchy  until the root is reached.
269*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
270*15db2897SKrishnendu Sadhukhan - Sun Microsystems static void
271*15db2897SKrishnendu Sadhukhan - Sun Microsystems update_stat_entry(lt_stat_collection_t *stat, int cause_id,
272*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		lt_stat_type_t type, uint64_t value,
273*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		const char *string, int group_to_use)
274*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
275*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_stat_entry_t *entry = NULL;
276*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_datagroup_t *group;
277*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
278*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (group_to_use < 0 || group_to_use >= NGROUPS) {
279*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return;
280*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
281*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
282*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	group = &(stat->lt_sc_groups[group_to_use]);
283*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
284*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (group->lt_grp_cidlist != NULL) {
285*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		entry = (lt_stat_entry_t *)g_hash_table_lookup(
286*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    group->lt_grp_cidlist, LT_INT_TO_POINTER(cause_id));
287*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	} else   {
288*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		group->lt_grp_cidlist = g_hash_table_new_full(
289*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    g_direct_hash, g_direct_equal,
290*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    NULL, (GDestroyNotify)free);
291*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		lt_check_null(group->lt_grp_cidlist);
292*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
293*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
294*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (entry == NULL) {
295*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		entry = (lt_stat_entry_t *)lt_zalloc(sizeof (lt_stat_entry_t));
296*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		entry->lt_se_string = string;
297*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
298*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		switch (group_to_use) {
299*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		case GROUP_CAUSE:
300*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			entry->lt_se_type = STAT_CAUSE;
301*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			entry->lt_se_tsdata.lt_se_t_cause.lt_se_c_id = cause_id;
302*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			entry->lt_se_tsdata.lt_se_t_cause.lt_se_c_flags =
303*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			    lt_table_get_cause_flag(cause_id, CAUSE_ALL_FLAGS);
304*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
305*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			/* hide the first '#' */
306*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			if ((entry->lt_se_tsdata.lt_se_t_cause.lt_se_c_flags
307*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			    & CAUSE_FLAG_HIDE_IN_SUMMARY) != 0) {
308*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				++entry->lt_se_string;
309*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			}
310*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
311*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			break;
312*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		case GROUP_SOBJ:
313*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			entry->lt_se_type = STAT_SOBJ;
314*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			entry->lt_se_tsdata.lt_se_t_sobj.lt_se_s_id = cause_id;
315*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			break;
316*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		}
317*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
318*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		g_hash_table_insert(group->lt_grp_cidlist,
319*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    LT_INT_TO_POINTER(cause_id), entry);
320*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
321*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
322*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_update_stat_value(&entry->lt_se_data, type, value);
323*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
324*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (group_to_use == GROUP_SOBJ ||
325*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    (entry->lt_se_tsdata.lt_se_t_cause.lt_se_c_flags &
326*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    CAUSE_FLAG_HIDE_IN_SUMMARY) == 0) {
327*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		lt_update_stat_value(&group->lt_grp_summary.lt_se_data, type,
328*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    value);
329*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
330*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
331*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (stat->lt_sc_parent != NULL) {
332*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		update_stat_entry(stat->lt_sc_parent, cause_id, type, value,
333*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    string, group_to_use);
334*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
335*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
336*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
337*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
338*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Identify the cause of latency from the given stack trace.
339*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Return cause_id.
340*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
341*15db2897SKrishnendu Sadhukhan - Sun Microsystems static void
342*15db2897SKrishnendu Sadhukhan - Sun Microsystems find_cause(char *stack, int *cause_id, int *cause_priority)
343*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
344*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	int cause_temp;
345*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	int prio_temp;
346*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	int cause = INVALID_CAUSE;
347*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	int priority = 0;
348*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	int found = 0;
349*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
350*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	g_assert(cause_id != NULL);
351*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	g_assert(cause_priority != NULL);
352*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
353*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	while (stack != NULL) {
354*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		char *sep;
355*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		sep = strchr(stack, ' ');
356*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
357*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		if (sep != NULL) {
358*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			*sep = '\0';
359*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		}
360*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
361*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		found = lt_table_cause_from_stack(stack, &cause_temp,
362*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    &prio_temp);
363*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
364*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		if (found && (cause == INVALID_CAUSE ||
365*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    HIGHER_PRIORITY(prio_temp, priority))) {
366*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			cause = cause_temp;
367*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			priority = prio_temp;
368*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		}
369*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
370*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		if (sep != NULL) {
371*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			*sep = ' ';
372*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			stack = sep + 1;
373*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		} else   {
374*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			stack = NULL;
375*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		}
376*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
377*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
378*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	*cause_id = cause;
379*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	*cause_priority = priority;
380*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
381*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
382*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
383*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Create a new collection and hook it to the parent.
384*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
385*15db2897SKrishnendu Sadhukhan - Sun Microsystems static lt_stat_collection_t *
386*15db2897SKrishnendu Sadhukhan - Sun Microsystems new_collection(lt_stat_level_t level, unsigned int id, char *name,
387*15db2897SKrishnendu Sadhukhan - Sun Microsystems     lt_stat_collection_t *parent, check_child_func_t check_child_func)
388*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
389*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	int i;
390*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_stat_collection_t *ret;
391*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
392*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	ret = (lt_stat_collection_t *)
393*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    lt_zalloc(sizeof (lt_stat_collection_t));
394*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
395*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	ret->lt_sc_level = level;
396*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	ret->lt_sc_check_child_func = check_child_func;
397*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	ret->lt_sc_id = id;
398*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	ret->lt_sc_name = name;
399*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
400*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	for (i = 0; i < NGROUPS; ++i) {
401*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		ret->lt_sc_groups[i].lt_grp_summary.lt_se_string =
402*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    (const char *)name;
403*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
404*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
405*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (parent != NULL) {
406*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		ret->lt_sc_parent = parent;
407*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
408*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		if (parent->lt_sc_children == NULL) {
409*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			parent->lt_sc_children = g_hash_table_new_full(
410*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			    g_direct_hash, g_direct_equal,
411*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			    NULL, (GDestroyNotify)free_stat);
412*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			lt_check_null(parent->lt_sc_children);
413*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		}
414*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
415*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		g_hash_table_insert(parent->lt_sc_children,
416*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    LT_INT_TO_POINTER((int)id), ret);
417*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
418*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
419*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	return (ret);
420*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
421*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
422*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
423*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Find the "leaf" in the collection hierarchy, using the given pid and tid.
424*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
425*15db2897SKrishnendu Sadhukhan - Sun Microsystems static lt_stat_collection_t *
426*15db2897SKrishnendu Sadhukhan - Sun Microsystems get_stat_c(pid_t pid, id_t tid)
427*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
428*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_stat_collection_t *stat_p = NULL;
429*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_stat_collection_t *stat_t = NULL;
430*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
431*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (stat_system == NULL) {
432*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		stat_system = new_collection(LT_LEVEL_GLOBAL,
433*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    PID_SYS_GLOBAL, lt_strdup("SYSTEM"), NULL, check_process);
434*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	} else if (stat_system->lt_sc_children != NULL) {
435*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		stat_p = (lt_stat_collection_t *)
436*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    g_hash_table_lookup(stat_system->lt_sc_children,
437*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    LT_INT_TO_POINTER(pid));
438*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
439*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
440*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (stat_p == NULL) {
441*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		char *fname;
442*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		fname = lt_get_proc_field(pid, LT_FIELD_FNAME);
443*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
444*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		if (fname == NULL) {
445*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			/*
446*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			 * we could not get the executable name of the
447*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			 * process; the process is probably already dead.
448*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			 */
449*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			return (NULL);
450*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		}
451*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
452*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		stat_p = new_collection(LT_LEVEL_PROCESS,
453*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    (unsigned int)pid, fname, stat_system, check_thread);
454*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	} else if (stat_p->lt_sc_children != NULL) {
455*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		stat_t = (lt_stat_collection_t *)
456*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    g_hash_table_lookup(stat_p->lt_sc_children,
457*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    LT_INT_TO_POINTER(tid));
458*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
459*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
460*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (stat_t == NULL) {
461*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		const int tname_size = 16; /* Enough for "Thread %d" */
462*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		char *tname;
463*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
464*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		tname = (char *)lt_zalloc(tname_size);
465*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		(void) snprintf(tname, tname_size, "Thread %d", tid);
466*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
467*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		stat_t = new_collection(LT_LEVEL_THREAD,
468*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    (unsigned int)tid, tname, stat_p, NULL);
469*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
470*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
471*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	return (stat_t);
472*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
473*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
474*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
475*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Update statistics with the given cause_id. Values will be added to
476*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * internal statistics.
477*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
478*15db2897SKrishnendu Sadhukhan - Sun Microsystems void
479*15db2897SKrishnendu Sadhukhan - Sun Microsystems lt_stat_update_cause(pid_t pid, id_t tid, int cause_id, lt_stat_type_t type,
480*15db2897SKrishnendu Sadhukhan - Sun Microsystems     uint64_t value)
481*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
482*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	const char *string;
483*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_stat_collection_t *stat_t = NULL;
484*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
485*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (cause_id < 0 || value == 0) {
486*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return;
487*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
488*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
489*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (lt_table_get_cause_flag(cause_id, CAUSE_FLAG_DISABLED)) {
490*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		/* Ignore this cause */
491*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return;
492*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
493*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
494*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	stat_t = get_stat_c(pid, tid);
495*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
496*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (stat_t == NULL) {
497*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		/* Process must be dead. */
498*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return;
499*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
500*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
501*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	string = lt_table_get_cause_name(cause_id);
502*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
503*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	update_stat_entry(stat_t, cause_id, type, value, string, GROUP_CAUSE);
504*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
505*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
506*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
507*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Update statistics with the given stack trace.
508*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * The stack trace is mapped to a cause and lt_stat_update_cause() is called
509*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * to update statistics.
510*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
511*15db2897SKrishnendu Sadhukhan - Sun Microsystems void
512*15db2897SKrishnendu Sadhukhan - Sun Microsystems lt_stat_update(pid_t pid, id_t tid, char *stack, char *tag,
513*15db2897SKrishnendu Sadhukhan - Sun Microsystems     unsigned int tag_priority, lt_stat_type_t type, uint64_t value)
514*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
515*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	int tag_cause_id = INVALID_CAUSE;
516*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	int stack_cause_id = INVALID_CAUSE;
517*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	int cause_id = INVALID_CAUSE;
518*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	int stack_priority = 0;
519*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
520*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (value == 0) {
521*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return;
522*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
523*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
524*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	find_cause(stack, &stack_cause_id, &stack_priority);
525*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
526*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (tag_priority != 0) {
527*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		tag_cause_id = lt_table_cause_from_name(tag, 0, 0);
528*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
529*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		if (tag_cause_id == INVALID_CAUSE) {
530*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			/* This must be a syscall tag */
531*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			char tmp[64];
532*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			(void) snprintf(tmp, sizeof (tmp), "Syscall: %s", tag);
533*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			tag_cause_id = lt_table_cause_from_name(tmp, 1, 0);
534*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		}
535*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
536*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
537*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	cause_id = (tag_priority > stack_priority) ? tag_cause_id :
538*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    stack_cause_id;
539*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
540*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (cause_id == INVALID_CAUSE) {
541*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		/*
542*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		 * We got an unmapped stack. Set SPECIAL flag to display it
543*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		 * in pane 2. This makes it easier to find the cause.
544*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		 */
545*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		cause_id = lt_table_cause_from_name(stack, 1,
546*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    CAUSE_FLAG_SPECIAL);
547*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		lt_klog_log(LT_KLOG_LEVEL_UNMAPPED, pid, stack, type, value);
548*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	} else   {
549*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		lt_klog_log(LT_KLOG_LEVEL_MAPPED, pid, stack, type, value);
550*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
551*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
552*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_stat_update_cause(pid, tid, cause_id, type, value);
553*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
554*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
555*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
556*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Zero out all statistics, but keep the data structures in memory
557*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * to be used to hold new data immediately following.
558*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
559*15db2897SKrishnendu Sadhukhan - Sun Microsystems void
560*15db2897SKrishnendu Sadhukhan - Sun Microsystems lt_stat_clear_all(void)
561*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
562*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (stat_system != NULL) {
563*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		clear_stat(NULL, stat_system, NULL);
564*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
565*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
566*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (sobj_table != NULL) {
567*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		g_hash_table_destroy(sobj_table);
568*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		sobj_table = NULL;
569*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
570*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
571*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
572*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
573*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Clean up function that frees all memory used for statistics.
574*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
575*15db2897SKrishnendu Sadhukhan - Sun Microsystems void
576*15db2897SKrishnendu Sadhukhan - Sun Microsystems lt_stat_free_all(void)
577*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
578*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (stat_system != NULL) {
579*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		free_stat(stat_system);
580*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		stat_system = NULL;
581*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
582*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
583*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (sobj_table != NULL) {
584*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		g_hash_table_destroy(sobj_table);
585*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		sobj_table = NULL;
586*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
587*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
588*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
589*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
590*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Get top N causes of latency for a process. Return handle to a stat_list.
591*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Use pid = PID_SYS_GLOBAL to get global top list.
592*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Call lt_stat_list_free after use to clean up.
593*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
594*15db2897SKrishnendu Sadhukhan - Sun Microsystems void *
595*15db2897SKrishnendu Sadhukhan - Sun Microsystems lt_stat_list_create(lt_list_type_t list_type, lt_stat_level_t level,
596*15db2897SKrishnendu Sadhukhan - Sun Microsystems     pid_t pid, id_t tid, int count, lt_sort_t sort_by)
597*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
598*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	GCompareFunc func;
599*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	GList *list, *walk;
600*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_stat_collection_t *stat_c = NULL;
601*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_stat_list_t *ret;
602*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_datagroup_t *group;
603*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
604*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (level == LT_LEVEL_GLOBAL) {
605*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		/* Use global entry */
606*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		stat_c = stat_system;
607*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	} else if (stat_system != NULL && stat_system->lt_sc_children != NULL) {
608*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		/* Find process entry first */
609*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		stat_c = (lt_stat_collection_t *)g_hash_table_lookup(
610*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    stat_system->lt_sc_children, LT_INT_TO_POINTER(pid));
611*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
612*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		if (level == LT_LEVEL_THREAD) {
613*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			/*
614*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			 * If thread entry is requested, find it based on
615*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			 * process entry.
616*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			 */
617*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			if (stat_c != NULL && stat_c->lt_sc_children != NULL) {
618*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				stat_c = (lt_stat_collection_t *)
619*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				    g_hash_table_lookup(stat_c->lt_sc_children,
620*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				    LT_INT_TO_POINTER(tid));
621*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			} else {
622*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				/*
623*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				 * Thread entry was not found; set it to NULL,
624*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				 * so that we can return empty list later.
625*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				 */
626*15db2897SKrishnendu Sadhukhan - Sun Microsystems 				stat_c = NULL;
627*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			}
628*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		}
629*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
630*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
631*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	ret = (lt_stat_list_t *)lt_zalloc(sizeof (lt_stat_list_t));
632*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	ret->lt_sl_entries = (lt_stat_entry_t **)
633*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    lt_zalloc(count * sizeof (lt_stat_entry_t *));
634*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
635*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (stat_c == NULL) {
636*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		/* Empty list */
637*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (ret);
638*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
639*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
640*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (list_type == LT_LIST_SOBJ) {
641*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		group = &(stat_c->lt_sc_groups[GROUP_SOBJ]);
642*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	} else {
643*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		group = &(stat_c->lt_sc_groups[GROUP_CAUSE]);
644*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
645*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
646*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (group->lt_grp_cidlist == NULL) {
647*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		/* Empty list */
648*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (ret);
649*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
650*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
651*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	ret->lt_sl_gtotal = group->lt_grp_summary.lt_se_data.lt_s_total;
652*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
653*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	list = g_hash_table_get_values(group->lt_grp_cidlist);
654*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
655*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	switch (sort_by) {
656*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	case LT_SORT_TOTAL:
657*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		func = (GCompareFunc)lt_sort_by_total_desc;
658*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		break;
659*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	case LT_SORT_MAX:
660*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		func = (GCompareFunc)lt_sort_by_max_desc;
661*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		break;
662*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	case LT_SORT_AVG:
663*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		func = (GCompareFunc)lt_sort_by_avg_desc;
664*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		break;
665*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	case LT_SORT_COUNT:
666*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		func = (GCompareFunc)lt_sort_by_count_desc;
667*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		break;
668*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
669*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	list = g_list_sort(list, func);
670*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
671*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	for (walk = list;
672*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    walk != NULL && count > 0;
673*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    walk = g_list_next(walk), --count) {
674*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		lt_stat_entry_t *data = (lt_stat_entry_t *)walk->data;
675*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
676*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		if (list_type == LT_LIST_CAUSE &&
677*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    data->lt_se_type == STAT_CAUSE &&
678*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    (data->lt_se_tsdata.lt_se_t_cause.lt_se_c_flags &
679*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    CAUSE_FLAG_HIDE_IN_SUMMARY) != 0) {
680*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			continue;
681*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		}
682*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
683*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		if (list_type == LT_LIST_SPECIALS &&
684*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    data->lt_se_type == STAT_CAUSE &&
685*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    (data->lt_se_tsdata.lt_se_t_cause.lt_se_c_flags &
686*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    CAUSE_FLAG_SPECIAL) == 0) {
687*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			continue;
688*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		}
689*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
690*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		if (data->lt_se_data.lt_s_count == 0) {
691*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			break;
692*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		}
693*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
694*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		ret->lt_sl_entries[ret->lt_sl_entry_count++] = data;
695*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
696*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
697*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	g_list_free(list);
698*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
699*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	return (ret);
700*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
701*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
702*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
703*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Free memory allocated by lt_stat_list_create().
704*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
705*15db2897SKrishnendu Sadhukhan - Sun Microsystems void
706*15db2897SKrishnendu Sadhukhan - Sun Microsystems lt_stat_list_free(void *ptr)
707*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
708*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_stat_list_t *list = (lt_stat_list_t *)ptr;
709*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
710*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (list == NULL) {
711*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return;
712*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
713*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
714*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (list->lt_sl_free_func != NULL) {
715*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		list->lt_sl_free_func(list);
716*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
717*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
718*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (list->lt_sl_entries != NULL) {
719*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		free(list->lt_sl_entries);
720*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
721*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
722*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	free(list);
723*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
724*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
725*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
726*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Check if the given list contains the given item.
727*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
728*15db2897SKrishnendu Sadhukhan - Sun Microsystems int
729*15db2897SKrishnendu Sadhukhan - Sun Microsystems lt_stat_list_has_item(void *ptr, int i)
730*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
731*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_stat_list_t *list = (lt_stat_list_t *)ptr;
732*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
733*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (list == NULL || i < 0 || i >= list->lt_sl_entry_count ||
734*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    list->lt_sl_entries[i] == NULL) {
735*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (0);
736*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
737*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
738*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	return (1);
739*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
740*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
741*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
742*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Get display name of the given item i in the given list.
743*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
744*15db2897SKrishnendu Sadhukhan - Sun Microsystems const char *
745*15db2897SKrishnendu Sadhukhan - Sun Microsystems lt_stat_list_get_reason(void *ptr, int i)
746*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
747*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_stat_list_t *list = (lt_stat_list_t *)ptr;
748*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
749*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (list == NULL || i < 0 || i >= list->lt_sl_entry_count ||
750*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    list->lt_sl_entries[i] == NULL) {
751*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (NULL);
752*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
753*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
754*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	g_assert(list->lt_sl_entries[i]->lt_se_string != NULL);
755*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
756*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	return (list->lt_sl_entries[i]->lt_se_string);
757*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
758*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
759*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
760*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Get maximum value of the given item i in the given list.
761*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
762*15db2897SKrishnendu Sadhukhan - Sun Microsystems uint64_t
763*15db2897SKrishnendu Sadhukhan - Sun Microsystems lt_stat_list_get_max(void *ptr, int i)
764*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
765*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_stat_list_t *list = (lt_stat_list_t *)ptr;
766*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
767*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (list == NULL || i < 0 || i >= list->lt_sl_entry_count ||
768*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    list->lt_sl_entries[i] == NULL) {
769*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (0);
770*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
771*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
772*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	return (list->lt_sl_entries[i]->lt_se_data.lt_s_max);
773*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
774*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
775*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
776*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Get total value of the given item i in the given list.
777*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
778*15db2897SKrishnendu Sadhukhan - Sun Microsystems uint64_t
779*15db2897SKrishnendu Sadhukhan - Sun Microsystems lt_stat_list_get_sum(void *ptr, int i)
780*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
781*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_stat_list_t *list = (lt_stat_list_t *)ptr;
782*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
783*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (list == NULL || i < 0 || i >= list->lt_sl_entry_count ||
784*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    list->lt_sl_entries[i] == NULL) {
785*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (0);
786*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
787*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
788*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	return (list->lt_sl_entries[i]->lt_se_data.lt_s_total);
789*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
790*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
791*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
792*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Get count value of the given item i in the given list.
793*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
794*15db2897SKrishnendu Sadhukhan - Sun Microsystems uint64_t
795*15db2897SKrishnendu Sadhukhan - Sun Microsystems lt_stat_list_get_count(void *ptr, int i)
796*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
797*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_stat_list_t *list = (lt_stat_list_t *)ptr;
798*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
799*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (list == NULL || i < 0 || i >= list->lt_sl_entry_count ||
800*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    list->lt_sl_entries[i] == NULL) {
801*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (0);
802*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
803*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
804*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	return (list->lt_sl_entries[i]->lt_se_data.lt_s_count);
805*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
806*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
807*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
808*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Get grand total of all latency in the list.
809*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
810*15db2897SKrishnendu Sadhukhan - Sun Microsystems uint64_t
811*15db2897SKrishnendu Sadhukhan - Sun Microsystems lt_stat_list_get_gtotal(void *ptr)
812*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
813*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_stat_list_t *list = (lt_stat_list_t *)ptr;
814*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
815*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (list == NULL) {
816*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (0);
817*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
818*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
819*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	return (list->lt_sl_gtotal);
820*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
821*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
822*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
823*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * ============================================================================
824*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Process and thread list.
825*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * They share a lot of the static variables that are used for keeping
826*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * statistics, hence they are located in this file.
827*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
828*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
829*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
830*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Helper function, sort by PID/TID ascend.
831*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
832*15db2897SKrishnendu Sadhukhan - Sun Microsystems static int
833*15db2897SKrishnendu Sadhukhan - Sun Microsystems sort_id(lt_stat_collection_t *a, lt_stat_collection_t *b)
834*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
835*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	return ((int)(a->lt_sc_id - b->lt_sc_id));
836*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
837*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
838*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
839*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Get the current list of processes. Call lt_stat_proc_list_free after use
840*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * to clean up.
841*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
842*15db2897SKrishnendu Sadhukhan - Sun Microsystems static int
843*15db2897SKrishnendu Sadhukhan - Sun Microsystems plist_create(pid_t ** list)
844*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
845*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	GList *pid_list, *walk;
846*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	int ret, count;
847*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
848*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	ret = g_hash_table_size(stat_system->lt_sc_children);
849*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	*list = (pid_t *)lt_malloc(sizeof (pid_t) * ret);
850*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
851*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	pid_list = g_hash_table_get_values(stat_system->lt_sc_children);
852*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	pid_list = g_list_sort(pid_list, (GCompareFunc)sort_id);
853*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
854*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	for (walk = pid_list, count = 0;
855*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    walk != NULL && count < ret;
856*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    walk = g_list_next(walk), ++count) {
857*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		(*list)[count] = (int)
858*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    ((lt_stat_collection_t *)(walk->data))->lt_sc_id;
859*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
860*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
861*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	g_list_free(pid_list);
862*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
863*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	return (ret);
864*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
865*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
866*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
867*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Count the no. of threads currently present in a process.
868*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Only thread that have SSLEEP are counted.
869*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
870*15db2897SKrishnendu Sadhukhan - Sun Microsystems /* ARGSUSED */
871*15db2897SKrishnendu Sadhukhan - Sun Microsystems static void
872*15db2897SKrishnendu Sadhukhan - Sun Microsystems count_threads(gpointer key, lt_stat_collection_t *stat_c, int *ret)
873*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
874*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	g_assert(ret != NULL);
875*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
876*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (stat_c->lt_sc_children != NULL) {
877*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		*ret += g_hash_table_size(stat_c->lt_sc_children);
878*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
879*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
880*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
881*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
882*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Get current list of processes and threads.
883*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Call lt_stat_proc_list_free after use to clean up.
884*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
885*15db2897SKrishnendu Sadhukhan - Sun Microsystems static int
886*15db2897SKrishnendu Sadhukhan - Sun Microsystems tlist_create(pid_t ** plist, id_t ** tlist)
887*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
888*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	GList *pid_list, *walk_p;
889*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	GList *tid_list, *walk_t;
890*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	int ret = 0;
891*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	int count = 0;
892*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
893*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	g_hash_table_foreach(stat_system->lt_sc_children,
894*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    (GHFunc)count_threads, &ret);
895*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
896*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	*plist = (pid_t *)lt_malloc(sizeof (pid_t) * ret);
897*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	*tlist = (id_t *)lt_malloc(sizeof (id_t) * ret);
898*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
899*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	pid_list = g_hash_table_get_values(stat_system->lt_sc_children);
900*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	pid_list = g_list_sort(pid_list, (GCompareFunc)sort_id);
901*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
902*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	for (walk_p = pid_list; walk_p != NULL;
903*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    walk_p = g_list_next(walk_p)) {
904*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		lt_stat_collection_t *stat_p =
905*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    (lt_stat_collection_t *)walk_p->data;
906*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
907*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		if (stat_p->lt_sc_children == NULL) {
908*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			continue;
909*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		}
910*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
911*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		tid_list = g_hash_table_get_values(stat_p->lt_sc_children);
912*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		tid_list = g_list_sort(tid_list, (GCompareFunc)sort_id);
913*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
914*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		for (walk_t = tid_list; walk_t != NULL;
915*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		    walk_t = g_list_next(walk_t)) {
916*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			lt_stat_collection_t *stat_t =
917*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			    (lt_stat_collection_t *)walk_t->data;
918*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
919*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			(*plist)[count] = (int)stat_p->lt_sc_id;
920*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			(*tlist)[count] = (int)stat_t->lt_sc_id;
921*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
922*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			++count;
923*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		}
924*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		g_list_free(tid_list);
925*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
926*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
927*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	g_list_free(pid_list);
928*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	g_assert(count == ret);
929*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
930*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	return (ret);
931*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
932*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
933*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
934*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * List of processes that are tracked by LatencyTOP.
935*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
936*15db2897SKrishnendu Sadhukhan - Sun Microsystems int
937*15db2897SKrishnendu Sadhukhan - Sun Microsystems lt_stat_proc_list_create(pid_t ** plist, id_t ** tlist)
938*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
939*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (plist == NULL) {
940*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (-1);
941*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
942*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
943*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (stat_system == NULL || stat_system->lt_sc_children == NULL) {
944*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		*plist = NULL;
945*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
946*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		if (tlist != NULL) {
947*15db2897SKrishnendu Sadhukhan - Sun Microsystems 			*tlist = NULL;
948*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		}
949*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
950*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (0);
951*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
952*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
953*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (tlist == NULL) {
954*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (plist_create(plist));
955*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	} else {
956*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (tlist_create(plist, tlist));
957*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
958*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
959*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
960*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
961*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Free memory allocated by lt_stat_proc_list_create().
962*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
963*15db2897SKrishnendu Sadhukhan - Sun Microsystems void
964*15db2897SKrishnendu Sadhukhan - Sun Microsystems lt_stat_proc_list_free(pid_t *plist, id_t *tlist)
965*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
966*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (plist != NULL) {
967*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		free(plist);
968*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
969*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
970*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (tlist != NULL) {
971*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		free(tlist);
972*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
973*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
974*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
975*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
976*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Get executable name of the given process (ID).
977*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
978*15db2897SKrishnendu Sadhukhan - Sun Microsystems const char *
979*15db2897SKrishnendu Sadhukhan - Sun Microsystems lt_stat_proc_get_name(pid_t pid)
980*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
981*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_stat_collection_t *stat_p = NULL;
982*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
983*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (stat_system == NULL || stat_system->lt_sc_children == NULL) {
984*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (NULL);
985*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
986*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
987*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	stat_p = (lt_stat_collection_t *)g_hash_table_lookup(
988*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    stat_system->lt_sc_children, LT_INT_TO_POINTER(pid));
989*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
990*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (stat_p != NULL) {
991*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (stat_p->lt_sc_name);
992*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	} else   {
993*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (NULL);
994*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
995*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
996*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
997*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
998*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Get number of threads.
999*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
1000*15db2897SKrishnendu Sadhukhan - Sun Microsystems int
1001*15db2897SKrishnendu Sadhukhan - Sun Microsystems lt_stat_proc_get_nthreads(pid_t pid)
1002*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
1003*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_stat_collection_t *stat_p = NULL;
1004*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
1005*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (stat_system == NULL || stat_system->lt_sc_children == NULL) {
1006*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (0);
1007*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
1008*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
1009*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	stat_p = (lt_stat_collection_t *)g_hash_table_lookup(
1010*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    stat_system->lt_sc_children, LT_INT_TO_POINTER(pid));
1011*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
1012*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (stat_p != NULL) {
1013*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (g_hash_table_size(stat_p->lt_sc_children));
1014*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	} else   {
1015*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return (0);
1016*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
1017*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
1018*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
1019*15db2897SKrishnendu Sadhukhan - Sun Microsystems /*
1020*15db2897SKrishnendu Sadhukhan - Sun Microsystems  * Update statistics for synchronization objects.
1021*15db2897SKrishnendu Sadhukhan - Sun Microsystems  */
1022*15db2897SKrishnendu Sadhukhan - Sun Microsystems void
1023*15db2897SKrishnendu Sadhukhan - Sun Microsystems lt_stat_update_sobj(pid_t pid, id_t tid, int stype,
1024*15db2897SKrishnendu Sadhukhan - Sun Microsystems     unsigned long long wchan,
1025*15db2897SKrishnendu Sadhukhan - Sun Microsystems     lt_stat_type_t type, uint64_t value)
1026*15db2897SKrishnendu Sadhukhan - Sun Microsystems {
1027*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_sobj_id_t id;
1028*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_sobj_t *sobj;
1029*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	int cause_id;
1030*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	lt_stat_collection_t *stat_t = NULL;
1031*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
1032*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	stat_t = get_stat_c(pid, tid);
1033*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
1034*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (stat_t == NULL) {
1035*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return;
1036*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
1037*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
1038*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	id.lt_soi_type = stype;
1039*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	id.lt_soi_addr = wchan;
1040*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	sobj = lookup_sobj(&id);
1041*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
1042*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	if (sobj == NULL) {
1043*15db2897SKrishnendu Sadhukhan - Sun Microsystems 		return;
1044*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	}
1045*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
1046*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	cause_id = sobj->lt_so_cause_id;
1047*15db2897SKrishnendu Sadhukhan - Sun Microsystems 
1048*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	update_stat_entry(stat_t, cause_id, type, value,
1049*15db2897SKrishnendu Sadhukhan - Sun Microsystems 	    sobj->lt_so_string, GROUP_SOBJ);
1050*15db2897SKrishnendu Sadhukhan - Sun Microsystems }
1051