Small change to comment out a warning message - naim
[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.11  1997/06/02 16:39:40  naim
47  * Small change to comment out a warning message - naim
48  *
49  * Revision 1.10  1997/05/07 18:59:15  naim
50  * Getting rid of old support for threads and turning it off until the new
51  * version is finished - naim
52  *
53  * Revision 1.9  1997/02/18 21:34:37  sec
54  * There were some bugs in how the time was accessed, fixed those; I also
55  * removed DYNISTexecvp which is buggy, and is never called (it was called
56  * for MPI stuff, but I replaced it with some modifications for poe/mpi in
57  * paradyn/DMthread).
58  *
59  * Revision 1.8  1997/01/27 19:43:31  naim
60  * Part of the base instrumentation for supporting multithreaded applications
61  * (vectors of counter/timers) implemented for all current platforms +
62  * different bug fixes - naim
63  *
64  * Revision 1.7  1997/01/16 22:19:34  tamches
65  * added proper param names to DYNINSTos_init
66  *
67  * Revision 1.6  1997/01/16 20:55:45  tamches
68  * params to DYNINSTos_init
69  *
70  * Revision 1.5  1996/08/16 21:27:27  tamches
71  * updated copyright for release 1.1
72  *
73  * Revision 1.4  1996/04/06 21:27:50  hollings
74  * Add missing case for system time.
75  *
76  * Revision 1.3  1996/02/13  16:21:57  hollings
77  * Fixed timer64 to be time64.
78  *
79  *
80  ************************************************************************/
81
82 #include <malloc.h>
83 #include <stdlib.h>
84 #include <stdio.h>
85 #include <errno.h>
86 #include <unistd.h>
87 #include <string.h>
88 #include <assert.h>
89 #include <signal.h>
90 #include <sys/reg.h>
91 #include <sys/ptrace.h>
92 #include <sys/ldr.h>
93 #include <sys/time.h>
94 #include <sys/resource.h>
95
96 #include "rtinst/h/rtinst.h"
97
98 #if defined(SHM_SAMPLING) && defined(MT_THREAD)
99 #include <sys/thread.h>
100 #endif
101
102 static const double NANO_PER_USEC   = 1.0e3;
103 static const long int MILLION       = 1000000;
104
105 /************************************************************************
106  * void DYNINSTos_init(void)
107  *
108  * os initialization function---currently null.
109 ************************************************************************/
110
111 void
112 DYNINSTos_init(int calledByFork, int calledByAttach) {
113 }
114
115
116 /************************************************************************
117  * time64 DYNINSTgetCPUtime(void)
118  *
119  * return value is in usec units.
120 ************************************************************************/
121
122 time64 DYNINSTgetCPUtime(void) 
123 {
124   time64        now;
125   static time64 prevTime = 0;
126   struct rusage ru;
127
128   do {
129     if (!getrusage(RUSAGE_SELF, &ru)) {
130       now = (time64) ru.ru_utime.tv_sec + (time64) ru.ru_stime.tv_sec;
131       now *= (time64) 1000000;
132       now += (time64) ru.ru_utime.tv_usec + (time64) ru.ru_stime.tv_usec;
133     } else {
134       perror("getrusage");
135       abort();
136     }
137   } while(prevTime > now);
138
139   prevTime = now;
140   return(now);
141 }
142
143
144
145
146
147 /************************************************************************
148  * time64 DYNINSTgetWalltime(void)
149  *
150  * get the total walltime used by the monitored process.
151  * return value is in usec units.
152 ************************************************************************/
153
154 time64 DYNINSTgetWalltime(void)
155 {
156   static time64 prevTime = 0;
157   time64        now;
158
159   register unsigned int timeSec asm("5");
160   register unsigned int timeNano asm("6");
161   register unsigned int timeSec2 asm("7");
162   
163   /* Need to read the first value twice to make sure it doesn't role
164    *   over while we are reading it.
165    */
166   do {
167     asm("mfspr   5,4");         /* read high into register 5 - timeSec */
168     asm("mfspr   6,5");         /* read low into register 6 - timeNano */
169     asm("mfspr   7,4");         /* read high into register 7 - timeSec2 */
170   } while(timeSec != timeSec2);
171   
172   /* convert to correct form. */
173   now = (time64) timeSec;
174   now *= (time64) MILLION;
175   now += (time64) timeNano/ (time64) 1000;
176
177   if(prevTime > now) {
178 /*
179     fprintf(stderr, "WARNING:  prevTime (%f) > now (%f)\n", 
180             (double) prevTime, (double) now);
181 */
182     return(prevTime);
183   } else {
184     prevTime = now;
185     return(now);
186   }
187 }
188
189
190 /*
191  * DYNINSTgetRusage(id) - Return the value of various OS stats.
192  *
193  *    The id is an integer, and when they are changed, any metric that uses
194  *        DYNINSTgetRusage will also need to be updated.
195  *
196  */
197 int DYNINSTgetRusage(int id)
198 {
199
200     int ret;
201     int value;
202     struct rusage rusage;
203     struct rusage *DYNINSTrusagePtr;
204
205     ret = getrusage(RUSAGE_SELF, &rusage);
206     if (ret) {
207         perror("getrusage");
208     }
209     DYNINSTrusagePtr = &rusage;
210     switch (id) {
211         case 0: /* page faults */
212             value = DYNINSTrusagePtr->ru_minflt+DYNINSTrusagePtr->ru_majflt;
213             break;
214         case 1: /* swaps */
215             value = DYNINSTrusagePtr->ru_nswap;
216             break;
217         case 2: /* signals received */
218             value = DYNINSTrusagePtr->ru_nsignals;
219             break;
220         case 3: /* max rss */
221             value = DYNINSTrusagePtr->ru_maxrss;
222             break;
223         case 4: /* context switches */
224             value = DYNINSTrusagePtr->ru_nvcsw + DYNINSTrusagePtr->ru_nivcsw;
225             break;
226         case 5: /* system time - in mili-seconds */
227             value = 1000 * DYNINSTrusagePtr->ru_stime.tv_sec + 
228                            DYNINSTrusagePtr->ru_stime.tv_usec/1000;
229             break;
230         default:
231             value = 0;
232             break;
233     }
234     return value;
235 }
236
237 #if defined(SHM_SAMPLING) && defined(MT_THREAD)
238 extern unsigned DYNINST_hash_lookup(unsigned key);
239 extern unsigned DYNINST_initialize_done;
240 extern void DYNINST_initialize_hash(unsigned total);
241 extern void DYNINST_initialize_free(unsigned total);
242 extern unsigned DYNINST_hash_insert(unsigned k);
243
244 int DYNINSTthreadSelf(void) {
245   return(thread_self());
246 }
247
248 int DYNINSTthreadPos(void) {
249   if (DYNINST_initialize_done) {
250     return(DYNINST_hash_lookup(DYNINSTthreadSelf()));
251   } else {
252     DYNINST_initialize_free(MAX_NUMBER_OF_THREADS);
253     DYNINST_initialize_hash(MAX_NUMBER_OF_THREADS);
254     DYNINST_initialize_done=1;
255     return(DYNINST_hash_insert(DYNINSTthreadSelf()));
256   }
257 }
258 #endif