|
|
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.