532 lines
18 KiB
Plaintext
532 lines
18 KiB
Plaintext
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.
|
|
|