xref: /plan9-contrib/sys/src/ape/lib/ap/plan9/profile.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include	<stdio.h>
2 #include	<stdlib.h>
3 #include	<string.h>
4 #include	<unistd.h>
5 #include	<sys/types.h>
6 #include	<fcntl.h>
7 #include	"sys9.h"
8 
9 extern	long*	_clock;
10 extern	long	_callpc(void**);
11 extern	long	_savearg(void);
12 extern	void*	sbrk(int);
13 
14 typedef unsigned long ulong;
15 
16 typedef	struct	Plink	Plink;
17 struct	Plink
18 {
19 	Plink	*old;		/* known to be 0(ptr) */
20 	Plink	*down;
21 	Plink	*link;
22 	long	pc;
23 	long	count;
24 	long	time;		/* known to be 20(ptr) */
25 };
26 
27 struct
28 {
29 	Plink	*pp;		/* known to be 0(ptr) */
30 	Plink	*next;		/* known to be 4(ptr) */
31 	Plink	*last;
32 	Plink	*first;
33 } __prof;
34 
35 ulong
36 _profin(void)
37 {
38 	void *dummy;
39 	long pc;
40 	Plink *pp, *p;
41 	ulong arg;
42 
43 	arg = _savearg();
44 	pc = _callpc(&dummy);
45 	pp = __prof.pp;
46 	if(pp == 0)
47 		return arg;
48 
49 	for(p=pp->down; p; p=p->link)
50 		if(p->pc == pc)
51 			goto out;
52 	p = __prof.next + 1;
53 	if(p >= __prof.last) {
54 		__prof.pp = 0;
55 		return arg;
56 	}
57 	__prof.next = p;
58 	p->link = pp->down;
59 	pp->down = p;
60 	p->pc = pc;
61 	p->old = pp;
62 	p->down = 0;
63 	p->count = 0;
64 
65 out:
66 	__prof.pp = p;
67 	p->count++;
68 	p->time += *_clock;
69 	return arg;		/* disgusting linkage */
70 }
71 
72 ulong
73 _profout(void)
74 {
75 	Plink *p;
76 	ulong arg;
77 
78 	arg = _savearg();
79 	p = __prof.pp;
80 	if(p) {
81 		p->time -= *_clock;
82 		__prof.pp = p->old;
83 	}
84 	return arg;
85 }
86 
87 void
88 _profdump(void)
89 {
90 	int f;
91 	long n;
92 	Plink *p;
93 	char *vp;
94 
95 	__prof.pp = 0;
96 	f = creat("prof.out", 0666);
97 	if(f < 0) {
98 		perror("create prof.out");
99 		return;
100 	}
101 	__prof.first->time = -*_clock;
102 	vp = (char*)__prof.first;
103 	for(p = __prof.first; p <= __prof.next; p++) {
104 		/*
105 		 * short down
106 		 */
107 		n = 0xffff;
108 		if(p->down)
109 			n = p->down - __prof.first;
110 		vp[0] = n>>8;
111 		vp[1] = n;
112 
113 		/*
114 		 * short right
115 		 */
116 		n = 0xffff;
117 		if(p->link)
118 			n = p->link - __prof.first;
119 		vp[2] = n>>8;
120 		vp[3] = n;
121 		vp += 4;
122 
123 		/*
124 		 * long pc
125 		 */
126 		n = p->pc;
127 		vp[0] = n>>24;
128 		vp[1] = n>>16;
129 		vp[2] = n>>8;
130 		vp[3] = n;
131 		vp += 4;
132 
133 		/*
134 		 * long count
135 		 */
136 		n = p->count;
137 		vp[0] = n>>24;
138 		vp[1] = n>>16;
139 		vp[2] = n>>8;
140 		vp[3] = n;
141 		vp += 4;
142 
143 		/*
144 		 * long time
145 		 */
146 		n = -p->time;
147 		vp[0] = n>>24;
148 		vp[1] = n>>16;
149 		vp[2] = n>>8;
150 		vp[3] = n;
151 		vp += 4;
152 	}
153 	write(f, (char*)__prof.first, vp - (char*)__prof.first);
154 	close(f);
155 }
156 
157 void
158 _profmain(void)
159 {
160 	char ename[50];
161 	int n, f;
162 
163 	n = 1000;
164 	f = _OPEN("/env/profsize", 0);
165 	if(f >= 0) {
166 		memset(ename, 0, sizeof(ename));
167 		_READ(f, ename, sizeof(ename)-1);
168 		_CLOSE(f);
169 		n = atol(ename);
170 	}
171 	__prof.first = sbrk(n*sizeof(Plink));
172 	__prof.last = sbrk(0);
173 	__prof.next = __prof.first;
174 	atexit(_profdump);
175 	*_clock = 1;
176 }
177