NT4/private/sdktools/perftool/timer
2020-09-30 17:12:29 +02:00
..
win32 First commit 2020-09-30 17:12:29 +02:00
makefile First commit 2020-09-30 17:12:29 +02:00
readme First commit 2020-09-30 17:12:29 +02:00
sources First commit 2020-09-30 17:12:29 +02:00
timer.c First commit 2020-09-30 17:12:29 +02:00
timerw32.def First commit 2020-09-30 17:12:29 +02:00
updlib.cmd First commit 2020-09-30 17:12:29 +02:00

This directory and its subdirectories contain source and 
binary files for the timer support packages that can
be run across multiple platforms.  

NOTE:  The dll under CR286 can be run under Cruiser only,
since it uses the PerfView "thunked" timer.  For Sloop/Cutter 
programs, use the dll under the Sloop directory.  This uses
the new 16BitTmr.sys, a timer driver.  For using the Sloop/Cutter
timer, read the section titled "Using the Cutter Timer".

The directory is organized as follows:

1) .\ ->  
          a) timer.c      (single c source)

          b) makefile.rst (common for windows, CR286, Sloop and 
                           OS2 386 and WOW)

          c) makefile     (for Windows NT)

          d) sources      (  -do-  )

          e) The header file, timing.h, is under .\inc\.
 
2) .\win  (FOR WINDOWS)

          a) .\src      (contains the .asm files for init and 8253io, and the 
                         module def file)

          b) .\bin      (the binary timerwin.dll file)

3) .\WIN32  (FOR Win32 NT)

          a) .\src      (contains the .def file and an i386 sub-dir.
                         that has an asm file) 

          b) .\bin      (the binary file)

4) .\Sloop  (FOR Sloop apps)

          a) .\src      (contains the initializing .asm file, and the 
                         module def file)

          b) .\bin      (the binary timerslp.dll file)

5) .\cr286 (FOR 16 bit OS/2 Cruiser apps)

          a) .\src      (contains the initializing asm file
                         and the module def file)

          b) .\bin      (the binary timer286.dll file)
         
6) .\os2386 (FOR 32 bit OS/2 Cruiser apps)

          a) .\src      (contains the initializing and math .asm
                         files, and the module def file)

          b) .\bin      (the binary timer386.dll file)

7) .\wow  (FOR 16 bit WOW on Windows NT - built for Win 3.0)

          a) .\src      (contains the .asm and the 
                         module def file)

          b) .\bin      (the binary timerwow.dll file)
**********************************************************************

To Use a timer DLL:
------------------

To use one of the above binaries, please read the USAGE NOTES at the
end of this document.  Please copy the timing.h file from this
directory to the directory where you are building your application.
Copy the relevant .dll to your libpath.

It is essential that you define the type of system you are building
your application for, since the header file uses some special types
that are dependent on the system.  While compiling your application,
add the following flag: -DXXX where XXX stands for one of: 

          WIN       - for Windows applications on Windows 3.x.
          WIN32     - for Win32 applications.
          WOW16     - for Windows applications on Windows NT.
          SLOOP     - for 16 bit Sloop (OS/2 1.2, 1.3) applications
          OS2286    - for 16 bit Cruiser (OS/2 2.0) applications
          OS2386    - for 32 bit OS/2 applications


**********************************************************************

To build one of the dlls:
------------------------

If building a Windows, WOW, Sloop, Cutter, CR286 or OS/2 32 bit dll:
--------------------------------------------------------------

NOTE: To build for Wow on NT, you must be setup to build for Win 3.0
      and not Win 3.1.  Also, you need the special Windows libraries.
      These need to be built on NT.

a)   Copy the timer.c from this dir. and the timing.h from ..\inc\.
     to a local directory.  

b)   Also copy the "makefile.rst" from here to the same directory.  

c)   From ???\src copy the remaining files to the local directory, 
     where ??? represents win, Sloop, cr286 or os2386.

