/* * runstats.c - * * This file provides a single procedure that returns a string * containing the amount of user and system time used so far, * as well as the size of the data area. * * ********************************************************************* * * Copyright (C) 1985, 1990 Regents of the University of California. * * * Permission to use, copy, modify, and distribute this * * * software and its documentation for any purpose and without * * * fee is hereby granted, provided that the above copyright * * * notice appear in all copies. The University of California * * * makes no representations about the suitability of this * * * software for any purpose. It is provided "as is" without * * * express or implied warranty. Export of this software outside * * * of the United States of America may require an export license. * * ********************************************************************* */ #ifndef lint static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/utils/runstats.c,v 1.2 2009/05/13 15:03:18 tim Exp $"; #endif /* not lint */ #include #include #ifdef HAVE_SYS_TIME_H #include #endif #include #include #include "utils/magic.h" #include "utils/runstats.h" /* Library imports: */ #ifdef CYGWIN extern char *sbrk(); extern int end; #else int end; #endif /* * ---------------------------------------------------------------------------- * * RunStats -- * * This procedure collects information about the process. * Depending on the flags provided, the following information is * returned: * * RS_TCUM -- cumulative user and system time * RS_TINCR -- difference between current cumulative user and system * time and that when RunStats was last called with RS_TINCR * as a flag. * RS_MEM -- number of bytes in the heap area. * * Results: * The return value is a string of the form "[ ... ...]", * where contains the information specified by the flags. * Times are of the form "mins:secsu mins:secss", where the first * time is the amount of user-space CPU time this process has * used, and the second time is the amount of system time used. * Memory is specified by a string of the form "Nk", where N * is the number of kilobytes of heap area used so far. * * Side Effects: * If RS_TINCR is specified, the parameters lastt and deltat * are set (if they are both non-NULL). Both point to tms structs; * the one pointed to by deltat is set to the difference between * the current user/system time and the time given in the tms struct * pointed to by lastt; the one pointed to by lastt is then set to * the current user/system time. * * ---------------------------------------------------------------------------- */ char * RunStats( int flags, struct tms *lastt, struct tms *deltat) { struct tms buffer; static char string[100]; int umins, usecs, smins, ssecs, udsecs, sdsecs; pointertype size; char *sp = string; *sp = '\0'; times(&buffer); if (flags & RS_TCUM) { umins = buffer.tms_utime; umins = (umins+30)/60; usecs = umins % 60; umins = umins/60; smins = buffer.tms_stime; smins = (smins+30)/60; ssecs = smins % 60; smins = smins/60; sprintf(sp, "%d:%02du %d:%02ds", umins, usecs, smins, ssecs); while (*sp) sp++; } if (flags & RS_TINCR) { umins = buffer.tms_utime - lastt->tms_utime; udsecs = umins % 6; umins = (umins+30)/60; usecs = umins % 60; umins = umins/60; smins = buffer.tms_stime - lastt->tms_stime; sdsecs = smins % 6; smins = (smins+30)/60; ssecs = smins % 60; smins = smins/60; if (deltat != (struct tms *) NULL) { deltat->tms_utime = buffer.tms_utime - lastt->tms_utime; deltat->tms_stime = buffer.tms_stime - lastt->tms_stime; lastt->tms_utime = buffer.tms_utime; lastt->tms_stime = buffer.tms_stime; } if (sp != string) *sp++ = ' '; sprintf(sp, "%d:%02d.%du %d:%02d.%ds", umins, usecs, udsecs, smins, ssecs, sdsecs); while (*sp) sp++; } #ifndef CYGWIN // Ignoring this under cygwin instead of trying to find a workaround if (flags & RS_MEM) { size = (((pointertype)sbrk(0) - (pointertype) &end) + 512)/1024; if (sp != string) *sp++ = ' '; sprintf(sp, "%dk", (int)size); } #endif return (string); } /* * ---------------------------------------------------------------------------- * * RunStatsRealTime -- * * Reports the real time, both since the first invocation and incremental * since the last invocation. * * Results: * A statically allocated string of the form: * x:xx.x x:xx.x * where the first number is the amount of elapsed real time since the * first call to this routine, and the second is the amount of elapsed * real time since the lastest call to this routine. * * Side Effects: * None. * * ---------------------------------------------------------------------------- */ char * RunStatsRealTime(void) { struct timeval curtime; static struct timeval firsttime, lasttime; static int havetime = 0; long totm, tots, tott, incm, incs, inct; struct timezone dummyz; static char buf[50]; gettimeofday(&curtime, &dummyz); if (!havetime) { havetime = 1; firsttime = curtime; lasttime = curtime; } /* * Compute time differences in minutes, seconds, and tenths. */ totm = (curtime.tv_sec - firsttime.tv_sec) / 60; tots = (curtime.tv_sec - firsttime.tv_sec) % 60; tott = curtime.tv_usec - firsttime.tv_usec; while (tott < 0) { tots--; tott += 1000000; } while (tots < 0) { tots += 60; totm--; } tott = (tott + 50000) / 100000; while (tott >= 10) { tott -= 10; tots++; } while (tots >= 60) { tots -= 60; totm++; } incm = (curtime.tv_sec - lasttime.tv_sec) / 60; incs = (curtime.tv_sec - lasttime.tv_sec) % 60; inct = curtime.tv_usec - lasttime.tv_usec; while (inct < 0) { incs--; inct += 1000000; } while (incs < 0) { incs += 60; incm--; } inct = (inct + 50000) / 100000; while (inct >= 10) { inct -= 10; incs++; } while (incs >= 60) { incs -= 60; incm++; } sprintf(buf, "%ld:%02ld.%ld %ld:%02ld.%ld", totm, tots, tott, incm, incs, inct); lasttime = curtime; return buf; }