home *** CD-ROM | disk | FTP | other *** search
/ Programming Win32 Under the API / ProgrammingWin32UnderTheApiPatVillani.iso / src / mingw-runtime-19991107 / mingw / profile / gmon.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-11-04  |  7.2 KB  |  285 lines

  1. /*-
  2.  * Copyright (c) 1983, 1992, 1993
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #if !defined(lint) && defined(LIBC_SCCS)
  35. static char rcsid[] = "$OpenBSD: gmon.c,v 1.8 1997/07/23 21:11:27 kstailey Exp $";
  36. #endif
  37.  
  38. /*
  39.  * This file is taken from Cygwin distribution. Please keep it in sync.
  40.  * The differences should be within __MINGW32__ guard.
  41.  */
  42.  
  43. #include <fcntl.h>
  44. #include <stdlib.h>
  45. #include <stdio.h>
  46. #ifndef __MINGW32__
  47. #include <unistd.h>
  48. #include <sys/param.h>
  49. #endif
  50. #include <sys/types.h>
  51. #include <gmon.h>
  52.  
  53. #include <profil.h>
  54.  
  55. /* XXX needed? */
  56. //extern char *minbrk __asm ("minbrk");
  57.  
  58. struct gmonparam _gmonparam = { GMON_PROF_OFF };
  59.  
  60. static int    s_scale;
  61. /* see profil(2) where this is describe (incorrectly) */
  62. #define        SCALE_1_TO_1    0x10000L
  63.  
  64. #define ERR(s) write(2, s, sizeof(s))
  65.  
  66. void    moncontrol __P((int));
  67.  
  68. static void *
  69. fake_sbrk(int size)
  70. {
  71.     return malloc(size);
  72. }
  73.  
  74. void
  75. monstartup(lowpc, highpc)
  76.     u_long lowpc;
  77.     u_long highpc;
  78. {
  79.     register int o;
  80.     char *cp;
  81.     struct gmonparam *p = &_gmonparam;
  82.  
  83.     /*
  84.      * round lowpc and highpc to multiples of the density we're using
  85.      * so the rest of the scaling (here and in gprof) stays in ints.
  86.      */
  87.     p->lowpc = ROUNDDOWN(lowpc, HISTFRACTION * sizeof(HISTCOUNTER));
  88.     p->highpc = ROUNDUP(highpc, HISTFRACTION * sizeof(HISTCOUNTER));
  89.     p->textsize = p->highpc - p->lowpc;
  90.     p->kcountsize = p->textsize / HISTFRACTION;
  91.     p->hashfraction = HASHFRACTION;
  92.     p->fromssize = p->textsize / p->hashfraction;
  93.     p->tolimit = p->textsize * ARCDENSITY / 100;
  94.     if (p->tolimit < MINARCS)
  95.         p->tolimit = MINARCS;
  96.     else if (p->tolimit > MAXARCS)
  97.         p->tolimit = MAXARCS;
  98.     p->tossize = p->tolimit * sizeof(struct tostruct);
  99.  
  100.     cp = fake_sbrk(p->kcountsize + p->fromssize + p->tossize);
  101.     if (cp == (char *)-1) {
  102.         ERR("monstartup: out of memory\n");
  103.         return;
  104.     }
  105. #ifdef notdef
  106.     bzero(cp, p->kcountsize + p->fromssize + p->tossize);
  107. #endif
  108.     p->tos = (struct tostruct *)cp;
  109.     cp += p->tossize;
  110.     p->kcount = (u_short *)cp;
  111.     cp += p->kcountsize;
  112.     p->froms = (u_short *)cp;
  113.  
  114.         /* XXX minbrk needed? */
  115.     //minbrk = fake_sbrk(0);
  116.     p->tos[0].link = 0;
  117.  
  118.     o = p->highpc - p->lowpc;
  119.     if (p->kcountsize < o) {
  120. #ifndef notdef
  121.         s_scale = ((float)p->kcountsize / o ) * SCALE_1_TO_1;
  122. #else /* avoid floating point */
  123.         int quot = o / p->kcountsize;
  124.  
  125.         if (quot >= 0x10000)
  126.             s_scale = 1;
  127.         else if (quot >= 0x100)
  128.             s_scale = 0x10000 / quot;
  129.         else if (o >= 0x800000)
  130.             s_scale = 0x1000000 / (o / (p->kcountsize >> 8));
  131.         else
  132.             s_scale = 0x1000000 / ((o << 8) / p->kcountsize);
  133. #endif
  134.     } else
  135.         s_scale = SCALE_1_TO_1;
  136.  
  137.     moncontrol(1);
  138. }
  139.  
  140. void
  141. _mcleanup()
  142. {
  143.     int fd;
  144.     int hz;
  145.     int fromindex;
  146.     int endfrom;
  147.     u_long frompc;
  148.     int toindex;
  149.     struct rawarc rawarc;
  150.     struct gmonparam *p = &_gmonparam;
  151.     struct gmonhdr gmonhdr, *hdr;
  152.     char *proffile;
  153. #ifdef DEBUG
  154.     int log, len;
  155.     char dbuf[200];
  156. #endif
  157.  
  158.     if (p->state == GMON_PROF_ERROR)
  159.         ERR("_mcleanup: tos overflow\n");
  160.  
  161.         hz = PROF_HZ;
  162.     moncontrol(0);
  163.  
  164. #ifdef nope
  165.     if ((profdir = getenv("PROFDIR")) != NULL) {
  166.         extern char *__progname;
  167.         char *s, *t, *limit;
  168.         pid_t pid;
  169.         long divisor;
  170.  
  171.         /* If PROFDIR contains a null value, no profiling
  172.            output is produced */
  173.         if (*profdir == '\0') {
  174.             return;
  175.         }
  176.  
  177.         limit = buf + sizeof buf - 1 - 10 - 1 -
  178.             strlen(__progname) - 1;
  179.         t = buf;
  180.         s = profdir;
  181.         while((*t = *s) != '\0' && t < limit) {
  182.             t++;
  183.             s++;
  184.         }
  185.         *t++ = '/';
  186.  
  187.         /*
  188.          * Copy and convert pid from a pid_t to a string.  For
  189.          * best performance, divisor should be initialized to
  190.          * the largest power of 10 less than PID_MAX.
  191.          */
  192.         pid = getpid();
  193.         divisor=10000;
  194.         while (divisor > pid) divisor /= 10;    /* skip leading zeros */
  195.         do {
  196.             *t++ = (pid/divisor) + '0';
  197.             pid %= divisor;
  198.         } while (divisor /= 10);
  199.         *t++ = '.';
  200.  
  201.         s = __progname;
  202.         while ((*t++ = *s++) != '\0')
  203.             ;
  204.  
  205.         proffile = buf;
  206.     } else {
  207.         proffile = "gmon.out";
  208.     }
  209. #else
  210.     proffile = "gmon.out";
  211. #endif
  212.  
  213.     fd = open(proffile , O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, 0666);
  214.     if (fd < 0) {
  215.         perror( proffile );
  216.         return;
  217.     }
  218. #ifdef DEBUG
  219.     log = open("gmon.log", O_CREAT|O_TRUNC|O_WRONLY, 0664);
  220.     if (log < 0) {
  221.         perror("mcount: gmon.log");
  222.         return;
  223.     }
  224.     len = sprintf(dbuf, "[mcleanup1] kcount 0x%x ssiz %d\n",
  225.         p->kcount, p->kcountsize);
  226.     write(log, dbuf, len);
  227. #endif
  228.     hdr = (struct gmonhdr *)&gmonhdr;
  229.     hdr->lpc = p->lowpc;
  230.     hdr->hpc = p->highpc;
  231.     hdr->ncnt = p->kcountsize + sizeof(gmonhdr);
  232.     hdr->version = GMONVERSION;
  233.     hdr->profrate = hz;
  234.     write(fd, (char *)hdr, sizeof *hdr);
  235.     write(fd, p->kcount, p->kcountsize);
  236.     endfrom = p->fromssize / sizeof(*p->froms);
  237.     for (fromindex = 0; fromindex < endfrom; fromindex++) {
  238.         if (p->froms[fromindex] == 0)
  239.             continue;
  240.  
  241.         frompc = p->lowpc;
  242.         frompc += fromindex * p->hashfraction * sizeof(*p->froms);
  243.         for (toindex = p->froms[fromindex]; toindex != 0;
  244.              toindex = p->tos[toindex].link) {
  245. #ifdef DEBUG
  246.             len = sprintf(dbuf,
  247.             "[mcleanup2] frompc 0x%x selfpc 0x%x count %d\n" ,
  248.                 frompc, p->tos[toindex].selfpc,
  249.                 p->tos[toindex].count);
  250.             write(log, dbuf, len);
  251. #endif
  252.             rawarc.raw_frompc = frompc;
  253.             rawarc.raw_selfpc = p->tos[toindex].selfpc;
  254.             rawarc.raw_count = p->tos[toindex].count;
  255.             write(fd, &rawarc, sizeof rawarc);
  256.         }
  257.     }
  258.     close(fd);
  259. }
  260.  
  261. /*
  262.  * Control profiling
  263.  *    profiling is what mcount checks to see if
  264.  *    all the data structures are ready.
  265.  */
  266. void
  267. moncontrol(mode)
  268.     int mode;
  269. {
  270.     struct gmonparam *p = &_gmonparam;
  271.  
  272.     if (mode) {
  273.         /* start */
  274.         profil((char *)p->kcount, p->kcountsize, p->lowpc,
  275.             s_scale);
  276.         p->state = GMON_PROF_ON;
  277.     } else {
  278.         /* stop */
  279.         profil((char *)0, 0, 0, 0);
  280.         p->state = GMON_PROF_OFF;
  281.     }
  282. }
  283.  
  284.  
  285.