d)   Edit makefile.rst to define the system that you are making the
     dll for.  Eg. if you are making the dll for windows, remove
     the comment sign (#) from the line "WIN=TRUE" in the makefile
     and ensure that the other system defines (WOW16, SLOOP, OS2286 
     and OS2386) are commented out.  

f)   Type "nmake -f makefile.rst" and the dll will be created for
     you.   (Ensure that your development environment is set up for 
     the right system).

If building the Win32 dll:
-------------------------

a)   Copy timer.c, makefile and sources files found under this 
     directory and timing.h from ..\inc\. to a local directory.  

b)   tc the win32\src directory to your local directory.  This 
     will create an i386 sub-directory containing an asm file on 
     your local machine.

c)   From the directory where you have your sources file, type
     "build -xxx timerw32" from the command line, where xxx represents
     your target system.  It is 386 by default.

c)   A binary file "timerw32.dll" will be created along with the
     .obj file under .\xxx\obj where xxx is your target system.
     It is i386 by default.

Using the Cutter Timer: (For use on machines running OS/2 1.2x, 1.3x)
----------------------

Note:  This driver cannot be used when the DOS box is running.
So edit your config.sys file so that the line "PROTECTONLY=YES"
is present.

a)   Copy the 16BitTmr.* files from the .\sloop\bin directory
to your machine.  

b)   Edit your Config.sys file to add the line
"DEVICE=xxx\16BitTmr.sys,  where xxx is the full path name where
the driver resides.  

c)   Copy the timerslp.dll from the .\sloop\bin directory to your
libpath.

c)   Reboot your machine and use the timerslp.dll as explained
elsewhere.

In case you have any questions, or if you run into any problems, 
contact vaidy (936-7812).

*****************************************************************

USAGE NOTES
-----------

This document  describes the  usage of the functions available 
through the Timer.dll.  This dll can be  used by  all application  
programs  that  require  a microsecond timer.  Send all 
comments/suggestions to vaidy (ph. 936-7812) or 
JohnOw (ph. 936-5557).

1) TimerOpen:
   ---------

Description:  Opens a timer object and returns a handle for use
              in timing operations.

#include "timing.h"    /* for error codes */

    SHORT FAR PASCAL
    TimerOpen (
        SHORT far * phTimer,
        _TimerUnits TimerUnits
        );

    phTimer    - Address to which to return the handle to the 
                 timer.

    TimerUnits - Will be one of the enumerated types listed below, that 
                 determines the units for the elapsed time values
                 returned by TimerRead.  The selected units may be
                 greater or less than the underlying clock frequency:
 
                     typedef enum {
                         KILOSECONDS,
                         SECONDS,
                         MILLISECONDS,
                         MICROSECONDS,
                         TENTHMICROSECS,
                         NANOSECONDS,
                         TIMER_FREE
                     } _TimerUnits;

Remarks:  This call should be made by each application, every time
          a new timer is required.  This call should precede any 
          other timer function calls.  Each call to TimerOpen will 
          return a new handle, so that multiple threads within a 
          process may use different timers for measuring time.  
          The handle obtained from this call should be used by 
          the other timing functions, viz. TimerOpen and TimerRead.  
          The handle is an index into an array of timer objects that
          are made available by this function.

          The number of timers will depend upon the implementation,
          but will usually be in the order of 100's or 1000's per
          process.  Use TimerClose to release unused timers in case
          there is a need to reuse a large number of timers.  Any
          opened timers will be automatically closed when the process
          using them terminates.
          
          The scaling factor decides the units of the time returned 
          by TimerRead.  The calling application should be careful 
          over the choice of units, to avoid possible overflow 
          and consequently, incorrect results.

Return:   0 if a timer handle is made available.

          An error code, on failure, which may be one of: 

              TIMERERR_TIMER_NOT_AVAILABLE
              TIMERERR_NO_MORE_HANDLES
              TIMERERR_INVALID_UNITS

See also: TimerInit, TimerRead, TimerClose.

2) TimerInit:
   ---------

Description:  Initializes the elements of an internal structure
              to the current time, obtained from the low level
              timer.

