Introduction
This DLL provides fifteen routines to satisfy application program requirements for timers and timed activities in a C/C++ and VB environment. The praxis is that 150 timer slots should be enough for any application. Each timer may be set up to raise an event-flag, execute a function (on the ticker thread), or spin off a thread. A timer is allocated a number (i.e., 1 to 150) on creation. Timers may be cancelled or modified by timer number.
Background
At initialization, two threads are spun off. The ticker-ticker thread fires every millisecond, using winmm.dll, the Windows (R) multi-media library (this library contains calls that are accurate to one millisecond). Each execution of this thread decrements positive-value timers. When a timer reaches zero, its action (one of three) is performed and the timer expires (negative state). The ticker thread is used to execute functions-to-be-called when timers expire and to exit the two threads, ticker-ticker and ticker, when so required. This ticker thread could become overtaxed since it must finish one function before it can begin another. In such a case, use make_tmrT
instead of make_tmrF
. Initialization is done when the first call to any timer or timings routine is made.
Using the code
VC 6.0 projects: Place the TIMDLL.dll in a directory on your path variable. Add the library TIMDLL.lib to the project resources. Add the module TIMcalls.h to the project. Use the routines therein.
VB 6.0 projects: Register the TIMDLL.dll with regsvr32. Add the module TIMDLL.bas to the project. Use the public routines therein.
#include "TIMcalls.h"
#include "stdio.h"// for printf
static bool pM = true; long timer_id[]= {0,0,0,0};
void cbr (void*prm) {printf("\nFunction cbr fires,
ictr %5d, prm %d",TIM_ictr(),(long)prm);}
void one (void*prm)
{
printf("\nFunction one fires, ictr %5d, prm %d",TIM_ictr(),(long)prm);
if (TIM_ictr() < 30000)
{
TIM_make_tmrF(5000-(TIM_ictr()%5000),&timer_id[2],
one,(void*)(TIM_ictr()/1000),false);
if (timer_id[0] > 0 && TIM_mod_tmr(timer_id[0],
20000-TIM_ictr()) != TIM_SUCCESS)
timer_id[0] = 0;
printf("\nIDs %d,%d,%d,%d",timer_id[0],
timer_id[1],timer_id[2],timer_id[3]);
}
}
void thr (void*prm) {printf("\nThread thr fires, ictr %5d, prm %d",
TIM_ictr(),(long)prm);}
void main (int argc, char*argv[])
{
HANDLE flg_han; unsigned long sts;
TIM_make_tmr (20000,&timer_id[0],"",false);
TIM_make_tmrF(13000,&timer_id[1],cbr,(void*)123,true);
TIM_make_tmrF(11000,&timer_id[2],one,(void*)456,false);
TIM_make_tmrT(18000,&timer_id[3],thr,(void*)789,true);
flg_han = TIM_get_handle(timer_id[0]);
printf("\nIDs %d,%d,%d,%d",timer_id[0],
timer_id[1],timer_id[2],timer_id[3]);
while(pM)
{
Sleep(1000-(TIM_ictr()%1000));
sts = WaitForSingleObject(flg_han,0);
if (sts != WAIT_OBJECT_0)
printf("\nFlag not yet set, ictr %5d",TIM_ictr());
else{printf("\nFlag set, ictr %5d",TIM_ictr()); pM=false;}
}
Sleep(57000-TIM_ictr());
printf("\nAbout to reset TIM sub-system");
long ictr = TIM_ictr();
TIM_reset();
printf("\n ...TIM_reset, about to exit");
Sleep(80000-ictr);
}
Points of Interest
For C/C++ only users, a static library can be built using the workspace and the project files provided. Slots used by event-flag setting timers are not re-used until absolutely necessary, thus the handle is available and the flag state may be queried after expiry. The more accurate 2nd demo VB project uses ccrpTmr.dll. Register the ccrpTmr.dll with regsvr32, ("common controls replacement project" DLL, free from ccrp.mvps.org).
History
- 3.4 TIM_Src.cpp - Comment/Logging maintenance.