2 * Copyright (c) 1996 Barton P. Miller
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.
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.
18 * (for other uses, please contact us at paradyn@cs.wisc.edu)
20 * All warranties, including without limitation, any warranty of
21 * merchantability or fitness for a particular purpose, are hereby
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.
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.
42 /************************************************************************
43 * RTaix.c: clock access functions for aix.
46 * Revision 1.8 1997/01/27 19:43:31 naim
47 * Part of the base instrumentation for supporting multithreaded applications
48 * (vectors of counter/timers) implemented for all current platforms +
49 * different bug fixes - naim
51 * Revision 1.7 1997/01/16 22:19:34 tamches
52 * added proper param names to DYNINSTos_init
54 * Revision 1.6 1997/01/16 20:55:45 tamches
55 * params to DYNINSTos_init
57 * Revision 1.5 1996/08/16 21:27:27 tamches
58 * updated copyright for release 1.1
60 * Revision 1.4 1996/04/06 21:27:50 hollings
61 * Add missing case for system time.
63 * Revision 1.3 1996/02/13 16:21:57 hollings
64 * Fixed timer64 to be time64.
67 ************************************************************************/
70 #include <sys/resource.h>
74 #include "rtinst/h/rtinst.h"
76 #if defined(MT_THREAD)
77 #include <sys/thread.h>
80 static const double NANO_PER_USEC = 1.0e3;
81 static const long int MILLION = 1000000;
83 /************************************************************************
84 * void DYNINSTos_init(void)
86 * os initialization function---currently null.
87 ************************************************************************/
90 DYNINSTos_init(int calledByFork, int calledByAttach) {
94 /************************************************************************
95 * time64 DYNINSTgetCPUtime(void)
97 * return value is in usec units.
98 ************************************************************************/
101 DYNINSTgetCPUtime(void) {
103 static time64 previous=0;
107 if (!getrusage(RUSAGE_SELF, &ru)) {
108 now = (time64)ru.ru_utime.tv_sec + (time64)ru.ru_stime.tv_sec;
109 now *= (time64)1000000;
110 now += (time64)ru.ru_utime.tv_usec + (time64)ru.ru_stime.tv_usec;
127 /************************************************************************
128 * time64 DYNINSTgetWalltime(void)
130 * get the total walltime used by the monitored process.
131 * return value is in usec units.
132 ************************************************************************/
134 time64 DYNINSTgetWalltime(void) {
136 register unsigned int timeSec asm("5");
137 register unsigned int timeNano asm("6");
138 register unsigned int timeSec2 asm("7");
140 /* Need to read the first value twice to make sure it doesn't role
141 * over while we are reading it.
144 asm("mfspr 5,4"); /* read high into register 5 - timeSec */
145 asm("mfspr 6,5"); /* read low into register 6 - timeNano */
146 asm("mfspr 7,4"); /* read high into register 7 - timeSec2 */
148 if (timeSec != timeSec2) goto retry;
149 /* convert to correct form. */
150 now = (time64)timeSec;
151 now *= (time64)MILLION;
152 now += (time64)timeNano/(time64)1000;
158 * Code to trap execvp call and munge command (for SP-2).
161 void DYNINSTexecvp(char *argv[])
173 if (inExecvp) return;
178 /* this only applies to poe on the SP-2 */
179 if (strcmp(cmd, "poe")) return;
181 for (iCount=0; argv[iCount]; iCount++);
183 pdArgs = (char *) getenv("PARADYN_MASTER_INFO");
185 fprintf(stdout, "unable to get PARADYN_MASTER_INFO\n");
190 /* extras for first arg, command, -runme, and null */
191 for (ch=pdArgs, acount=4; *ch; ch++) if (*ch == ' ') acount++;
192 newArgs = calloc(sizeof(char*), iCount+acount);
195 newArgs[1] = "paradynd";
197 /* skip white spave at start */
198 while (*pdArgs && *pdArgs == ' ') pdArgs++;
200 for (ch=pdArgs, acount=3; *ch; ch++) {
203 /* skip over null argument -caused by spaces in environment var */
204 if (!strlen(newArgs[acount-1])) acount--;
205 newArgs[acount++] = ++ch;
208 /* skip over null argument -caused by space at end of environment var */
209 if (!strlen(newArgs[acount-1])) acount--;
211 newArgs[acount++] = "-runme";
212 for (i=1; i < iCount; i++) {
213 newArgs[acount++] = argv[i];
216 newArgs[acount] = "";
218 /* generate an exit record about the process to paradynd */
221 /* Now call execvp with the correct arguments */
222 ret = execvp(cmd, newArgs);
224 fprintf(stderr, "execvp failed\n");
236 * DYNINSTgetRusage(id) - Return the value of various OS stats.
238 * The id is an integer, and when they are changed, any metric that uses
239 * DYNINSTgetRusage will also need to be updated.
242 int DYNINSTgetRusage(int id)
246 struct rusage rusage;
247 struct rusage *DYNINSTrusagePtr;
249 ret = getrusage(RUSAGE_SELF, &rusage);
253 DYNINSTrusagePtr = &rusage;
255 case 0: /* page faults */
256 value = DYNINSTrusagePtr->ru_minflt+DYNINSTrusagePtr->ru_majflt;
259 value = DYNINSTrusagePtr->ru_nswap;
261 case 2: /* signals received */
262 value = DYNINSTrusagePtr->ru_nsignals;
264 case 3: /* max rss */
265 value = DYNINSTrusagePtr->ru_maxrss;
267 case 4: /* context switches */
268 value = DYNINSTrusagePtr->ru_nvcsw + DYNINSTrusagePtr->ru_nivcsw;
270 case 5: /* system time - in mili-seconds */
271 value = 1000 * DYNINSTrusagePtr->ru_stime.tv_sec +
272 DYNINSTrusagePtr->ru_stime.tv_usec/1000;
281 #if defined(MT_THREAD)
282 extern unsigned hash_lookup(unsigned key);
283 extern unsigned initialize_done;
284 extern void initialize_hash(unsigned total);
285 extern void initialize_free(unsigned total);
286 extern unsigned hash_insert(unsigned k);
288 int DYNINSTthreadSelf(void) {
289 return(thread_self());
292 int DYNINSTthreadPos(void) {
293 if (initialize_done) {
294 return(hash_lookup(DYNINSTthreadSelf()));
296 initialize_free(MAX_NUMBER_OF_THREADS);
297 initialize_hash(MAX_NUMBER_OF_THREADS);
299 return(hash_insert(DYNINSTthreadSelf()));