#include "timing.h"    /* for error codes */

    SHORT FAR PASCAL
    TimerInit (
        SHORT hTimer
        );

    hTimer - The handle, to the timer, that was made available by
             a call to TimerOpen.

Remarks:  This function should be called after opening the timer
          object.  Each call to this function should just precede
          the operation that is being timed.  Passing a handle
          to a timer object that has not been opened, will result
          in an error code being returned.  

Return:   0 if the call is successful.

          An error code is returned, if the call failed.  The error code is:

              TIMERERR_INVALID_HANDLE

See also: TimerOpen, TimerRead, TimerClose.

3) TimerRead:
   ---------

Description:  Returns the elapsed time since the previous call to
              TimerInit.

#include "timing.h"    /* for error codes */

    ULONG FAR PASCAL
    TimerRead (
        SHORT hTimer
        );

    hTimer - handle to the timer object that was opened with a call
             to TimerOpen and initialized by calling TimerInit.

Remarks:  This call should have been preceded by a call to TimerOpen
          and TimerInit.  This call gets the current time from the
          low level timer and, using the initialized values in the
          internal structure, computes the elapsed time from the
          previous call to TimerInit.  Any number of calls to 
          TimerRead may be made, as long they are preceded by at least
          one call to TimerInit.  A timer overflow error code is 
          returned if the scaling factor was so chosen as to
          cause an overflow in the time being returned.  A bad
          handle to this call will also result in an error code 
          being returned.  

Return:   A successful call returns the elapsed time since the last
          call to TimerInit.  

          A failure, either invalid handle or overflow, is indicated 
          by returning the maximum ULONG value (0xffffffff).

See also: TimerOpen, TimerInit, TimerClose.

4) TimerClose:
   ----------

Description:  Closes a timer object that was opened with a call to
              TimerInit.

#include "timing.h"

    SHORT FAR PASCAL
    TimerClose (
        SHORT hTimer
        );

    hTimer - Handle to the timer object that was opened with a call to
             TimerInit.
  
Remarks:  This function closes the specfied timer object and returns 
          it to the pool of available timer objects.  The object then 
          is considered as available for use, when a call to TimerOpen is
          made.
          
Return:   0 if the timer was successfully closed.

          An error code on failure:
            
              TIMERERR_INVALID_HANDLE

See also: TimerOpen, TimerInit, TimerRead.

----------------------------------------------------------------------

Usage:
-----

Test Application Body:

{
    SHORT hTimerHandle1;
    SHORT sRetVal;

    if ((sRetVal = TimerOpen ((SHORT far *) &hTimerHandle1, MICROSECONDS)) {
        could not open timer 
        Do not perform any timing operation
    }
    :
    :
    Do Stuff
    :
    :
    /* Commence timing operations */
    
    for (some conditions) {
        TimerInit (hTimerHandle1);
        Do Timed Operation
        ulElapsedTime = TimerRead (hTimerHandle1);
    }

    if (TimerClose (hTimerHandle1)) {
        Could not close timer.  Check handle and take corrective
        action   
    }
    :
    :
}

--------------------------------------------------------------------

Debugging Routine
-----------------

5) TimerReport:
   -----------

Description:  Used as a debugging tool, this routine fetches the
              the time from the last call to TimerInit and TimerRead.


#include "timing.h"    /* for error codes */

    SHORT BOOL PASCAL
    TimerReport (
        PSZ pszReportString,
        SHORT hHandleHandle;
        );

    pszReportString - Address to which to return the string containing
                      the time obtained in the last call to
                      TimerInit, TimerRead and the time returned
                      from the last call to TimerRead.

    hTimerHandle    - Handle to the timer from whom the information is
                      sought.
 
