|
|
1.1 root 1: #include <kern/cpu_number.h>
2: #include <machine/spl.h>
3:
4: #define HZ 100
5: #include <mach/clock_types.h>
6: #include <mach/mach_types.h>
7:
8: #include <sys/kdebug.h>
9: #include <sys/errno.h>
10: #include <sys/param.h> /* for splhigh */
11: #include <sys/proc.h>
12: #include <sys/vm.h>
13: #include <sys/sysctl.h>
14: #include <vm/vm_kern.h>
15:
16:
17: unsigned int pc_buftomem = 0;
18: u_long * pc_buffer = 0; /* buffer that holds each pc */
19: u_long * pc_bufptr = 0;
20: u_long * pc_buflast = 0;
21: u_long * pc_readlast = 0;
22: unsigned int npcbufs = 8192; /* number of pc entries in buffer */
23: unsigned int pc_bufsize = 0;
24: unsigned int pcsample_flags = 0;
25: unsigned int pcsample_enable = 0;
26: unsigned int pcsample_nolog = 1;
27:
28: /* Set the default framework boundaries */
29: u_long pcsample_beg = 0;
30: u_long pcsample_end = 0;
31:
32: void
33: add_pcsamples( pc)
34: register u_long pc;
35: {
36:
37: if (pcsample_nolog && pcsample_enable)
38: return;
39:
40: if ((pc < pcsample_beg) || (pc > pcsample_end))
41: return;
42:
43: *pc_bufptr = (u_long)pc;
44: pc_bufptr++;
45:
46: /* We never wrap the buffer */
47: if (pc_bufptr >= pc_buflast)
48: {
49: pcsample_nolog = 1 ;
50: }
51: }
52:
53:
54:
55: pcsamples_bootstrap()
56: {
57: pc_bufsize = npcbufs * sizeof(* pc_buffer);
58: if (kmem_alloc(kernel_map, &pc_buftomem,
59: (vm_size_t)pc_bufsize) == KERN_SUCCESS)
60: pc_buffer = (u_long *) pc_buftomem;
61: else
62: pc_buffer= (u_long *) 0;
63:
64: if (pc_buffer) {
65: pc_bufptr = pc_buffer;
66: pc_buflast = &pc_bufptr[npcbufs];
67: pc_readlast = pc_bufptr;
68: pcsample_enable = 0;
69: pcsample_nolog = 1;
70: return(0);
71: } else {
72: pc_bufsize=0;
73: return(EINVAL);
74: }
75:
76: }
77:
78: pcsamples_reinit()
79: {
80: int x;
81: int ret=0;
82: if (pc_bufsize && pc_buffer)
83: kmem_free(kernel_map,pc_buffer,pc_bufsize);
84:
85: ret= pcsamples_bootstrap();
86: return(ret);
87: }
88:
89:
90:
91: pcsamples_clear()
92: {
93: int x;
94: /* Clean up the sample buffer, set defaults */
95: pcsample_enable = 0;
96: pcsample_nolog = 1;
97: if(pc_bufsize && pc_buffer)
98: kmem_free(kernel_map,pc_buffer,pc_bufsize);
99: pc_buffer = (u_long *)0;
100: pc_bufptr = (u_long *)0;
101: pc_buflast = (u_long *)0;
102: pc_readlast = (u_long *)0;
103: pc_bufsize = 0;
104: pcsample_beg= 0;
105: pcsample_end= 0;
106: }
107:
108: pcsamples_control(name, namelen, where, sizep)
109: int *name;
110: u_int namelen;
111: char *where;
112: size_t *sizep;
113: {
114: int ret=0;
115: int size=*sizep;
116: int max_entries;
117: unsigned int value = name[1];
118: pcinfo_t pc_bufinfo;
119: switch(name[0]) {
120: case PCSAMPLE_ENABLE: /* used to enable or disable */
121: if (value)
122: {
123: /* enable only if buffer is initialized */
124: if ((pc_bufsize <= 0) || (!pc_buffer))
125: {
126: ret=EINVAL;
127: break;
128: }
129: }
130: pcsample_enable=(value)?1:0;
131: pcsample_nolog = (value)?0:1;
132: break;
133: case PCSAMPLE_SETNUMBUF:
134: /* We allow a maximum buffer size of 25% of memory */
135: max_entries = (mem_size/4) / sizeof(u_long);
136: if (value <= max_entries)
137: npcbufs = value;
138: else
139: npcbufs = max_entries;
140: break;
141: case PCSAMPLE_GETNUMBUF:
142: if(size < sizeof(pcinfo_t)) {
143: ret=EINVAL;
144: break;
145: }
146: pc_bufinfo.npcbufs = npcbufs;
147: pc_bufinfo.bufsize = pc_bufsize;
148: pc_bufinfo.nolog = pcsample_nolog;
149: pc_bufinfo.enable = pcsample_enable;
150: pc_bufinfo.pcsample_beg = pcsample_beg;
151: pc_bufinfo.pcsample_end = pcsample_end;
152: if(copyout (&pc_bufinfo, where, sizeof(pc_bufinfo)))
153: {
154: ret=EINVAL;
155: }
156: break;
157: case PCSAMPLE_SETUP:
158: ret=pcsamples_reinit();
159: break;
160: case PCSAMPLE_REMOVE:
161: pcsamples_clear();
162: break;
163: case PCSAMPLE_READBUF:
164: ret = pcsamples_read(where, sizep);
165: break;
166: case PCSAMPLE_SETREG:
167: if (size < sizeof(pcinfo_t))
168: {
169: ret = EINVAL;
170: break;
171: }
172: if (copyin(where, &pc_bufinfo, sizeof(pcinfo_t)))
173: {
174: ret = EINVAL;
175: break;
176: }
177:
178: pcsample_beg = pc_bufinfo.pcsample_beg;
179: pcsample_end = pc_bufinfo.pcsample_end;
180: break;
181: default:
182: ret= EOPNOTSUPP;
183: break;
184: }
185: return(ret);
186: }
187:
188:
189:
190: pcsamples_read(u_long *buffer, size_t *number)
191: {
192: int x,i;
193: int ret=0;
194: int avail=*number;
195: int count=0;
196:
197: count = avail/sizeof(u_long);
198: if (count) {
199: if (pc_bufsize && pc_buffer) {
200: if (count > npcbufs)
201: count = npcbufs;
202:
203: for (i = 0; i < count ; i++ )
204: {
205: if (pc_readlast == pc_bufptr)
206: {
207: /* Nothing left to read */
208: /* Reset pointers to begin of buffer */
209: pc_readlast = pc_buffer;
210: pc_bufptr = pc_buffer;
211: if (pcsample_enable)
212: {
213: /* Always be sure logging is on after a reset */
214: pcsample_nolog = 0;
215: }
216: break;
217: }
218: if(copyout(pc_readlast,buffer,sizeof(u_long))) {
219: ret=EINVAL;
220: break;
221: }
222: pc_readlast++;
223: buffer ++;
224: if (pc_readlast >= pc_buflast)
225: {
226: /* We've reached the end of the buffer */
227: /* Reset pointers to begin of buffer */
228: pc_readlast = pc_buffer;
229: pc_bufptr = pc_buffer;
230: if (pcsample_enable)
231: {
232: /* Always be sure logging is on after a reset */
233: pcsample_nolog = 0;
234: }
235: break;
236: }
237: }
238: *number = i;
239: } else ret = EINVAL;
240: } else ret=EINVAL;
241: return (ret);
242: }
243:
244:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.