00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #ifdef _KEEP_RCS_ID
00037 static const char source_file[] = __FILE__;
00038 static const char rcs_id[] = "$Source: /depot/CVSROOT/javi/src/sw/cmplr/common/util/resource.c,v $ $Revision: 1.1 $";
00039 #endif
00040
00041 #if (1)
00042 # include <sys/time.h>
00043 #ifdef __MINGW32__
00044 #include<time.h>
00045 #include<sys/types.h>
00046 #include<sys/timeb.h>
00047 #else
00048 # include <sys/resource.h>
00049 typedef struct rusage time_buf_t;
00050 #endif
00051 #else
00052 # include <sys/param.h>
00053 # include <sys/types.h>
00054 # include <sys/times.h>
00055 # include <time.h>
00056 typedef struct tms time_buf_t;
00057 #endif
00058
00059 #include <unistd.h>
00060 #include <string.h>
00061
00062
00063
00064
00065 #ifdef MAX
00066 #undef MAX
00067 #endif
00068 #ifdef MIN
00069 #undef MIN
00070 #endif
00071
00072 #include "defs.h"
00073 #include "resource.h"
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 struct resources {
00085 TIME_INFO utime;
00086 TIME_INFO stime;
00087 TIME_INFO etime;
00088
00089
00090
00091
00092
00093
00094 INTPTR memory;
00095 INTPTR freemem;
00096 };
00097
00098
00099
00100
00101
00102 struct rstate {
00103 RESOURCES cur;
00104 RESOURCES del;
00105 struct rstate *dad;
00106 const char *name;
00107 };
00108
00109 static void Clear_Resource ( RESOURCES *r );
00110 static void Get_Resources ( RESOURCES *r );
00111 static void Get_Delta_Time ( TIME_INFO *current,
00112 TIME_INFO *base,
00113 TIME_INFO *delta );
00114 static void Get_Delta_Resource ( RESOURCES *current,
00115 RESOURCES *base,
00116 RESOURCES *delta );
00117 static void Accum_Delta_Time ( TIME_INFO *delta, TIME_INFO *summary );
00118 static void Accum_Delta_Resource ( RESOURCES *delta,
00119 RESOURCES *summary );
00120
00121
00122 #ifndef __MINGW32__
00123 static time_buf_t tbuf;
00124 #endif
00125 static RESOURCES curtime, deltime;
00126 static RSTATE runtime;
00127 #if (1)
00128 #ifdef __MINGW32__
00129 static struct _timeb start_time;
00130 #else
00131 static struct timeval start_time;
00132 #endif
00133 #else
00134 static INT start_time;
00135 #endif
00136 static INT initialized = 0;
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 static void
00148 Clear_Resource (
00149 RESOURCES *r
00150 )
00151 {
00152 r->utime.secs = 0;
00153 r->utime.usecs = 0;
00154 r->stime.secs = 0;
00155 r->stime.usecs = 0;
00156 r->etime.secs = 0;
00157 r->etime.usecs = 0;
00158 r->memory = 0;
00159 r->freemem = 0;
00160 }
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 static void
00172 Get_Resources (
00173 RESOURCES *r
00174 )
00175 {
00176 #if (1)
00177 #ifdef __MINGW32__
00178 struct _timeb now;
00179 #else
00180 struct timeval now;
00181 #endif
00182 #else
00183 INT secs, frac;
00184 #endif
00185
00186
00187 if ( ! initialized ) Resource_Init ();
00188
00189
00190 #ifdef __MINGW32__
00191 _ftime(&now);
00192 r->etime.secs = now.time - start_time.time;
00193 r->etime.usecs = (now.millitm - start_time.millitm) * 1000;
00194
00195 r->utime.secs = clock() / 2;
00196 r->stime.secs = clock() / 2;
00197 r->utime.usecs = 0;
00198 r->stime.usecs = 0;
00199 #else
00200 #if (1)
00201 #if !(defined(linux) || defined(BUILD_OS_DARWIN))
00202 gettimeofday(&now);
00203 #else
00204 gettimeofday(&now, NULL);
00205 #endif
00206 r->etime.secs = now.tv_sec - start_time.tv_sec;
00207 r->etime.usecs = now.tv_usec - start_time.tv_usec;
00208 #else
00209 r->etime.secs = time (0) - start_time;
00210 r->etime.usecs = 0;
00211 #endif
00212
00213
00214 #if (1)
00215 getrusage (RUSAGE_SELF, &tbuf);
00216 #else
00217 (void) times (&tbuf);
00218 #endif
00219
00220
00221 #if (1)
00222 r->utime.secs = tbuf.ru_utime.tv_sec;
00223 r->utime.usecs = tbuf.ru_utime.tv_usec;
00224 r->stime.secs = tbuf.ru_stime.tv_sec;
00225 r->stime.usecs = tbuf.ru_stime.tv_usec;
00226 #else
00227 secs = tbuf.tms_utime / HZ;
00228 frac = tbuf.tms_utime - (secs*HZ);
00229 r->utime.secs = secs;
00230 r->utime.usecs = frac * (1000000/HZ);
00231 secs = tbuf.tms_stime / HZ;
00232 frac = tbuf.tms_stime - (secs*HZ);
00233 r->stime.secs = secs;
00234 r->stime.usecs = frac * (1000000/HZ);
00235 #endif
00236
00237
00238 r->memory = (INTPTR) sbrk(0);
00239 #endif
00240 r->freemem = 0;
00241 }
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 static void
00253 Get_Delta_Time (
00254 TIME_INFO *current,
00255 TIME_INFO *base,
00256 TIME_INFO *delta
00257 )
00258 {
00259 delta->secs = current->secs - base->secs;
00260 delta->usecs = current->usecs - base->usecs;
00261 if ( delta->usecs < 0 ) {
00262 delta->usecs += 1000000;
00263 delta->secs --;
00264 }
00265 }
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 static void
00278 Get_Delta_Resource (
00279 RESOURCES *current,
00280 RESOURCES *base,
00281 RESOURCES *delta
00282 )
00283 {
00284 Get_Resources ( current );
00285
00286 Get_Delta_Time ( ¤t->utime, &base->utime, &delta->utime );
00287 Get_Delta_Time ( ¤t->stime, &base->stime, &delta->stime );
00288 Get_Delta_Time ( ¤t->etime, &base->etime, &delta->etime );
00289 delta->memory = current->memory - base->memory;
00290 delta->freemem = current->freemem - base->freemem;
00291 }
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 static void
00303 Accum_Delta_Time (
00304 TIME_INFO *delta,
00305 TIME_INFO *summary
00306 )
00307 {
00308 summary->secs += delta->secs;
00309 summary->usecs += delta->usecs;
00310 if ( summary->usecs >= 1000000 ) {
00311 summary->usecs -= 1000000;
00312 summary->secs ++;
00313 }
00314 }
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 static void
00327 Accum_Delta_Resource (
00328 RESOURCES *delta,
00329 RESOURCES *summary
00330 )
00331 {
00332 Accum_Delta_Time ( &delta->utime, &summary->utime );
00333 Accum_Delta_Time ( &delta->stime, &summary->stime );
00334 Accum_Delta_Time ( &delta->etime, &summary->etime );
00335 summary->memory = MAX(summary->memory,delta->memory);
00336 summary->freemem += delta->freemem;
00337 }
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349 void
00350 Resource_Init ( void )
00351 {
00352
00353 #ifdef __MINGW32__
00354 _ftime(&start_time);
00355 #else
00356 #if (1)
00357 #if !(defined(linux) || defined(BUILD_OS_DARWIN))
00358 gettimeofday(&start_time);
00359 #else
00360 gettimeofday(&start_time, NULL);
00361 #endif
00362 #else
00363 start_time = time (0);
00364 #endif
00365 #endif
00366 initialized = 1;
00367
00368
00369 runtime.name = "Process";
00370 Get_Resources ( &runtime.cur );
00371 }
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383 RSTATE *
00384 Resource_Alloc (
00385 const char *rname,
00386 RSTATE *parent
00387 )
00388 {
00389 RSTATE *r;
00390
00391 r = (RSTATE *) calloc ( 1, sizeof(RSTATE) );
00392 r->name = rname;
00393 r->dad = parent;
00394
00395 return r;
00396 }
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416 void
00417 Resource_Accum ( RSTATE *r, RES_REQUEST req )
00418 {
00419
00420 if ( ! r ) return;
00421
00422
00423 Get_Delta_Resource ( &curtime, &r->cur, &deltime );
00424
00425
00426 switch ( req ) {
00427 case RR_Clear: Clear_Resource ( &r->del );
00428 break;
00429 case RR_Start: break;
00430 case RR_Stop: Accum_Delta_Resource ( &deltime, &r->del );
00431 break;
00432 case RR_End: if ( r->dad ) {
00433 Accum_Delta_Resource ( &r->del, &r->dad->del );
00434 Clear_Resource ( &r->del );
00435 }
00436 break;
00437 }
00438
00439
00440 r->cur = curtime;
00441 }
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453 TIME_INFO *
00454 Get_Time (
00455 RSTATE *r,
00456 RES_REQUEST req
00457 )
00458 {
00459 switch ( req ) {
00460 case RR_Current_User: return &(r->cur.utime);
00461 case RR_Current_System: return &(r->cur.stime);
00462 case RR_Current_Elapsed: return &(r->cur.etime);
00463 case RR_Delta_User: return &(r->del.utime);
00464 case RR_Delta_System: return &(r->del.stime);
00465 case RR_Delta_Elapsed: return &(r->del.etime);
00466 }
00467 return 0;
00468 }
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480 const char *
00481 Get_Timer_Name (
00482 RSTATE *r
00483 )
00484 {
00485 return r->name;
00486 }
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497 INTPTR
00498 Get_Memory (
00499 RSTATE *r,
00500 RES_REQUEST req
00501 )
00502 {
00503 switch ( req ) {
00504 case RR_Current_Memory: return r->cur.memory;
00505 case RR_Delta_Memory: return r->del.memory;
00506 }
00507 return 0;
00508 }
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521 void
00522 Resource_Report (
00523 FILE *file,
00524 RES_REQUEST func,
00525 RSTATE *r,
00526 char *title
00527 )
00528 {
00529 RESOURCES *res;
00530
00531
00532 if ( ! r ) {
00533 res = &curtime;
00534 Get_Resources (res);
00535
00536
00537 } else {
00538 switch ( func ) {
00539 case RR_Report_Delta: res = &(r->del);
00540 break;
00541 case RR_Report_Current:
00542 default: res = &(r->cur);
00543 break;
00544 }
00545 }
00546
00547
00548 if ( title && *title ) fprintf ( file, "%s\n", title );
00549 fprintf ( file,
00550 #if (1)
00551 "\tuser:\t%4d.%06d\n\tsystem:\t%4d.%06d\n\telapsed: %4d.%06d\n",
00552 res->utime.secs, res->utime.usecs,
00553 res->stime.secs, res->stime.usecs,
00554 res->etime.secs, res->etime.usecs );
00555 #else
00556 "\tuser:\t%4d.%03d\n\tsystem:\t%4d.%03d\n\telapsed: %4d.%02d\n",
00557 res->utime.secs, res->utime.usecs/1000,
00558 res->stime.secs, res->stime.usecs/1000,
00559 res->etime.secs, res->etime.usecs/10000 );
00560 #endif
00561 fprintf ( file, "\tmemory:\t%8x\n\tfree:\t%8x\n",
00562 res->memory, res->freemem );
00563 }
00564