Windows: Build Demand Attach File Service
[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
16 #include <stdio.h>
17 #include <sys/file.h>
18 #include <signal.h>
19
20 #if defined(sun) || defined(mac2)
21 #define PROFSTART       0x8000
22 #endif
23 #ifdef vax
24 #define PROFSTART       2
25 #endif
26 #ifdef  mips
27 #define PROFSTART       2       /* Verify This! */
28 #endif
29 #ifdef  NeXT
30 #define PROFSTART       0x2000
31 #endif
32 #ifdef  __alpha
33 #define PROFSTART       0
34 #endif
35 #define         SCALE_1_TO_1    0x10000L
36
37 #ifdef  AFS_OSF_ENV
38 extern void *malloc();
39 #else
40 extern char *malloc();
41 #endif
42 extern int etext;
43 void AllocProfBuf();
44
45 static char *profBuf = NULL;
46 static int profBufSize;
47 static int profSig = -1;
48 static int profiling = 0;
49 static struct {
50     afs_int32 startpc;
51     afs_int32 endpc;
52     afs_int32 count;
53 } profileHeader;
54
55 void
56 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
93 AllocProfBuf()
94 {
95 #if !defined (AFS_AIX_ENV) && !defined (AFS_HPUX_ENV)
96 /* Soon should handle aix profiling */
97     if (profBuf != NULL)
98         return;
99     profBufSize = (int)&etext - PROFSTART;
100     profBuf = (char *)malloc(profBufSize);
101     if (profBuf == NULL) {
102         fprintf(stderr, "Couldn't get profiling buffer.\n");
103         return;
104     }
105 #endif
106 }
107 int ProfileToggle();
108
109 /* Arrange to start and stop profiling when signo is sent. */
110 void
111 ProfileSig(int signo)
112 {
113 #if !defined (AFS_AIX_ENV) && !defined (AFS_HPUX_ENV)
114 /* Soon should handle aix profiling */
115     profSig = signo;
116     if (signo >= 0) {
117         AllocProfBuf();
118         signal(signo, ProfileToggle);
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     } else {
136         StartProfiling();
137         write(fileno(stdout), onMsg, strlen(onMsg));
138     }
139 #endif
140 }