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.