Remarks:  This call can be used as a debugging device in case there
          is a doubt as to what values are being returned by the
          timer.  This routine should normally be called after a call
          to TimerRead.  The routines TimerInit and TimerRead call an
          underlying timer to obtain clock tics/time.  The call
          to TimerRead uses this information and returns the
          time (clock tics are converted to time using the clock
          frequency on NT) as a ULONG.  TimerReport obtains the 
          information stored by the last call to TimerInit and 
          last call to TimerRead.  It also obtains the time that 
          is returned by TimerRead (after converting clock tics 
          to time whereever applicable, and subtracting the 
          overhead) and prints the information into a string whose 
          address is passed in as the first parameter to this routine.

          The format of the string is as follows:

          "Init Time %lu:%lu Current Time %lu:%lu Returned Time %lu".
       
          Both the times are printed as 64 bit values (high:low).

          On NT, the init and current times are clock tics while
          the returned time is in time units.  The returned time
          will be about 0.8 times the difference between the clock
          tics.

          Note that the returned time takes into account the calling
          overhead also and hence, is not exactly the difference
          between the current time and init time.

Return:   TRUE if timer exists and has been opened.
          FALSE otherwise.

See also: TimerOpen, TimerInit, TimerRead, TimerClose.

-------------------------------------------------------------------------

Additional Routines:
-------------------

6) TimerQueryPerformanceCounter:
   ----------------------------

Description:  Makes the raw counts, (tics), and the timer frequency
              available.

#include "timing.h"    /* for error codes */

    VOID BOOL PASCAL
    TimerQueryPerformanceCounter (
        PQWORD pCurrentTic,
        PQWORD pFrequency [OPTIONAL]
        );

    pCurrentTic     - Address to a 64-bit location to which the raw
                      tic count is written on returning from the call.
                      PQWORD is defined a PLARGE_INTEGER for the Win32
                      platform in timing.h.  PQWORD is a pointer to a
                      QWORD structure (consisting of two ULONG
                      elements), on Win 3.x and OS/2 platforms.

    pFrequency      - Address to a 64-bit location to which the 
                      timer frequency is written on returning from
                      the call, if this pointer is not NULL.  This
                      is OPTIONAL.  If NULL, only the current tic
                      count is written to the location pointed by 
                      pCurrentTic.
 
Remarks:  This call can be used by any application to return the
          timer frequency and current tic count.  The frequency needs
          to be obtained only once.  All other calls to this routine
          can have NULL as the second parameter.

          The calling application should perform its own calibration
          to determine the overhead when this routine is called
          back-to-back.  

          To time an operation, this routine should immediately
          precede and follow the operation.  The difference of
          the tic counts should be computed.  The overhead for
          calling this routine back to back should be subtracted from
          this difference, and then divided by the frequency to
          obtain the time in seconds.  (To obtain the time in 
          microseconds, multiply the raw tics by a million before 
          dividing by the frequency.  To convert the time to units 
          other than seconds, the conversion factor should be applied
          before performing the division by the frequency, to 
          avoid loss of precision).

          There is no need to open or initialize the timer if this
          routine is used to obtain the tic count.
          
Return:   None.

See also: TimerOpen, TimerInit, TimerRead, TimerClose.

7) TimerConvertTicsToUSec:
   ----------------------

Description:  Used as a utility tool, this routine returns
              the time in microseconds when the tic difference and
              timer frequency are passed in.


#include "timing.h"    /* for error codes */

    ULONG BOOL PASCAL
    TimerConvertTicsToUSec (
        ULONG ulTicDifference,
        ULONG ulTimerFreq;
        );

    ulTicDifference - The duration of an operation in tics.  This is
                      obtained by calling
                      TimerQueryPerformanceCounter immediately before
                      and following the desired operation and
                      subtracting the overhead of calling 
                      TimerQueryPerformanceCounter back to back.

    ulTimerFreq    -  The timer frequency. This is obtained by
                      calling TimerQueryPerformanceCounter.
 
Remarks:  This routine just accepts the duration of an operation in
          timer counts and the timer frequency.  It returns the
          actual time in microseconds corresponding to the tic
          count.  

          There is no need to open or initialize the timer if this
          routine is used to obtain the tic count.

Return:   The time in microseconds that corresponds to the input
          tics and frequency.

          A zero if the frequency is zero.

See also: TimerOpen, TimerInit, TimerRead, TimerClose.