|
|
1.1 root 1: /*
2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * The contents of this file constitute Original Code as defined in and
7: * are subject to the Apple Public Source License Version 1.1 (the
8: * "License"). You may not use this file except in compliance with the
9: * License. Please obtain a copy of the License at
10: * http://www.apple.com/publicsource and read it before using this file.
11: *
12: * This Original Code and all software distributed under the License are
13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17: * License for the specific language governing rights and limitations
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /*
23: * @OSF_COPYRIGHT@
24: */
25: /*
26: * HISTORY
27: *
28: * Revision 1.1.1.1 1998/09/22 21:05:49 wsanchez
29: * Import of Mac OS X kernel (~semeria)
30: *
31: * Revision 1.1.1.1 1998/03/07 02:26:08 wsanchez
32: * Import of OSF Mach kernel (~mburg)
33: *
34: * Revision 1.1.5.1 1995/01/06 19:54:04 devrcs
35: * mk6 CR668 - 1.3b26 merge
36: * new file for mk6
37: * [1994/10/12 22:25:34 dwm]
38: *
39: * Revision 1.1.2.1 1994/04/08 17:52:05 meissner
40: * Add callback function to _profile_kgmon.
41: * [1994/02/16 22:38:31 meissner]
42: *
43: * _profile_kgmon now returns pointer to area, doesn't do move itself.
44: * [1994/02/11 16:52:17 meissner]
45: *
46: * Move all printfs into if (pv->debug) { ... } blocks.
47: * Add debug printfs protected by if (pv->debug) for all error conditions.
48: * Add code to reset profiling information.
49: * Add code to get/set debug flag.
50: * Expand copyright.
51: * [1994/02/07 12:41:14 meissner]
52: *
53: * Add support to copy arbitrary regions.
54: * Delete several of the KGMON_GET commands, now that arb. regions are supported.
55: * Explicitly call _profile_update_stats before dumping vars or stats.
56: * [1994/02/03 00:59:05 meissner]
57: *
58: * Combine _profile_{vars,stats,md}; Allow more than one _profile_vars.
59: * [1994/02/01 12:04:09 meissner]
60: *
61: * CR 10198 - Initial version.
62: * [1994/01/28 23:33:37 meissner]
63: *
64: * $EndLog$
65: */
66:
67: #include <profiling/profile-internal.h>
68:
69: #ifdef MACH_KERNEL
70: #include <profiling/machine/profile-md.h>
71: #endif
72:
73: #ifndef PROFILE_VARS
74: #define PROFILE_VARS(cpu) (&_profile_vars)
75: #endif
76:
77: extern int printf(const char *, ...);
78:
79:
80: /*
81: * Kgmon interface. This returns the count of bytes moved if everything was ok,
82: * or -1 if there were errors.
83: */
84:
85: long
86: _profile_kgmon(int write,
87: size_t count,
88: long indx,
89: int max_cpus,
90: void **p_ptr,
91: void (*control_func)(kgmon_control_t))
92: {
93: kgmon_control_t kgmon;
94: int cpu;
95: int error = 0;
96: int i;
97: struct profile_vars *pv;
98: static struct callback dummy_callback;
99:
100: *p_ptr = (void *)0;
101:
102: /*
103: * If the number passed is not within bounds, just copy the data directly.
104: */
105:
106: if (!LEGAL_KGMON(indx)) {
107: *p_ptr = (void *)indx;
108: if (!write) {
109: if (PROFILE_VARS(0)->debug) {
110: printf("_profile_kgmon: copy %5ld bytes, from 0x%lx\n",
111: (long)count,
112: (long)indx);
113: }
114:
115: } else {
116: if (PROFILE_VARS(0)->debug) {
117: printf("_profile_kgmon: copy %5ld bytes, to 0x%lx\n",
118: (long)count,
119: (long)indx);
120: }
121: }
122:
123: return count;
124: }
125:
126: /*
127: * Decode the record number into the component pieces.
128: */
129:
130: DECODE_KGMON(indx, kgmon, cpu);
131:
132: if (PROFILE_VARS(0)->debug) {
133: printf("_profile_kgmon: start: kgmon control = %2d, cpu = %d, count = %ld\n",
134: kgmon, cpu, (long)count);
135: }
136:
137: /* Validate the CPU number */
138: if (cpu < 0 || cpu >= max_cpus) {
139: if (PROFILE_VARS(0)->debug) {
140: printf("KGMON, bad cpu %d\n", cpu);
141: }
142:
143: return -1;
144:
145: } else {
146: pv = PROFILE_VARS(cpu);
147:
148: if (!write) {
149: switch (kgmon) {
150: default:
151: if (PROFILE_VARS(0)->debug) {
152: printf("Unknown KGMON read command\n");
153: }
154:
155: error = -1;
156: break;
157:
158: case KGMON_GET_STATUS: /* return whether or not profiling is active */
159: if (cpu != 0) {
160: if (PROFILE_VARS(0)->debug) {
161: printf("KGMON_GET_STATUS: cpu = %d\n", cpu);
162: }
163:
164: error = -1;
165: break;
166: }
167:
168: if (count != sizeof(pv->active)) {
169: if (PROFILE_VARS(0)->debug) {
170: printf("KGMON_GET_STATUS: count = %ld, should be %ld\n",
171: (long)count,
172: (long)sizeof(pv->active));
173: }
174:
175: error = -1;
176: break;
177: }
178:
179: *p_ptr = (void *)&pv->active;
180: break;
181:
182: case KGMON_GET_DEBUG: /* return whether or not debugging is active */
183: if (cpu != 0) {
184: if (PROFILE_VARS(0)->debug) {
185: printf("KGMON_GET_DEBUG: cpu = %d\n", cpu);
186: }
187:
188: error = -1;
189: break;
190: }
191:
192: if (count != sizeof(pv->debug)) {
193: if (PROFILE_VARS(0)->debug) {
194: printf("KGMON_GET_DEBUG: count = %ld, should be %ld\n",
195: (long)count,
196: (long)sizeof(pv->active));
197: }
198:
199: error = -1;
200: break;
201: }
202:
203: *p_ptr = (void *)&pv->debug;
204: break;
205:
206: case KGMON_GET_PROFILE_VARS: /* return the _profile_vars structure */
207: if (count != sizeof(struct profile_vars)) {
208: if (PROFILE_VARS(0)->debug) {
209: printf("KGMON_GET_PROFILE_VARS: count = %ld, should be %ld\n",
210: (long)count,
211: (long)sizeof(struct profile_vars));
212: }
213:
214: error = -1;
215: break;
216: }
217:
218: _profile_update_stats(pv);
219: *p_ptr = (void *)pv;
220: break;
221:
222: case KGMON_GET_PROFILE_STATS: /* return the _profile_stats structure */
223: if (count != sizeof(struct profile_stats)) {
224: if (PROFILE_VARS(0)->debug) {
225: printf("KGMON_GET_PROFILE_STATS: count = %ld, should be = %ld\n",
226: (long)count,
227: (long)sizeof(struct profile_stats));
228: }
229:
230: error = -1;
231: break;
232: }
233:
234: _profile_update_stats(pv);
235: *p_ptr = (void *)&pv->stats;
236: break;
237: }
238:
239: } else {
240: switch (kgmon) {
241: default:
242: if (PROFILE_VARS(0)->debug) {
243: printf("Unknown KGMON write command\n");
244: }
245:
246: error = -1;
247: break;
248:
249: case KGMON_SET_PROFILE_ON: /* turn on profiling */
250: if (cpu != 0) {
251: if (PROFILE_VARS(0)->debug) {
252: printf("KGMON_SET_PROFILE_ON, cpu = %d\n", cpu);
253: }
254:
255: error = -1;
256: break;
257: }
258:
259: if (!PROFILE_VARS(0)->active) {
260: for (i = 0; i < max_cpus; i++) {
261: PROFILE_VARS(i)->active = 1;
262: }
263:
264: if (control_func) {
265: (*control_func)(kgmon);
266: }
267:
268: _profile_md_start();
269: }
270:
271: count = 0;
272: break;
273:
274: case KGMON_SET_PROFILE_OFF: /* turn off profiling */
275: if (cpu != 0) {
276: if (PROFILE_VARS(0)->debug) {
277: printf("KGMON_SET_PROFILE_OFF, cpu = %d\n", cpu);
278: }
279:
280: error = -1;
281: break;
282: }
283:
284: if (PROFILE_VARS(0)->active) {
285: for (i = 0; i < max_cpus; i++) {
286: PROFILE_VARS(i)->active = 0;
287: }
288:
289: _profile_md_stop();
290:
291: if (control_func) {
292: (*control_func)(kgmon);
293: }
294: }
295:
296: count = 0;
297: break;
298:
299: case KGMON_SET_PROFILE_RESET: /* reset profiling */
300: if (cpu != 0) {
301: if (PROFILE_VARS(0)->debug) {
302: printf("KGMON_SET_PROFILE_RESET, cpu = %d\n", cpu);
303: }
304:
305: error = -1;
306: break;
307: }
308:
309: for (i = 0; i < max_cpus; i++) {
310: _profile_reset(PROFILE_VARS(i));
311: }
312:
313: if (control_func) {
314: (*control_func)(kgmon);
315: }
316:
317: count = 0;
318: break;
319:
320: case KGMON_SET_DEBUG_ON: /* turn on profiling */
321: if (cpu != 0) {
322: if (PROFILE_VARS(0)->debug) {
323: printf("KGMON_SET_DEBUG_ON, cpu = %d\n", cpu);
324: }
325:
326: error = -1;
327: break;
328: }
329:
330: if (!PROFILE_VARS(0)->debug) {
331: for (i = 0; i < max_cpus; i++) {
332: PROFILE_VARS(i)->debug = 1;
333: }
334:
335: if (control_func) {
336: (*control_func)(kgmon);
337: }
338: }
339:
340: count = 0;
341: break;
342:
343: case KGMON_SET_DEBUG_OFF: /* turn off profiling */
344: if (cpu != 0) {
345: if (PROFILE_VARS(0)->debug) {
346: printf("KGMON_SET_DEBUG_OFF, cpu = %d\n", cpu);
347: }
348:
349: error = -1;
350: break;
351: }
352:
353: if (PROFILE_VARS(0)->debug) {
354: for (i = 0; i < max_cpus; i++) {
355: PROFILE_VARS(i)->debug = 0;
356: }
357:
358: if (control_func) {
359: (*control_func)(kgmon);
360: }
361: }
362:
363: count = 0;
364: break;
365: }
366: }
367: }
368:
369: if (error) {
370: if (PROFILE_VARS(0)->debug) {
371: printf("_profile_kgmon: done: kgmon control = %2d, cpu = %d, error = %d\n",
372: kgmon, cpu, error);
373: }
374:
375: return -1;
376: }
377:
378: if (PROFILE_VARS(0)->debug) {
379: printf("_profile_kgmon: done: kgmon control = %2d, cpu = %d, count = %ld\n",
380: kgmon, cpu, (long)count);
381: }
382:
383: return count;
384: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.