Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
00001 /* 00002 00003 Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00004 00005 This program is free software; you can redistribute it and/or modify it 00006 under the terms of version 2 of the GNU General Public License as 00007 published by the Free Software Foundation. 00008 00009 This program is distributed in the hope that it would be useful, but 00010 WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00012 00013 Further, this software is distributed without any warranty that it is 00014 free of the rightful claim of any third person regarding infringement 00015 or the like. Any license provided herein, whether implied or 00016 otherwise, applies only to this software file. Patent licenses, if 00017 any, provided herein do not apply to combinations of this program with 00018 other software, or any other product whatsoever. 00019 00020 You should have received a copy of the GNU General Public License along 00021 with this program; if not, write the Free Software Foundation, Inc., 59 00022 Temple Place - Suite 330, Boston MA 02111-1307, USA. 00023 00024 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00025 Mountain View, CA 94043, or: 00026 00027 http://www.sgi.com 00028 00029 For further information regarding this notice, see: 00030 00031 http://oss.sgi.com/projects/GenInfo/NoticeExplan 00032 00033 */ 00034 00035 00036 #ifdef _KEEP_RCS_ID 00037 static const char source_file[] = __FILE__; 00038 #endif 00039 00040 #if (1) 00041 # include <sys/time.h> 00042 # include <sys/resource.h> 00043 typedef struct rusage time_buf_t; 00044 #else 00045 # include <sys/param.h> 00046 # include <sys/types.h> 00047 # include <sys/times.h> 00048 # include <time.h> 00049 typedef struct tms time_buf_t; 00050 #endif 00051 00052 #include <unistd.h> 00053 #include <string.h> 00054 /* Hack: These were defined in sys/param.h and will be redefined in defs.h 00055 * if we don't prevent it. TODO: Really defs.h should check to see if they are 00056 * defined before defining them. 00057 */ 00058 #ifdef MAX 00059 #undef MAX 00060 #endif 00061 #ifdef MIN 00062 #undef MIN 00063 #endif 00064 00065 #include "defs.h" 00066 #include "resource.h" 00067 00068 00069 /* ==================================================================== 00070 * 00071 * Basic internal data structures: 00072 * 00073 * ==================================================================== 00074 */ 00075 00076 /* The following structure may contain absolute or delta information: */ 00077 struct resources { 00078 TIME_INFO utime; /* User cpu time */ 00079 TIME_INFO stime; /* System cpu time */ 00080 TIME_INFO etime; /* Elapsed time */ 00081 INT memory; /* Memory used (bytes) */ 00082 INT freemem; /* Free memory allocated */ 00083 }; 00084 00085 /* The following structure contains the latest absolute and the 00086 * accumulated delta information. It is the basic object exported 00087 * to the world, although they don't know it. 00088 */ 00089 struct rstate { 00090 RESOURCES cur; /* The latest absolute information */ 00091 RESOURCES del; /* The accumulated delta information */ 00092 struct rstate *dad; /* The parent structure in hierarchy */ 00093 char *name; /* The resource record name */ 00094 }; 00095 00096 static void Clear_Resource ( RESOURCES *r ); 00097 static void Get_Resources ( RESOURCES *r ); 00098 static void Get_Delta_Time ( TIME_INFO *current, 00099 TIME_INFO *base, 00100 TIME_INFO *delta ); 00101 static void Get_Delta_Resource ( RESOURCES *current, 00102 RESOURCES *base, 00103 RESOURCES *delta ); 00104 static void Accum_Delta_Time ( TIME_INFO *delta, TIME_INFO *summary ); 00105 static void Accum_Delta_Resource ( RESOURCES *delta, 00106 RESOURCES *summary ); 00107 00108 /* We need a few buffers for internal use: */ 00109 static time_buf_t tbuf; 00110 static RESOURCES curtime, deltime; 00111 static RSTATE runtime; 00112 #if (1) 00113 static struct timeval start_time; 00114 #else 00115 static INT start_time; /* Initial date/time */ 00116 #endif 00117 static INT initialized = 0; 00118 00119 /* ==================================================================== 00120 * 00121 * Clear_Resource 00122 * 00123 * Clear all components of a resource structure. 00124 * 00125 * ==================================================================== 00126 */ 00127 00128 static void 00129 Clear_Resource ( 00130 RESOURCES *r 00131 ) 00132 { 00133 r->utime.secs = 0; 00134 r->utime.usecs = 0; 00135 r->stime.secs = 0; 00136 r->stime.usecs = 0; 00137 r->etime.secs = 0; 00138 r->etime.usecs = 0; 00139 r->memory = 0; 00140 r->freemem = 0; 00141 } 00142 00143 /* ==================================================================== 00144 * 00145 * Get_Resources 00146 * 00147 * Fill the RESOURCES structure passed with the current time/state. 00148 * 00149 * ==================================================================== 00150 */ 00151 00152 static void 00153 Get_Resources ( 00154 RESOURCES *r 00155 ) 00156 { 00157 #if (1) 00158 struct timeval now; 00159 #else 00160 INT secs, frac; 00161 #endif 00162 00163 /* Initialize if the user didn't: */ 00164 if ( ! initialized ) Resource_Init (); 00165 00166 /* Get the elapsed time: */ 00167 #if (1) 00168 00169 /* Solaris workaround */ 00170 #if defined(_SOLARIS_SOLARIS) || defined(_LINUX_LINUX) 00171 gettimeofday(&now, NULL); 00172 #elif !defined(linux) 00173 gettimeofday(&now, NULL); 00174 #else 00175 gettimeofday(&now); 00176 #endif 00177 00178 r->etime.secs = now.tv_sec - start_time.tv_sec; 00179 r->etime.usecs = now.tv_usec - start_time.tv_usec; 00180 #else 00181 r->etime.secs = time (0) - start_time; 00182 r->etime.usecs = 0; 00183 #endif 00184 00185 /* Get the CPU time information from the system: */ 00186 #if (1) 00187 getrusage (RUSAGE_SELF, &tbuf); 00188 #else 00189 (void) times (&tbuf); 00190 #endif 00191 00192 /* Transfer it to caller's structure: */ 00193 #if (1) 00194 r->utime.secs = tbuf.ru_utime.tv_sec; 00195 r->utime.usecs = tbuf.ru_utime.tv_usec; 00196 r->stime.secs = tbuf.ru_stime.tv_sec; 00197 r->stime.usecs = tbuf.ru_stime.tv_usec; 00198 #else 00199 secs = tbuf.tms_utime / HZ; 00200 frac = tbuf.tms_utime - (secs*HZ); 00201 r->utime.secs = secs; 00202 r->utime.usecs = frac * (1000000/HZ); 00203 secs = tbuf.tms_stime / HZ; 00204 frac = tbuf.tms_stime - (secs*HZ); 00205 r->stime.secs = secs; 00206 r->stime.usecs = frac * (1000000/HZ); 00207 #endif 00208 00209 /* Get the memory information */ 00210 r->memory = (INT) sbrk(0); 00211 r->freemem = 0; 00212 } 00213 00214 /* ==================================================================== 00215 * 00216 * Get_Delta_Time 00217 * 00218 * Set delta to the time difference between current and base. 00219 * 00220 * ==================================================================== 00221 */ 00222 00223 static void 00224 Get_Delta_Time ( 00225 TIME_INFO *current, /* This is current time */ 00226 TIME_INFO *base, /* Calculate delta from this base */ 00227 TIME_INFO *delta /* Put delta here */ 00228 ) 00229 { 00230 delta->secs = current->secs - base->secs; 00231 delta->usecs = current->usecs - base->usecs; 00232 if ( delta->usecs < 0 ) { 00233 delta->usecs += 1000000; 00234 delta->secs --; 00235 } 00236 } 00237 00238 00239 /* ==================================================================== 00240 * 00241 * Get_Delta_Resource 00242 * 00243 * Calculate the delta resource usage from a given base. 00244 * 00245 * ==================================================================== 00246 */ 00247 00248 static void 00249 Get_Delta_Resource ( 00250 RESOURCES *current, /* Put current state here */ 00251 RESOURCES *base, /* Calculate delta from this base */ 00252 RESOURCES *delta /* Put delta here */ 00253 ) 00254 { 00255 Get_Resources ( current ); 00256 00257 Get_Delta_Time ( ¤t->utime, &base->utime, &delta->utime ); 00258 Get_Delta_Time ( ¤t->stime, &base->stime, &delta->stime ); 00259 Get_Delta_Time ( ¤t->etime, &base->etime, &delta->etime ); 00260 delta->memory = current->memory - base->memory; 00261 delta->freemem = current->freemem - base->freemem; 00262 } 00263 00264 /* ==================================================================== 00265 * 00266 * Accum_Delta_Time 00267 * 00268 * Accumulate a delta time into a summary record. 00269 * 00270 * ==================================================================== 00271 */ 00272 00273 static void 00274 Accum_Delta_Time ( 00275 TIME_INFO *delta, /* Add this delta ... */ 00276 TIME_INFO *summary /* ... to this summary record */ 00277 ) 00278 { 00279 summary->secs += delta->secs; 00280 summary->usecs += delta->usecs; 00281 if ( summary->usecs >= 1000000 ) { 00282 summary->usecs -= 1000000; 00283 summary->secs ++; 00284 } 00285 } 00286 00287 00288 /* ==================================================================== 00289 * 00290 * Accum_Delta_Resource 00291 * 00292 * Accumulate a delta resource record into a summary record. 00293 * 00294 * ==================================================================== 00295 */ 00296 00297 static void 00298 Accum_Delta_Resource ( 00299 RESOURCES *delta, /* Add this delta ... */ 00300 RESOURCES *summary /* ... to this summary record */ 00301 ) 00302 { 00303 Accum_Delta_Time ( &delta->utime, &summary->utime ); 00304 Accum_Delta_Time ( &delta->stime, &summary->stime ); 00305 Accum_Delta_Time ( &delta->etime, &summary->etime ); 00306 summary->memory = MAX(summary->memory,delta->memory); 00307 summary->freemem += delta->freemem; 00308 } 00309 00310 /* ==================================================================== 00311 * 00312 * Resource_Init 00313 * 00314 * Initialize the resource module. Currently means just initializing 00315 * the start_time and runtime variables. 00316 * 00317 * ==================================================================== 00318 */ 00319 00320 void 00321 Resource_Init ( void ) 00322 { 00323 /* Initialize elapsed time base: */ 00324 #if (1) 00325 00326 #if defined(_SOLARIS_SOLARIS) || defined(_LINUX_LINUX) 00327 gettimeofday(&start_time, NULL); 00328 #elif !defined(linux) 00329 gettimeofday(&start_time, NULL); 00330 #else 00331 gettimeofday(&start_time); 00332 #endif 00333 00334 #else 00335 start_time = time (0); 00336 #endif 00337 initialized = 1; 00338 00339 /* Initialize the process initialization structure: */ 00340 runtime.name = "Process"; 00341 Get_Resources ( &runtime.cur ); 00342 } 00343 00344 00345 /* ==================================================================== 00346 * 00347 * Resource_Alloc 00348 * 00349 * Allocate and initialize a resource structure. 00350 * 00351 * ==================================================================== 00352 */ 00353 00354 RSTATE * 00355 Resource_Alloc ( 00356 char *rname, 00357 RSTATE *parent 00358 ) 00359 { 00360 RSTATE *r; 00361 00362 r = (RSTATE *) calloc ( 1, sizeof(RSTATE) ); 00363 r->name = rname; 00364 r->dad = parent; 00365 00366 return r; 00367 } 00368 00369 /* ==================================================================== 00370 * 00371 * Resource_Accum 00372 * 00373 * Accumulate resource information. Valid requests are: 00374 * RR_Clear: Clear the delta information. 00375 * RR_Start: Start a new delta period (i.e. set current state). 00376 * RR_Stop: Add a delta period to the summary. 00377 * RR_End: Accumulate delta information to parent and clear. 00378 * The default for an unrecognized request is RR_Start. Note that if 00379 * there is no parent, RR_End is equivalent to RR_Clear. All of the 00380 * requests set current state. 00381 * 00382 * See Resource_Report and Resource_Time for reporting possibilities. 00383 * 00384 * ==================================================================== 00385 */ 00386 00387 void 00388 Resource_Accum ( RSTATE *r, RES_REQUEST req ) 00389 { 00390 /* If passed a NULL pointer, just return: */ 00391 if ( ! r ) return; 00392 00393 /* Get the current state: */ 00394 Get_Delta_Resource ( &curtime, &r->cur, &deltime ); 00395 00396 /* Do the right thing: */ 00397 switch ( req ) { 00398 case RR_Clear: Clear_Resource ( &r->del ); 00399 break; 00400 case RR_Start: break; 00401 case RR_Stop: Accum_Delta_Resource ( &deltime, &r->del ); 00402 break; 00403 case RR_End: if ( r->dad ) { 00404 Accum_Delta_Resource ( &r->del, &r->dad->del ); 00405 Clear_Resource ( &r->del ); 00406 } 00407 break; 00408 } 00409 00410 /* Reset the current state: */ 00411 r->cur = curtime; 00412 } 00413 00414 /* ==================================================================== 00415 * 00416 * Get_Time 00417 * 00418 * Return a pointer to the requesting timing structure. Returns NULL 00419 * if the request is not recognized. 00420 * 00421 * ==================================================================== 00422 */ 00423 00424 TIME_INFO * 00425 Get_Time ( 00426 RSTATE *r, 00427 RES_REQUEST req 00428 ) 00429 { 00430 switch ( req ) { 00431 case RR_Current_User: return &(r->cur.utime); 00432 case RR_Current_System: return &(r->cur.stime); 00433 case RR_Current_Elapsed: return &(r->cur.etime); 00434 case RR_Delta_User: return &(r->del.utime); 00435 case RR_Delta_System: return &(r->del.stime); 00436 case RR_Delta_Elapsed: return &(r->del.etime); 00437 } 00438 return 0; 00439 } 00440 00441 00442 /* ==================================================================== 00443 * 00444 * Get_Timer_Name 00445 * 00446 * Return the name string for a resource record. 00447 * 00448 * ==================================================================== 00449 */ 00450 00451 char * 00452 Get_Timer_Name ( 00453 RSTATE *r 00454 ) 00455 { 00456 return r->name; 00457 } 00458 00459 /* ==================================================================== 00460 * 00461 * Get_Memory 00462 * 00463 * Return the current or delta memory usage. 00464 * 00465 * ==================================================================== 00466 */ 00467 00468 INT 00469 Get_Memory ( 00470 RSTATE *r, 00471 RES_REQUEST req 00472 ) 00473 { 00474 switch ( req ) { 00475 case RR_Current_Memory: return r->cur.memory; 00476 case RR_Delta_Memory: return r->del.memory; 00477 } 00478 return 0; 00479 } 00480 00481 /* ==================================================================== 00482 * 00483 * Resource_Report 00484 * 00485 * Report resource usage. If the RSTATE structure pointer passed 00486 * is non-null, report its current or delta content, as requested. 00487 * If it is null, report the current process state. 00488 * 00489 * ==================================================================== 00490 */ 00491 00492 void 00493 Resource_Report ( 00494 FILE *file, 00495 RES_REQUEST func, 00496 RSTATE *r, 00497 char *title 00498 ) 00499 { 00500 RESOURCES *res; 00501 00502 /* Deal with NULL r: */ 00503 if ( ! r ) { 00504 res = &curtime; 00505 Get_Resources (res); 00506 00507 /* Otherwise select reportable structure using func: */ 00508 } else { 00509 switch ( func ) { 00510 case RR_Report_Delta: res = &(r->del); 00511 break; 00512 case RR_Report_Current: 00513 default: res = &(r->cur); 00514 break; 00515 } 00516 } 00517 00518 /* Report: */ 00519 if ( title && *title ) fprintf ( file, "%s\n", title ); 00520 fprintf ( file, 00521 #if (1) 00522 "\tuser:\t%4d.%06d\n\tsystem:\t%4d.%06d\n\telapsed: %4d.%06d\n", 00523 res->utime.secs, res->utime.usecs, 00524 res->stime.secs, res->stime.usecs, 00525 res->etime.secs, res->etime.usecs ); 00526 #else 00527 "\tuser:\t%4d.%03d\n\tsystem:\t%4d.%03d\n\telapsed: %4d.%02d\n", 00528 res->utime.secs, res->utime.usecs/1000, 00529 res->stime.secs, res->stime.usecs/1000, 00530 res->etime.secs, res->etime.usecs/10000 ); 00531 #endif 00532 fprintf ( file, "\tmemory:\t%8x\n\tfree:\t%8x\n", 00533 res->memory, res->freemem ); 00534 } 00535