added proper param names to DYNINSTos_init
[dyninst.git] / rtinst / src / RTetc-aix.c
1 /*
2  * Copyright (c) 1996 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 /************************************************************************
43  * RTaix.c: clock access functions for aix.
44  *
45  * $Log: RTetc-aix.c,v $
46  * Revision 1.7  1997/01/16 22:19:34  tamches
47  * added proper param names to DYNINSTos_init
48  *
49  * Revision 1.6  1997/01/16 20:55:45  tamches
50  * params to DYNINSTos_init
51  *
52  * Revision 1.5  1996/08/16 21:27:27  tamches
53  * updated copyright for release 1.1
54  *
55  * Revision 1.4  1996/04/06 21:27:50  hollings
56  * Add missing case for system time.
57  *
58  * Revision 1.3  1996/02/13  16:21:57  hollings
59  * Fixed timer64 to be time64.
60  *
61  *
62  ************************************************************************/
63
64 #include <sys/time.h>
65 #include <sys/resource.h>
66 #include <malloc.h>
67 #include <stdlib.h>
68 #include <stdio.h>
69 #include "rtinst/h/rtinst.h"
70
71
72 static const double NANO_PER_USEC = 1.0e3;
73 static const long int MILLION       = 1000000;
74
75 /************************************************************************
76  * void DYNINSTos_init(void)
77  *
78  * os initialization function---currently null.
79 ************************************************************************/
80
81 void
82 DYNINSTos_init(int calledByFork, int calledByAttach) {
83 }
84
85
86 /************************************************************************
87  * time64 DYNINSTgetCPUtime(void)
88  *
89  * return value is in usec units.
90 ************************************************************************/
91
92 time64
93 DYNINSTgetCPUtime(void) {
94      time64 now;
95      static time64 previous=0;
96      struct rusage ru;
97
98 try_again:    
99     if (!getrusage(RUSAGE_SELF, &ru)) {
100       now = (time64)ru.ru_utime.tv_sec + (time64)ru.ru_stime.tv_sec;
101       now *= (time64)1000000;
102       now += (time64)ru.ru_utime.tv_usec + (time64)ru.ru_stime.tv_usec;
103       if (now<previous) {
104         goto try_again;
105       }
106       previous=now;
107       return(now);
108     }
109     else {
110       perror("getrusage");
111       abort();
112     }
113 }
114
115
116 \f
117
118
119 /************************************************************************
120  * time64 DYNINSTgetWalltime(void)
121  *
122  * get the total walltime used by the monitored process.
123  * return value is in usec units.
124 ************************************************************************/
125
126 time64 DYNINSTgetWalltime(void) {
127     time64 now;
128     register unsigned int timeSec asm("5");
129     register unsigned int timeNano asm("6");
130     register unsigned int timeSec2 asm("7");
131
132     /* Need to read the first value twice to make sure it doesn't role
133      *   over while we are reading it.
134      */
135 retry:
136     asm("mfspr   5,4");         /* read high into register 5 - timeSec */
137     asm("mfspr   6,5");         /* read low into register 6 - timeNano */
138     asm("mfspr   7,4");         /* read high into register 7 - timeSec2 */
139
140     if (timeSec != timeSec2) goto retry;
141     /* convert to correct form. */
142     now = (time64)timeSec;
143     now *= (time64)MILLION;
144     now += (time64)timeNano/(time64)1000;
145     return(now);
146 }
147
148
149 /*
150  * Code to trap execvp call and munge command (for SP-2).
151  *
152  */
153 void DYNINSTexecvp(char *argv[])
154 {
155      int i;
156      int ret;
157      char *ch;
158      char *cmd;
159      int iCount;
160      int acount;
161      char *pdArgs;
162      char **newArgs;
163      static int inExecvp;
164
165      if (inExecvp) return;
166      inExecvp = 1;
167
168      cmd = argv[0];
169
170      /* this only applies to poe on the SP-2 */
171      if (strcmp(cmd, "poe")) return;
172
173      for (iCount=0; argv[iCount]; iCount++);
174
175      pdArgs = (char *) getenv("PARADYN_MASTER_INFO");
176      if (!pdArgs) {
177          fprintf(stdout, "unable to get PARADYN_MASTER_INFO\n");
178          fflush(stdout);
179          return;
180      }
181
182      /* extras for first arg, command, -runme, and null  */
183      for (ch=pdArgs, acount=4; *ch; ch++) if (*ch == ' ') acount++;
184      newArgs = calloc(sizeof(char*), iCount+acount);
185
186      newArgs[0] = "poe";
187      newArgs[1] = "paradynd";
188
189      /* skip white spave at start */
190      while (*pdArgs && *pdArgs == ' ') pdArgs++;
191      newArgs[2] = pdArgs;
192      for (ch=pdArgs, acount=3; *ch; ch++) {
193          if (*ch == ' ') {
194              *ch = '\0';
195              /* skip over null argument -caused by spaces in environment var */
196              if (!strlen(newArgs[acount-1])) acount--;
197              newArgs[acount++] = ++ch;
198          }
199      }
200      /* skip over null argument -caused by space at end of environment var */
201      if (!strlen(newArgs[acount-1])) acount--;
202
203      newArgs[acount++] = "-runme";
204      for (i=1; i < iCount; i++) {
205          newArgs[acount++] = argv[i];
206      }
207
208      newArgs[acount] = "";
209
210      /* generate an exit record about the process to paradynd */
211      DYNINSTprintCost();
212
213      /* Now call execvp with the correct arguments */
214      ret = execvp(cmd, newArgs);
215
216      fprintf(stderr, "execvp failed\n");
217      perror("execvp");
218      fflush(stderr);
219
220      exit(-1);
221
222      inExecvp = 0;
223      return;
224 }
225
226
227 /*
228  * DYNINSTgetRusage(id) - Return the value of various OS stats.
229  *
230  *    The id is an integer, and when they are changed, any metric that uses
231  *        DYNINSTgetRusage will also need to be updated.
232  *
233  */
234 int DYNINSTgetRusage(int id)
235 {
236     int ret;
237     int value;
238     struct rusage rusage;
239     struct rusage *DYNINSTrusagePtr;
240
241     ret = getrusage(RUSAGE_SELF, &rusage);
242     if (ret) {
243         perror("getrusage");
244     }
245     DYNINSTrusagePtr = &rusage;
246     switch (id) {
247         case 0: /* page faults */
248             value = DYNINSTrusagePtr->ru_minflt+DYNINSTrusagePtr->ru_majflt;
249             break;
250         case 1: /* swaps */
251             value = DYNINSTrusagePtr->ru_nswap;
252             break;
253         case 2: /* signals received */
254             value = DYNINSTrusagePtr->ru_nsignals;
255             break;
256         case 3: /* max rss */
257             value = DYNINSTrusagePtr->ru_maxrss;
258             break;
259         case 4: /* context switches */
260             value = DYNINSTrusagePtr->ru_nvcsw + DYNINSTrusagePtr->ru_nivcsw;
261             break;
262         case 5: /* system time - in mili-seconds */
263             value = 1000 * DYNINSTrusagePtr->ru_stime.tv_sec + 
264                            DYNINSTrusagePtr->ru_stime.tv_usec/1000;
265             break;
266         default:
267             value = 0;
268             break;
269     }
270     return value;
271 }