xref: /xnu-8792.81.2/tools/lockstat/lockstat.c (revision 19c3b8c28c31cb8130e034cfb5df6bf9ba342d90)
1*19c3b8c2SApple OSS Distributions #include <mach/mach.h>
2*19c3b8c2SApple OSS Distributions #include <stdlib.h>
3*19c3b8c2SApple OSS Distributions #include <stdio.h>
4*19c3b8c2SApple OSS Distributions #include <signal.h>
5*19c3b8c2SApple OSS Distributions #include <unistd.h>
6*19c3b8c2SApple OSS Distributions #include <sys/time.h>
7*19c3b8c2SApple OSS Distributions #include <time.h>
8*19c3b8c2SApple OSS Distributions #include <mach/error.h>
9*19c3b8c2SApple OSS Distributions #include <mach/mach_error.h>
10*19c3b8c2SApple OSS Distributions #include <mach/mig_errors.h>
11*19c3b8c2SApple OSS Distributions #include <mach/machine.h>
12*19c3b8c2SApple OSS Distributions #include <mach/processor_info.h>
13*19c3b8c2SApple OSS Distributions #include <assert.h>
14*19c3b8c2SApple OSS Distributions #include <nlist.h>
15*19c3b8c2SApple OSS Distributions #include <fcntl.h>
16*19c3b8c2SApple OSS Distributions #include <string.h>
17*19c3b8c2SApple OSS Distributions #include <mach/mach.h>
18*19c3b8c2SApple OSS Distributions #include <mach/host_info.h>
19*19c3b8c2SApple OSS Distributions 
20*19c3b8c2SApple OSS Distributions /*
21*19c3b8c2SApple OSS Distributions  *	lockstat.c
22*19c3b8c2SApple OSS Distributions  *
23*19c3b8c2SApple OSS Distributions  *	Utility to display kernel lock contention statistics.
24*19c3b8c2SApple OSS Distributions  *	Usage:
25*19c3b8c2SApple OSS Distributions  *	lockstat [all, spin, mutex, rw, <lock group name>] {<repeat interval>} {abs}
26*19c3b8c2SApple OSS Distributions  *
27*19c3b8c2SApple OSS Distributions  *	Argument 1 specifies the type of lock to display contention statistics
28*19c3b8c2SApple OSS Distributions  *	for; alternatively, a lock group (a logically grouped set of locks,
29*19c3b8c2SApple OSS Distributions  *	which can encompass multiple types of locks) can be specified by name.
30*19c3b8c2SApple OSS Distributions  *	When argument 1 is "all", statistics are displayed for all lock groups
31*19c3b8c2SApple OSS Distributions  *	which have statistics enabled.
32*19c3b8c2SApple OSS Distributions  *	Lock types include mutexes, reader-writer locks and spin locks.
33*19c3b8c2SApple OSS Distributions  *	Note that support for gathering contention statistics may not be present
34*19c3b8c2SApple OSS Distributions  *	for all types of locks on all platforms.
35*19c3b8c2SApple OSS Distributions  *
36*19c3b8c2SApple OSS Distributions  *	Argument 2 specifies a periodic interval. The program will display an
37*19c3b8c2SApple OSS Distributions  *	updated list of statistics every <repeat interval> seconds. This
38*19c3b8c2SApple OSS Distributions  *	argument is optional. The updates display the deltas from the previous
39*19c3b8c2SApple OSS Distributions  *	set of statistics, unless "abs" is specified as argument 3.
40*19c3b8c2SApple OSS Distributions  *
41*19c3b8c2SApple OSS Distributions  *	Argument 3, if "abs", causes the periodically refreshed lock statistics
42*19c3b8c2SApple OSS Distributions  *	to be displayed as absolute values rather than deltas from the previous
43*19c3b8c2SApple OSS Distributions  *	display.
44*19c3b8c2SApple OSS Distributions  *
45*19c3b8c2SApple OSS Distributions  *	Types of statistics:
46*19c3b8c2SApple OSS Distributions  *	Acquisitions: These can include both normal acquisitions, as well
47*19c3b8c2SApple OSS Distributions  *	as acquisition attempts. These are listed in the first column.
48*19c3b8c2SApple OSS Distributions  *	Examples include calls to lck_mtx_lock and lck_mtx_try_lock
49*19c3b8c2SApple OSS Distributions  *	Misses: Incremented if  a lock acquisition attempt failed, due to
50*19c3b8c2SApple OSS Distributions  *	contention.
51*19c3b8c2SApple OSS Distributions  *	Waits (Meaningful only for lock types that can block): Incremented
52*19c3b8c2SApple OSS Distributions  *	if a lock acquisition attempt proceeded to block.
53*19c3b8c2SApple OSS Distributions  *
54*19c3b8c2SApple OSS Distributions  *	Direct Waits (currently implemented only on i386/x86_64): For adaptive
55*19c3b8c2SApple OSS Distributions  *	locks, such as mutexes, incremented if the owner of the mutex
56*19c3b8c2SApple OSS Distributions  *	wasn't active on another processor at the time of the lock
57*19c3b8c2SApple OSS Distributions  *	attempt. This indicates that no adaptive spin occurred.
58*19c3b8c2SApple OSS Distributions  */
59*19c3b8c2SApple OSS Distributions 
60*19c3b8c2SApple OSS Distributions /*
61*19c3b8c2SApple OSS Distributions  * HISTORY
62*19c3b8c2SApple OSS Distributions  * 2005: Bernard Semeria
63*19c3b8c2SApple OSS Distributions  *		Created.
64*19c3b8c2SApple OSS Distributions  * 2006: Derek Kumar
65*19c3b8c2SApple OSS Distributions  *		Display i386 specific stats, fix incremental display, add
66*19c3b8c2SApple OSS Distributions  *		explanatory block comment.
67*19c3b8c2SApple OSS Distributions  */
68*19c3b8c2SApple OSS Distributions void usage(void);
69*19c3b8c2SApple OSS Distributions void print_spin_hdr(void);
70*19c3b8c2SApple OSS Distributions void print_spin(int requested, lockgroup_info_t *lockgroup);
71*19c3b8c2SApple OSS Distributions void print_all_spin(lockgroup_info_t *lockgroup);
72*19c3b8c2SApple OSS Distributions void print_mutex_hdr(void);
73*19c3b8c2SApple OSS Distributions void print_mutex(int requested, lockgroup_info_t *lockgroup);
74*19c3b8c2SApple OSS Distributions void print_all_mutex(lockgroup_info_t *lockgroup);
75*19c3b8c2SApple OSS Distributions void print_rw_hdr(void);
76*19c3b8c2SApple OSS Distributions void print_rw(int requested, lockgroup_info_t *lockgroup);
77*19c3b8c2SApple OSS Distributions void print_all_rw(lockgroup_info_t *lockgroup);
78*19c3b8c2SApple OSS Distributions void prime_lockgroup_deltas(void);
79*19c3b8c2SApple OSS Distributions void get_lockgroup_deltas(void);
80*19c3b8c2SApple OSS Distributions 
81*19c3b8c2SApple OSS Distributions char *pgmname;
82*19c3b8c2SApple OSS Distributions mach_port_t host_control;
83*19c3b8c2SApple OSS Distributions 
84*19c3b8c2SApple OSS Distributions lockgroup_info_t        *lockgroup_info, *lockgroup_start, *lockgroup_deltas;
85*19c3b8c2SApple OSS Distributions unsigned int            count;
86*19c3b8c2SApple OSS Distributions 
87*19c3b8c2SApple OSS Distributions unsigned int            gDebug = 1;
88*19c3b8c2SApple OSS Distributions 
89*19c3b8c2SApple OSS Distributions int
main(int argc,char ** argv)90*19c3b8c2SApple OSS Distributions main(int argc, char **argv)
91*19c3b8c2SApple OSS Distributions {
92*19c3b8c2SApple OSS Distributions 	kern_return_t           kr;
93*19c3b8c2SApple OSS Distributions 	int                     arg2;
94*19c3b8c2SApple OSS Distributions 	unsigned int            i;
95*19c3b8c2SApple OSS Distributions 	int                     found;
96*19c3b8c2SApple OSS Distributions 
97*19c3b8c2SApple OSS Distributions 	setlinebuf(stdout);
98*19c3b8c2SApple OSS Distributions 
99*19c3b8c2SApple OSS Distributions 	pgmname = argv[0];
100*19c3b8c2SApple OSS Distributions 	gDebug = (NULL != strstr(argv[0], "debug"));
101*19c3b8c2SApple OSS Distributions 
102*19c3b8c2SApple OSS Distributions 	host_control = mach_host_self();
103*19c3b8c2SApple OSS Distributions 
104*19c3b8c2SApple OSS Distributions 	kr = host_lockgroup_info(host_control, &lockgroup_info, &count);
105*19c3b8c2SApple OSS Distributions 
106*19c3b8c2SApple OSS Distributions 	if (kr != KERN_SUCCESS) {
107*19c3b8c2SApple OSS Distributions 		mach_error("host_statistics", kr);
108*19c3b8c2SApple OSS Distributions 		exit(EXIT_FAILURE);
109*19c3b8c2SApple OSS Distributions 	}
110*19c3b8c2SApple OSS Distributions 	if (gDebug) {
111*19c3b8c2SApple OSS Distributions 		printf("count = %d\n", count);
112*19c3b8c2SApple OSS Distributions 		for (i = 0; i < count; i++) {
113*19c3b8c2SApple OSS Distributions 			printf("%s\n", lockgroup_info[i].lockgroup_name);
114*19c3b8c2SApple OSS Distributions 		}
115*19c3b8c2SApple OSS Distributions 	}
116*19c3b8c2SApple OSS Distributions 
117*19c3b8c2SApple OSS Distributions 	switch (argc) {
118*19c3b8c2SApple OSS Distributions 	case 2:
119*19c3b8c2SApple OSS Distributions 		if (strcmp(argv[1], "all") == 0) {
120*19c3b8c2SApple OSS Distributions 			print_spin_hdr();
121*19c3b8c2SApple OSS Distributions 			print_all_spin(lockgroup_info);
122*19c3b8c2SApple OSS Distributions 			print_mutex_hdr();
123*19c3b8c2SApple OSS Distributions 			print_all_mutex(lockgroup_info);
124*19c3b8c2SApple OSS Distributions 			print_rw_hdr();
125*19c3b8c2SApple OSS Distributions 			print_all_rw(lockgroup_info);
126*19c3b8c2SApple OSS Distributions 		} else if (strcmp(argv[1], "spin") == 0) {
127*19c3b8c2SApple OSS Distributions 			print_spin_hdr();
128*19c3b8c2SApple OSS Distributions 			print_all_spin(lockgroup_info);
129*19c3b8c2SApple OSS Distributions 		} else if (strcmp(argv[1], "mutex") == 0) {
130*19c3b8c2SApple OSS Distributions 			print_mutex_hdr();
131*19c3b8c2SApple OSS Distributions 			print_all_mutex(lockgroup_info);
132*19c3b8c2SApple OSS Distributions 		} else if (strcmp(argv[1], "rw") == 0) {
133*19c3b8c2SApple OSS Distributions 			print_rw_hdr();
134*19c3b8c2SApple OSS Distributions 			print_all_rw(lockgroup_info);
135*19c3b8c2SApple OSS Distributions 		} else {
136*19c3b8c2SApple OSS Distributions 			found = 0;
137*19c3b8c2SApple OSS Distributions 			for (i = 0; i < count; i++) {
138*19c3b8c2SApple OSS Distributions 				if (strcmp(argv[1], lockgroup_info[i].lockgroup_name) == 0) {
139*19c3b8c2SApple OSS Distributions 					found = 1;
140*19c3b8c2SApple OSS Distributions 					print_spin_hdr();
141*19c3b8c2SApple OSS Distributions 					print_spin(i, lockgroup_info);
142*19c3b8c2SApple OSS Distributions 					print_mutex_hdr();
143*19c3b8c2SApple OSS Distributions 					print_mutex(i, lockgroup_info);
144*19c3b8c2SApple OSS Distributions 					print_rw_hdr();
145*19c3b8c2SApple OSS Distributions 					print_rw(i, lockgroup_info);
146*19c3b8c2SApple OSS Distributions 					break;
147*19c3b8c2SApple OSS Distributions 				}
148*19c3b8c2SApple OSS Distributions 			}
149*19c3b8c2SApple OSS Distributions 			if (found == 0) {
150*19c3b8c2SApple OSS Distributions 				usage();
151*19c3b8c2SApple OSS Distributions 			}
152*19c3b8c2SApple OSS Distributions 		}
153*19c3b8c2SApple OSS Distributions 		break;
154*19c3b8c2SApple OSS Distributions 	case 3:
155*19c3b8c2SApple OSS Distributions 		if (sscanf(argv[2], "%d", &arg2) != 1) {
156*19c3b8c2SApple OSS Distributions 			usage();
157*19c3b8c2SApple OSS Distributions 		}
158*19c3b8c2SApple OSS Distributions 		if (arg2 < 0) {
159*19c3b8c2SApple OSS Distributions 			usage();
160*19c3b8c2SApple OSS Distributions 		}
161*19c3b8c2SApple OSS Distributions 		prime_lockgroup_deltas();
162*19c3b8c2SApple OSS Distributions 		if (strcmp(argv[1], "all") == 0) {
163*19c3b8c2SApple OSS Distributions 			while (1) {
164*19c3b8c2SApple OSS Distributions 				sleep(arg2);
165*19c3b8c2SApple OSS Distributions 				get_lockgroup_deltas();
166*19c3b8c2SApple OSS Distributions 				print_spin_hdr();
167*19c3b8c2SApple OSS Distributions 				print_all_spin(lockgroup_deltas);
168*19c3b8c2SApple OSS Distributions 				print_mutex_hdr();
169*19c3b8c2SApple OSS Distributions 				print_all_mutex(lockgroup_deltas);
170*19c3b8c2SApple OSS Distributions 				print_rw_hdr();
171*19c3b8c2SApple OSS Distributions 				print_all_rw(lockgroup_deltas);
172*19c3b8c2SApple OSS Distributions 			}
173*19c3b8c2SApple OSS Distributions 		} else if (strcmp(argv[1], "spin") == 0) {
174*19c3b8c2SApple OSS Distributions 			while (1) {
175*19c3b8c2SApple OSS Distributions 				sleep(arg2);
176*19c3b8c2SApple OSS Distributions 				get_lockgroup_deltas();
177*19c3b8c2SApple OSS Distributions 				print_spin_hdr();
178*19c3b8c2SApple OSS Distributions 				print_all_spin(lockgroup_deltas);
179*19c3b8c2SApple OSS Distributions 			}
180*19c3b8c2SApple OSS Distributions 		} else if (strcmp(argv[1], "mutex") == 0) {
181*19c3b8c2SApple OSS Distributions 			while (1) {
182*19c3b8c2SApple OSS Distributions 				sleep(arg2);
183*19c3b8c2SApple OSS Distributions 				get_lockgroup_deltas();
184*19c3b8c2SApple OSS Distributions 				print_mutex_hdr();
185*19c3b8c2SApple OSS Distributions 				print_all_mutex(lockgroup_deltas);
186*19c3b8c2SApple OSS Distributions 			}
187*19c3b8c2SApple OSS Distributions 		} else if (strcmp(argv[1], "rw") == 0) {
188*19c3b8c2SApple OSS Distributions 			while (1) {
189*19c3b8c2SApple OSS Distributions 				sleep(arg2);
190*19c3b8c2SApple OSS Distributions 				get_lockgroup_deltas();
191*19c3b8c2SApple OSS Distributions 				print_rw_hdr();
192*19c3b8c2SApple OSS Distributions 				print_all_rw(lockgroup_deltas);
193*19c3b8c2SApple OSS Distributions 			}
194*19c3b8c2SApple OSS Distributions 		} else {
195*19c3b8c2SApple OSS Distributions 			found = 0;
196*19c3b8c2SApple OSS Distributions 			for (i = 0; i < count; i++) {
197*19c3b8c2SApple OSS Distributions 				if (strcmp(argv[1], lockgroup_info[i].lockgroup_name) == 0) {
198*19c3b8c2SApple OSS Distributions 					found = 1;
199*19c3b8c2SApple OSS Distributions 					while (1) {
200*19c3b8c2SApple OSS Distributions 						sleep(arg2);
201*19c3b8c2SApple OSS Distributions 						get_lockgroup_deltas();
202*19c3b8c2SApple OSS Distributions 						print_spin_hdr();
203*19c3b8c2SApple OSS Distributions 						print_spin(i, lockgroup_deltas);
204*19c3b8c2SApple OSS Distributions 						print_mutex_hdr();
205*19c3b8c2SApple OSS Distributions 						print_mutex(i, lockgroup_deltas);
206*19c3b8c2SApple OSS Distributions 						print_rw_hdr();
207*19c3b8c2SApple OSS Distributions 						print_rw(i, lockgroup_deltas);
208*19c3b8c2SApple OSS Distributions 					}
209*19c3b8c2SApple OSS Distributions 				}
210*19c3b8c2SApple OSS Distributions 			}
211*19c3b8c2SApple OSS Distributions 			if (found == 0) {
212*19c3b8c2SApple OSS Distributions 				usage();
213*19c3b8c2SApple OSS Distributions 			}
214*19c3b8c2SApple OSS Distributions 		}
215*19c3b8c2SApple OSS Distributions 		break;
216*19c3b8c2SApple OSS Distributions 	case 4:
217*19c3b8c2SApple OSS Distributions 		if (strcmp(argv[3], "abs") != 0) {
218*19c3b8c2SApple OSS Distributions 			usage();
219*19c3b8c2SApple OSS Distributions 		}
220*19c3b8c2SApple OSS Distributions 		if (sscanf(argv[2], "%d", &arg2) != 1) {
221*19c3b8c2SApple OSS Distributions 			usage();
222*19c3b8c2SApple OSS Distributions 		}
223*19c3b8c2SApple OSS Distributions 		if (strcmp(argv[1], "all") == 0) {
224*19c3b8c2SApple OSS Distributions 			while (1) {
225*19c3b8c2SApple OSS Distributions 				print_spin_hdr();
226*19c3b8c2SApple OSS Distributions 				print_all_spin(lockgroup_info);
227*19c3b8c2SApple OSS Distributions 				print_mutex_hdr();
228*19c3b8c2SApple OSS Distributions 				print_all_mutex(lockgroup_info);
229*19c3b8c2SApple OSS Distributions 				print_rw_hdr();
230*19c3b8c2SApple OSS Distributions 				print_all_rw(lockgroup_info);
231*19c3b8c2SApple OSS Distributions 				sleep(arg2);
232*19c3b8c2SApple OSS Distributions 			}
233*19c3b8c2SApple OSS Distributions 		} else if (strcmp(argv[1], "spin") == 0) {
234*19c3b8c2SApple OSS Distributions 			while (1) {
235*19c3b8c2SApple OSS Distributions 				print_all_spin(lockgroup_info);
236*19c3b8c2SApple OSS Distributions 				sleep(arg2);
237*19c3b8c2SApple OSS Distributions 			}
238*19c3b8c2SApple OSS Distributions 		} else if (strcmp(argv[1], "mutex") == 0) {
239*19c3b8c2SApple OSS Distributions 			print_mutex_hdr();
240*19c3b8c2SApple OSS Distributions 			while (1) {
241*19c3b8c2SApple OSS Distributions 				print_all_mutex(lockgroup_info);
242*19c3b8c2SApple OSS Distributions 				sleep(arg2);
243*19c3b8c2SApple OSS Distributions 			}
244*19c3b8c2SApple OSS Distributions 		} else if (strcmp(argv[1], "rw") == 0) {
245*19c3b8c2SApple OSS Distributions 			print_rw_hdr();
246*19c3b8c2SApple OSS Distributions 			while (1) {
247*19c3b8c2SApple OSS Distributions 				print_all_rw(lockgroup_info);
248*19c3b8c2SApple OSS Distributions 				sleep(arg2);
249*19c3b8c2SApple OSS Distributions 			}
250*19c3b8c2SApple OSS Distributions 		} else {
251*19c3b8c2SApple OSS Distributions 			found = 0;
252*19c3b8c2SApple OSS Distributions 			for (i = 0; i < count; i++) {
253*19c3b8c2SApple OSS Distributions 				if (strcmp(argv[1], lockgroup_info[i].lockgroup_name) == 0) {
254*19c3b8c2SApple OSS Distributions 					found = 1;
255*19c3b8c2SApple OSS Distributions 					while (1) {
256*19c3b8c2SApple OSS Distributions 						print_spin_hdr();
257*19c3b8c2SApple OSS Distributions 						print_spin(i, lockgroup_info);
258*19c3b8c2SApple OSS Distributions 						print_mutex_hdr();
259*19c3b8c2SApple OSS Distributions 						print_mutex(i, lockgroup_info);
260*19c3b8c2SApple OSS Distributions 						print_rw_hdr();
261*19c3b8c2SApple OSS Distributions 						print_rw(i, lockgroup_info);
262*19c3b8c2SApple OSS Distributions 						sleep(arg2);
263*19c3b8c2SApple OSS Distributions 					}
264*19c3b8c2SApple OSS Distributions 				}
265*19c3b8c2SApple OSS Distributions 			}
266*19c3b8c2SApple OSS Distributions 			if (found == 0) {
267*19c3b8c2SApple OSS Distributions 				usage();
268*19c3b8c2SApple OSS Distributions 			}
269*19c3b8c2SApple OSS Distributions 		}
270*19c3b8c2SApple OSS Distributions 		break;
271*19c3b8c2SApple OSS Distributions 	default:
272*19c3b8c2SApple OSS Distributions 		usage();
273*19c3b8c2SApple OSS Distributions 		break;
274*19c3b8c2SApple OSS Distributions 	}
275*19c3b8c2SApple OSS Distributions 
276*19c3b8c2SApple OSS Distributions 	exit(0);
277*19c3b8c2SApple OSS Distributions }
278*19c3b8c2SApple OSS Distributions 
279*19c3b8c2SApple OSS Distributions void
usage()280*19c3b8c2SApple OSS Distributions usage()
281*19c3b8c2SApple OSS Distributions {
282*19c3b8c2SApple OSS Distributions 	fprintf(stderr, "Usage: %s [all, spin, mutex, rw, <lock group name>] {<repeat interval>} {abs}\n", pgmname);
283*19c3b8c2SApple OSS Distributions 	exit(EXIT_FAILURE);
284*19c3b8c2SApple OSS Distributions }
285*19c3b8c2SApple OSS Distributions 
286*19c3b8c2SApple OSS Distributions void
print_spin_hdr(void)287*19c3b8c2SApple OSS Distributions print_spin_hdr(void)
288*19c3b8c2SApple OSS Distributions {
289*19c3b8c2SApple OSS Distributions 	printf("    Spinlock acquires           misses   Name\n");
290*19c3b8c2SApple OSS Distributions }
291*19c3b8c2SApple OSS Distributions 
292*19c3b8c2SApple OSS Distributions void
print_spin(int requested,lockgroup_info_t * lockgroup)293*19c3b8c2SApple OSS Distributions print_spin(int requested, lockgroup_info_t *lockgroup)
294*19c3b8c2SApple OSS Distributions {
295*19c3b8c2SApple OSS Distributions 	lockgroup_info_t        *curptr = &lockgroup[requested];
296*19c3b8c2SApple OSS Distributions 
297*19c3b8c2SApple OSS Distributions 	if (curptr->lock_spin_cnt != 0 && curptr->lock_spin_util_cnt != 0) {
298*19c3b8c2SApple OSS Distributions 		printf("%16lld ", curptr->lock_spin_util_cnt);
299*19c3b8c2SApple OSS Distributions 		printf("%16lld   ", curptr->lock_spin_miss_cnt);
300*19c3b8c2SApple OSS Distributions 		printf("%-14s\n", curptr->lockgroup_name);
301*19c3b8c2SApple OSS Distributions 	}
302*19c3b8c2SApple OSS Distributions }
303*19c3b8c2SApple OSS Distributions 
304*19c3b8c2SApple OSS Distributions void
print_all_spin(lockgroup_info_t * lockgroup)305*19c3b8c2SApple OSS Distributions print_all_spin(lockgroup_info_t *lockgroup)
306*19c3b8c2SApple OSS Distributions {
307*19c3b8c2SApple OSS Distributions 	unsigned int            i;
308*19c3b8c2SApple OSS Distributions 
309*19c3b8c2SApple OSS Distributions 	for (i = 0; i < count; i++) {
310*19c3b8c2SApple OSS Distributions 		print_spin(i, lockgroup);
311*19c3b8c2SApple OSS Distributions 	}
312*19c3b8c2SApple OSS Distributions 	printf("\n");
313*19c3b8c2SApple OSS Distributions }
314*19c3b8c2SApple OSS Distributions 
315*19c3b8c2SApple OSS Distributions void
print_mutex_hdr(void)316*19c3b8c2SApple OSS Distributions print_mutex_hdr(void)
317*19c3b8c2SApple OSS Distributions {
318*19c3b8c2SApple OSS Distributions #if defined(__i386__) || defined(__x86_64__)
319*19c3b8c2SApple OSS Distributions 	printf("Mutex lock attempts  Misses      Waits Direct Waits Name\n");
320*19c3b8c2SApple OSS Distributions #else
321*19c3b8c2SApple OSS Distributions 	printf("     mutex locks           misses            waits   name\n");
322*19c3b8c2SApple OSS Distributions #endif
323*19c3b8c2SApple OSS Distributions }
324*19c3b8c2SApple OSS Distributions 
325*19c3b8c2SApple OSS Distributions void
print_mutex(int requested,lockgroup_info_t * lockgroup)326*19c3b8c2SApple OSS Distributions print_mutex(int requested, lockgroup_info_t *lockgroup)
327*19c3b8c2SApple OSS Distributions {
328*19c3b8c2SApple OSS Distributions 	lockgroup_info_t        *curptr = &lockgroup[requested];
329*19c3b8c2SApple OSS Distributions 
330*19c3b8c2SApple OSS Distributions 	if (curptr->lock_mtx_cnt != 0 && curptr->lock_mtx_util_cnt != 0) {
331*19c3b8c2SApple OSS Distributions 		printf("%16lld ", curptr->lock_mtx_util_cnt);
332*19c3b8c2SApple OSS Distributions #if defined(__i386__) || defined(__x86_64__)
333*19c3b8c2SApple OSS Distributions 		printf("%10lld %10lld %10lld   ", curptr->lock_mtx_miss_cnt, curptr->lock_mtx_wait_cnt, curptr->lock_mtx_held_cnt);
334*19c3b8c2SApple OSS Distributions #else
335*19c3b8c2SApple OSS Distributions 		printf("%16lld %16lld   ", curptr->lock_mtx_miss_cnt, curptr->lock_mtx_wait_cnt);
336*19c3b8c2SApple OSS Distributions #endif
337*19c3b8c2SApple OSS Distributions 		printf("%-14s\n", curptr->lockgroup_name);
338*19c3b8c2SApple OSS Distributions 	}
339*19c3b8c2SApple OSS Distributions }
340*19c3b8c2SApple OSS Distributions 
341*19c3b8c2SApple OSS Distributions void
print_all_mutex(lockgroup_info_t * lockgroup)342*19c3b8c2SApple OSS Distributions print_all_mutex(lockgroup_info_t *lockgroup)
343*19c3b8c2SApple OSS Distributions {
344*19c3b8c2SApple OSS Distributions 	unsigned int            i;
345*19c3b8c2SApple OSS Distributions 
346*19c3b8c2SApple OSS Distributions 	for (i = 0; i < count; i++) {
347*19c3b8c2SApple OSS Distributions 		print_mutex(i, lockgroup);
348*19c3b8c2SApple OSS Distributions 	}
349*19c3b8c2SApple OSS Distributions 	printf("\n");
350*19c3b8c2SApple OSS Distributions }
351*19c3b8c2SApple OSS Distributions 
352*19c3b8c2SApple OSS Distributions void
print_rw_hdr(void)353*19c3b8c2SApple OSS Distributions print_rw_hdr(void)
354*19c3b8c2SApple OSS Distributions {
355*19c3b8c2SApple OSS Distributions 	printf("        RW locks           Misses            Waits   Name\n");
356*19c3b8c2SApple OSS Distributions }
357*19c3b8c2SApple OSS Distributions 
358*19c3b8c2SApple OSS Distributions void
print_rw(int requested,lockgroup_info_t * lockgroup)359*19c3b8c2SApple OSS Distributions print_rw(int requested, lockgroup_info_t *lockgroup)
360*19c3b8c2SApple OSS Distributions {
361*19c3b8c2SApple OSS Distributions 	lockgroup_info_t        *curptr = &lockgroup[requested];
362*19c3b8c2SApple OSS Distributions 
363*19c3b8c2SApple OSS Distributions 	if (curptr->lock_rw_cnt != 0 && curptr->lock_rw_util_cnt != 0) {
364*19c3b8c2SApple OSS Distributions 		printf("%16lld ", curptr->lock_rw_util_cnt);
365*19c3b8c2SApple OSS Distributions 		printf("%16lld %16lld   ", curptr->lock_rw_miss_cnt, curptr->lock_rw_wait_cnt);
366*19c3b8c2SApple OSS Distributions 		printf("%-14s\n", curptr->lockgroup_name);
367*19c3b8c2SApple OSS Distributions 	}
368*19c3b8c2SApple OSS Distributions }
369*19c3b8c2SApple OSS Distributions 
370*19c3b8c2SApple OSS Distributions void
print_all_rw(lockgroup_info_t * lockgroup)371*19c3b8c2SApple OSS Distributions print_all_rw(lockgroup_info_t *lockgroup)
372*19c3b8c2SApple OSS Distributions {
373*19c3b8c2SApple OSS Distributions 	unsigned int            i;
374*19c3b8c2SApple OSS Distributions 
375*19c3b8c2SApple OSS Distributions 	for (i = 0; i < count; i++) {
376*19c3b8c2SApple OSS Distributions 		print_rw(i, lockgroup);
377*19c3b8c2SApple OSS Distributions 	}
378*19c3b8c2SApple OSS Distributions 	printf("\n");
379*19c3b8c2SApple OSS Distributions }
380*19c3b8c2SApple OSS Distributions 
381*19c3b8c2SApple OSS Distributions void
prime_lockgroup_deltas(void)382*19c3b8c2SApple OSS Distributions prime_lockgroup_deltas(void)
383*19c3b8c2SApple OSS Distributions {
384*19c3b8c2SApple OSS Distributions 	lockgroup_start = calloc(count, sizeof(lockgroup_info_t));
385*19c3b8c2SApple OSS Distributions 	if (lockgroup_start == NULL) {
386*19c3b8c2SApple OSS Distributions 		fprintf(stderr, "Can't allocate memory for lockgroup info\n");
387*19c3b8c2SApple OSS Distributions 		exit(EXIT_FAILURE);
388*19c3b8c2SApple OSS Distributions 	}
389*19c3b8c2SApple OSS Distributions 	memcpy(lockgroup_start, lockgroup_info, count * sizeof(lockgroup_info_t));
390*19c3b8c2SApple OSS Distributions 
391*19c3b8c2SApple OSS Distributions 	lockgroup_deltas = calloc(count, sizeof(lockgroup_info_t));
392*19c3b8c2SApple OSS Distributions 	if (lockgroup_deltas == NULL) {
393*19c3b8c2SApple OSS Distributions 		fprintf(stderr, "Can't allocate memory for lockgroup info\n");
394*19c3b8c2SApple OSS Distributions 		exit(EXIT_FAILURE);
395*19c3b8c2SApple OSS Distributions 	}
396*19c3b8c2SApple OSS Distributions }
397*19c3b8c2SApple OSS Distributions 
398*19c3b8c2SApple OSS Distributions void
get_lockgroup_deltas(void)399*19c3b8c2SApple OSS Distributions get_lockgroup_deltas(void)
400*19c3b8c2SApple OSS Distributions {
401*19c3b8c2SApple OSS Distributions 	kern_return_t                   kr;
402*19c3b8c2SApple OSS Distributions 	unsigned int                    i;
403*19c3b8c2SApple OSS Distributions 
404*19c3b8c2SApple OSS Distributions 	kr = host_lockgroup_info(host_control, &lockgroup_info, &count);
405*19c3b8c2SApple OSS Distributions 
406*19c3b8c2SApple OSS Distributions 	if (kr != KERN_SUCCESS) {
407*19c3b8c2SApple OSS Distributions 		mach_error("host_statistics", kr);
408*19c3b8c2SApple OSS Distributions 		exit(EXIT_FAILURE);
409*19c3b8c2SApple OSS Distributions 	}
410*19c3b8c2SApple OSS Distributions 
411*19c3b8c2SApple OSS Distributions 	memcpy(lockgroup_deltas, lockgroup_info, count * sizeof(lockgroup_info_t));
412*19c3b8c2SApple OSS Distributions 	for (i = 0; i < count; i++) {
413*19c3b8c2SApple OSS Distributions 		lockgroup_deltas[i].lock_spin_util_cnt =
414*19c3b8c2SApple OSS Distributions 		    lockgroup_info[i].lock_spin_util_cnt -
415*19c3b8c2SApple OSS Distributions 		    lockgroup_start[i].lock_spin_util_cnt;
416*19c3b8c2SApple OSS Distributions 		lockgroup_deltas[i].lock_spin_miss_cnt =
417*19c3b8c2SApple OSS Distributions 		    lockgroup_info[i].lock_spin_miss_cnt -
418*19c3b8c2SApple OSS Distributions 		    lockgroup_start[i].lock_spin_miss_cnt;
419*19c3b8c2SApple OSS Distributions 		lockgroup_deltas[i].lock_mtx_util_cnt =
420*19c3b8c2SApple OSS Distributions 		    lockgroup_info[i].lock_mtx_util_cnt -
421*19c3b8c2SApple OSS Distributions 		    lockgroup_start[i].lock_mtx_util_cnt;
422*19c3b8c2SApple OSS Distributions 		lockgroup_deltas[i].lock_mtx_miss_cnt =
423*19c3b8c2SApple OSS Distributions 		    lockgroup_info[i].lock_mtx_miss_cnt -
424*19c3b8c2SApple OSS Distributions 		    lockgroup_start[i].lock_mtx_miss_cnt;
425*19c3b8c2SApple OSS Distributions 		lockgroup_deltas[i].lock_mtx_wait_cnt =
426*19c3b8c2SApple OSS Distributions 		    lockgroup_info[i].lock_mtx_wait_cnt -
427*19c3b8c2SApple OSS Distributions 		    lockgroup_start[i].lock_mtx_wait_cnt;
428*19c3b8c2SApple OSS Distributions 		lockgroup_deltas[i].lock_mtx_held_cnt =
429*19c3b8c2SApple OSS Distributions 		    lockgroup_info[i].lock_mtx_held_cnt -
430*19c3b8c2SApple OSS Distributions 		    lockgroup_start[i].lock_mtx_held_cnt;
431*19c3b8c2SApple OSS Distributions 		lockgroup_deltas[i].lock_rw_util_cnt =
432*19c3b8c2SApple OSS Distributions 		    lockgroup_info[i].lock_rw_util_cnt -
433*19c3b8c2SApple OSS Distributions 		    lockgroup_start[i].lock_rw_util_cnt;
434*19c3b8c2SApple OSS Distributions 		lockgroup_deltas[i].lock_rw_miss_cnt =
435*19c3b8c2SApple OSS Distributions 		    lockgroup_info[i].lock_rw_miss_cnt -
436*19c3b8c2SApple OSS Distributions 		    lockgroup_start[i].lock_rw_miss_cnt;
437*19c3b8c2SApple OSS Distributions 		lockgroup_deltas[i].lock_rw_wait_cnt =
438*19c3b8c2SApple OSS Distributions 		    lockgroup_info[i].lock_rw_wait_cnt -
439*19c3b8c2SApple OSS Distributions 		    lockgroup_start[i].lock_rw_wait_cnt;
440*19c3b8c2SApple OSS Distributions 	}
441*19c3b8c2SApple OSS Distributions 	memcpy(lockgroup_start, lockgroup_info, count * sizeof(lockgroup_info_t));
442*19c3b8c2SApple OSS Distributions }
443