home *** CD-ROM | disk | FTP | other *** search
/ H4CK3R 4 / hacker04 / 04_HACK04.ISO / darwin / darwinx86.iso / usr / include / profile / profile-kgmon.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-09-30  |  8.3 KB  |  385 lines

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