home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
howlong.zip
/
HOWLONG.C
Wrap
C/C++ Source or Header
|
1999-12-16
|
7KB
|
274 lines
/*
* HowLong - measure execution times of processes via DosTmr builtin funcs
* (c) 1999 by Heinz Repp
*/
#include <stdio.h>
#include <stdlib.h>
#if defined (__OS2__)
#define INCL_DOSPROFILE
#define INCL_DOSPROCESS
#include <os2.h>
#elif defined (_WIN32)
#include <win.h>
#include <mapidefs.h>
#define ulLo LowPart
#define ulHi HighPart
typedef LARGE_INTEGER QWORD;
#else
#error Compiles only with OS/2 or 32 bit Windows!
#endif
QWORD Ticks2Secs (QWORD ticks, ULONG ticks_per_sec)
{
ULONG interlow;
int tpsbits, nextbits, bitoffset;
ldiv_t ldivres;
/* findout how many bits ticks_per_sec uses */
tpsbits = 0;
while (ticks_per_sec >> ++tpsbits);
nextbits = 31 - tpsbits; /* long int of ldiv_t has 31 bit */
/* divide ticks by ticks_per_seconds (quotient: seconds,
remainder: ticks left to form the fraction of one second) */
bitoffset = 32;
ldivres.rem = ticks.ulHi % ticks_per_sec; /* wraparound at 2^32 seconds */
ticks.ulHi = 0;
do
{
bitoffset -= nextbits;
ldivres = ldiv (ldivres.rem << nextbits |
ticks.ulLo >> bitoffset & ~(~0ul << nextbits),
ticks_per_sec);
ticks.ulHi |= ldivres.quot << bitoffset;
} while (bitoffset > nextbits);
ldivres = ldiv (ldivres.rem << bitoffset |
ticks.ulLo & ~(~0ul << bitoffset),
ticks_per_sec);
ticks.ulHi |= ldivres.quot;
/* multiply remainder by one million */
ticks.ulLo = ((unsigned long) ldivres.rem & ~(~0ul << 12)) *
1000000ul;
interlow = 0ul;
bitoffset = 0;
while (bitoffset + 12 < tpsbits)
{
interlow |= (ticks.ulLo & ~(~0ul << 12)) << bitoffset;
ticks.ulLo >>= 12;
bitoffset += 12;
ticks.ulLo += ((unsigned long) ldivres.rem >> bitoffset & ~(~0ul << 12)) *
1000000ul;
}
interlow |= ticks.ulLo << bitoffset;
ticks.ulLo >>= 32 - bitoffset;
/* add ticks_per_sec/2 for exact rounding */
interlow += ticks_per_sec >> 1;
if (interlow < ticks_per_sec) /* overflow */
ticks.ulLo++;
/* divide intermediate by ticks_per_seconds (quotient: microseconds) */
bitoffset = tpsbits - 11;
ldivres = ldiv (ticks.ulLo << (32 - bitoffset) | interlow >> bitoffset,
ticks_per_sec);
ticks.ulLo = ldivres.quot << bitoffset;
while (bitoffset > nextbits)
{
bitoffset -= nextbits;
ldivres = ldiv (ldivres.rem << nextbits |
interlow >> bitoffset & ~(~0ul << nextbits),
ticks_per_sec);
ticks.ulLo |= ldivres.quot << bitoffset;
}
ticks.ulLo |= (ldivres.rem << bitoffset |
interlow & ~(~0ul << bitoffset)) /
ticks_per_sec;
/* correct if rounding caused overflow */
if (ticks.ulLo >= 1000000ul)
{
ticks.ulLo -= 1000000ul;
ticks.ulHi++;
}
return ticks;
}
int main (int argc, char *argv[])
{
UCHAR command[300];
QWORD start, stop;
ULONG tfreq;
#if defined (__OS2__)
UCHAR reserr[CCHMAXPATH] = {0};
RESULTCODES rescode;
PID ended;
#elif defined (_WIN32)
PROCESS_INFORMATION pInfo;
STARTUPINFO sInfo;
DWORD exitCode;
#endif
/* check for commandline args */
if (argc < 2)
{
printf ("Usage: %s <executable> [<arguments> ...]\n", argv[0]);
#if defined (__OS2__)
DosExit (EXIT_PROCESS, 1);
#elif defined (_WIN32)
ExitProcess (1);
#endif
}
/* construct command strings: program name and arguments */
{
register char *src, *dst;
int i;
BOOL flag = TRUE;
/* 1st argument = target program;
flag means it is specified without extension */
src = argv[1];
dst = command;
while (*src)
{
switch (*dst++ = *src++)
{
case '.':
/* dot in program name means extension is explicitly stated */
flag = FALSE;
break;
case '\\':
case '/':
/* ignore any dots before last path delimiter */
flag = TRUE;
}
}
/* if no extension given: append '.exe' */
if (flag)
{
*dst++ = '.';
*dst++ = 'e';
*dst++ = 'x';
*dst++ = 'e';
}
#if defined (__OS2__)
/* append null */
*dst = 0;
#elif defined (_WIN32)
/* insert space */
*dst = ' ';
#endif
/* any further arguments = target program arguments;
flag means that argument has one or more spaces */
if (argc > 2)
{
i = 2;
do
{
flag = FALSE;
src = argv[i];
while (*src)
{
if (*src == ' ')
{
flag = TRUE;
break;
}
src++;
}
src = argv[i];
/* if spaces in argument: surround it with double quotes */
if (flag)
*++dst = '\"';
while (*++dst = *src++);
if (flag)
*dst++ = '\"';
*dst = ' ';
} while (++i < argc);
}
#if defined (__OS2__)
else
dst++;
#endif
*dst = 0; /* terminate argument string */
#if defined (__OS2__)
*++dst = 0; /* terminate command */
#endif
}
#if defined (__OS2__)
if (DosExecPgm (reserr, sizeof (reserr), EXEC_ASYNCRESULT,
command, NULL, &rescode, command))
#elif defined (_WIN32)
sInfo.cb = sizeof(STARTUPINFO);
sInfo.lpReserved = NULL;
sInfo.lpReserved2 = NULL;
sInfo.cbReserved2 = 0;
sInfo.lpDesktop = NULL;
sInfo.lpTitle = NULL;
sInfo.dwFlags = 0;
sInfo.dwX = 0;
sInfo.dwY = 0;
sInfo.dwFillAttribute = 0;
sInfo.wShowWindow = SW_SHOW;
if (! CreateProcess(NULL, command, NULL, NULL, FALSE, 0, NULL, NULL,
&sInfo, &pInfo))
#endif
{
printf ( "Unable to run <%s>.\n", command);
}
else
{
#if defined (__OS2__)
DosTmrQueryTime (&start);
DosWaitChild (DCWA_PROCESS, DCWW_WAIT,
&rescode, &ended, rescode.codeTerminate);
DosTmrQueryTime (&stop);
#elif defined (_WIN32)
QueryPerformanceCounter (&start);
WaitForSingleObject (pInfo.hProcess, INFINITE);
QueryPerformanceCounter (&stop);
GetExitCodeProcess (pInfo.hProcess, &exitCode);
#endif
/* subtract start time ticks from stop time ticks */
stop.ulHi -= start.ulHi;
if (stop.ulLo < start.ulLo) stop.ulHi--;
stop.ulLo -= start.ulLo;
/* get timer ticks per second */
#if defined (__OS2__)
DosTmrQueryFreq (&tfreq);
#elif defined (_WIN32)
QueryPerformanceFrequency (&start);
tfreq = start.ulLo;
#endif
/* convert to seconds and microseconds */
stop = Ticks2Secs (stop, tfreq);
printf ("\n<%s> ended after %lu.%06lu sec with rc=%lu.\n",
argv[1], stop.ulHi, stop.ulLo,
#if defined (__OS2__)
rescode.codeResult
#elif defined (_WIN32)
exitCode
#endif
);
}
return 0;
}