viced: Don't VTakeOffline_r without glock
[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 #include <roken.h>
16
17 #ifdef HAVE_SYS_FILE_H
18 #include <sys/file.h>
19 #endif
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 extern int etext;
39 void AllocProfBuf();
40
41 static char *profBuf = NULL;
42 static int profBufSize;
43 static int profSig = -1;
44 static int profiling = 0;
45 static struct {
46     afs_int32 startpc;
47     afs_int32 endpc;
48     afs_int32 count;
49 } profileHeader;
50
51 void
52 StartProfiling()
53 {
54 #if !defined (AFS_AIX_ENV) && !defined (AFS_HPUX_ENV)
55 /* Soon should handle aix profiling */
56     AllocProfBuf();
57     memset(profBuf, 0, profBufSize);
58     /* the following code is to replace the monitor call below  */
59     /*  monitor (PROFSTART, &etext, profBuf, profBufSize, 0); */
60     profileHeader.startpc = PROFSTART;
61     profileHeader.endpc = (afs_int32) & etext;
62     profileHeader.count = 0;
63     profil(profBuf, profBufSize, PROFSTART, SCALE_1_TO_1);
64     profiling = 1;
65     return;
66 #endif
67 }
68
69 EndProfiling()
70 {
71 #if !defined (AFS_AIX_ENV) && !defined (AFS_HPUX_ENV)
72 /* Soon should handle aix profiling */
73     int f;
74
75     /* monitor(0); */
76     profil(0, 0, 0, 0);
77     profiling = 0;
78     f = open("mon.out", O_CREAT | O_TRUNC | O_WRONLY, 0666);
79     if (f <= 0)
80         return;
81     write(f, &profileHeader, sizeof(profileHeader));
82     write(f, profBuf, profBufSize);
83     close(f);
84 #endif
85 }
86
87 /* Allocate the profiling buffer */
88 void
89 AllocProfBuf()
90 {
91 #if !defined (AFS_AIX_ENV) && !defined (AFS_HPUX_ENV)
92 /* Soon should handle aix profiling */
93     if (profBuf != NULL)
94         return;
95     profBufSize = (int)&etext - PROFSTART;
96     profBuf = (char *)malloc(profBufSize);
97     if (profBuf == NULL) {
98         fprintf(stderr, "Couldn't get profiling buffer.\n");
99         return;
100     }
101 #endif
102 }
103 int ProfileToggle();
104
105 /* Arrange to start and stop profiling when signo is sent. */
106 void
107 ProfileSig(int signo)
108 {
109 #if !defined (AFS_AIX_ENV) && !defined (AFS_HPUX_ENV)
110 /* Soon should handle aix profiling */
111     profSig = signo;
112     if (signo >= 0) {
113         AllocProfBuf();
114         signal(signo, ProfileToggle);
115     } else
116         signal(profSig, SIG_DFL);
117 #endif
118 }
119
120 /* Toggle profiling.  Can be called as a signal handler. */
121 ProfileToggle()
122 {
123 #if !defined (AFS_AIX_ENV) && !defined (AFS_HPUX_ENV)
124 /* Soon should handle aix profiling */
125     static char *onMsg = "Profiling turned on.\n";
126     static char *offMsg = "Profiling turned off; mon.out written.\n";
127
128     if (profiling) {
129         EndProfiling();
130         write(fileno(stdout), offMsg, strlen(offMsg));
131     } else {
132         StartProfiling();
133         write(fileno(stdout), onMsg, strlen(onMsg));
134     }
135 #endif
136 }