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 #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
00055
00056
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
00072
00073
00074
00075
00076
00077 struct resources {
00078 TIME_INFO utime;
00079 TIME_INFO stime;
00080 TIME_INFO etime;
00081 INT memory;
00082 INT freemem;
00083 };
00084
00085
00086
00087
00088
00089 struct rstate {
00090 RESOURCES cur;
00091 RESOURCES del;
00092 struct rstate *dad;
00093 char *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
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;
00116 #endif
00117 static INT initialized = 0;
00118
00119
00120
00121
00122
00123
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
00146
00147
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
00164 if ( ! initialized ) Resource_Init ();
00165
00166
00167 #if (1)
00168
00169
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
00186 #if (1)
00187 getrusage (RUSAGE_SELF, &tbuf);
00188 #else
00189 (void) times (&tbuf);
00190 #endif
00191
00192
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
00210 r->memory = (INT) sbrk(0);
00211 r->freemem = 0;
00212 }
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223 static void
00224 Get_Delta_Time (
00225 TIME_INFO *current,
00226 TIME_INFO *base,
00227 TIME_INFO *delta
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
00242
00243
00244
00245
00246
00247
00248 static void
00249 Get_Delta_Resource (
00250 RESOURCES *current,
00251 RESOURCES *base,
00252 RESOURCES *delta
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
00267
00268
00269
00270
00271
00272
00273 static void
00274 Accum_Delta_Time (
00275 TIME_INFO *delta,
00276 TIME_INFO *summary
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
00291
00292
00293
00294
00295
00296
00297 static void
00298 Accum_Delta_Resource (
00299 RESOURCES *delta,
00300 RESOURCES *summary
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
00313
00314
00315
00316
00317
00318
00319
00320 void
00321 Resource_Init ( void )
00322 {
00323
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
00340 runtime.name = "Process";
00341 Get_Resources ( &runtime.cur );
00342 }
00343
00344
00345
00346
00347
00348
00349
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
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387 void
00388 Resource_Accum ( RSTATE *r, RES_REQUEST req )
00389 {
00390
00391 if ( ! r ) return;
00392
00393
00394 Get_Delta_Resource ( &curtime, &r->cur, &deltime );
00395
00396
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
00411 r->cur = curtime;
00412 }
00413
00414
00415
00416
00417
00418
00419
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
00445
00446
00447
00448
00449
00450
00451 char *
00452 Get_Timer_Name (
00453 RSTATE *r
00454 )
00455 {
00456 return r->name;
00457 }
00458
00459
00460
00461
00462
00463
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
00484
00485
00486
00487
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
00503 if ( ! r ) {
00504 res = &curtime;
00505 Get_Resources (res);
00506
00507
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
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