viced-rewrite-breaklatercallbacks-20030218
[openafs.git] / src / viced / profile.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 /* profile.c -- routines to deal with profiling.   2 June 1986 */
11
12 #include <afsconfig.h>
13 #include <afs/param.h>
14
15 RCSID("$Header$");
16
17 #include <stdio.h>
18 #include <sys/file.h>
19 #include <signal.h>
20
21 #if defined(sun) || defined(mac2)
22 #define PROFSTART       0x8000
23 #endif
24 #ifdef vax
25 #define PROFSTART       2
26 #endif
27 #ifdef  mips
28 #define PROFSTART       2   /* Verify This! */
29 #endif
30 #ifdef  NeXT
31 #define PROFSTART       0x2000
32 #endif
33 #ifdef  __alpha
34 #define PROFSTART       0
35 #endif
36 #define         SCALE_1_TO_1    0x10000L
37
38 #ifdef  AFS_OSF_ENV
39 extern void *malloc();
40 #else
41 extern char *malloc();
42 #endif
43 extern int etext;
44 void AllocProfBuf();
45
46 static char *profBuf = NULL;
47 static int profBufSize;
48 static int profSig = -1;
49 static int profiling = 0;
50 static struct {
51     afs_int32 startpc;
52     afs_int32 endpc;
53     afs_int32 count;
54 } profileHeader;
55
56 void StartProfiling()
57 {
58 #if !defined (AFS_AIX_ENV) && !defined (AFS_HPUX_ENV)
59 /* Soon should handle aix profiling */
60     AllocProfBuf();
61     memset(profBuf, 0, profBufSize);
62   /* the following code is to replace the monitor call below  */
63   /*  monitor (PROFSTART, &etext, profBuf, profBufSize, 0); */
64     profileHeader.startpc = PROFSTART;
65     profileHeader.endpc = (afs_int32)&etext;
66     profileHeader.count = 0;
67     profil(profBuf, profBufSize, PROFSTART, SCALE_1_TO_1);
68     profiling = 1;
69     return;
70 #endif
71 }
72
73 EndProfiling ()
74 {
75 #if !defined (AFS_AIX_ENV) && !defined (AFS_HPUX_ENV)
76 /* Soon should handle aix profiling */
77     int f;
78
79     /* monitor(0); */
80     profil(0, 0, 0, 0);
81     profiling = 0;
82     f = open("mon.out", O_CREAT|O_TRUNC|O_WRONLY, 0666);
83     if (f <= 0)
84         return;
85     write(f, &profileHeader, sizeof(profileHeader));
86     write(f, profBuf, profBufSize);
87     close(f);
88 #endif
89 }
90
91 /* Allocate the profiling buffer */
92 void AllocProfBuf()
93 {
94 #if !defined (AFS_AIX_ENV) && !defined (AFS_HPUX_ENV)
95 /* Soon should handle aix profiling */
96     if (profBuf != NULL)
97         return;
98     profBufSize = (int) &etext - PROFSTART;
99     profBuf = (char *)malloc (profBufSize);
100     if (profBuf == NULL) {
101         fprintf (stderr, "Couldn't get profiling buffer.\n");
102         return;
103     }
104 #endif
105 }
106 int ProfileToggle();
107
108 /* Arrange to start and stop profiling when signo is sent. */
109 ProfileSig(signo)
110     int signo;
111 {
112 #if !defined (AFS_AIX_ENV) && !defined (AFS_HPUX_ENV)
113 /* Soon should handle aix profiling */
114     profSig = signo;
115     if (signo >= 0) {
116         AllocProfBuf();
117         signal(signo, ProfileToggle);
118     }
119     else
120         signal(profSig, SIG_DFL);
121 #endif
122 }
123
124 /* Toggle profiling.  Can be called as a signal handler. */
125 ProfileToggle()
126 {
127 #if !defined (AFS_AIX_ENV) && !defined (AFS_HPUX_ENV)
128 /* Soon should handle aix profiling */
129     static char *onMsg = "Profiling turned on.\n";
130     static char *offMsg = "Profiling turned off; mon.out written.\n";
131
132     if (profiling) {
133         EndProfiling();
134         write(fileno(stdout), offMsg, strlen(offMsg));
135     }
136     else {
137         StartProfiling();
138         write(fileno(stdout), onMsg, strlen(onMsg));
139     }
140 #endif
141 }