darwin-xnu/osfmk/profiling/profile-kgmon.c
<<
>>
Prefs
   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
  77extern 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
  85long
  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}
 385
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.