source: trunk/dll/tmrsvcs.c@ 1200

Last change on this file since 1200 was 948, checked in by Steven Levine, 17 years ago

Rework collector progress reporting and improve performance (ticket #79)

File size: 3.1 KB
Line 
1
2/***********************************************************************
3
4 $Id: $
5
6 Timer services
7
8 Copyright (c) 2008 Steven H. Levine
9
10 05 Jan 08 SHL Baseline
11
12***********************************************************************/
13
14#define INCL_DOS // QSV_MS_COUNT
15
16// #include "errutil.h" // DbgMsg // 05 Jan 08 SHL fixme debug
17#include "tmrsvcs.h"
18
19// static PSZ pszSrcFile = __FILE__; // 05 Jan 08 SHL fixme debug
20
21/**
22 * Prepare interval timer descriptor for use
23 * Call with interval 0 to to reset internal estimators
24 * @param pTD point to interval timer descriptor
25 * @param interval_msec is the timer interval in msec or 0 to retain existing value
26 */
27
28VOID InitITimer(ITIMER_DESC *pitd, UINT interval_msec)
29{
30 if (interval_msec) {
31 // Assume starting new loop at similar rate
32 pitd->interval_msec = interval_msec;
33 pitd->remaining = pitd->estimated;
34 }
35 else {
36 // Assume loop rate is changing to a significantly lower value
37 pitd->remaining = 0;
38 pitd->estimated = 1; // Force rate recalc
39 }
40 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &pitd->start_msec, sizeof(pitd->start_msec));
41}
42
43/**
44 * Check timer interval expired
45 * Attempts to optimize calls to fetch QSV_MS_COUNT
46 * Caller should reinit if processing rate changes
47 * @return TRUE if expired
48 */
49
50BOOL IsITimerExpired(ITIMER_DESC *pitd)
51{
52 INT err_msec;
53 ULONG cur_msec;
54 UINT elapsed_msec;
55 INT cnt;
56
57 if (--pitd->remaining < 0) {
58
59 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &cur_msec, sizeof(cur_msec));
60 elapsed_msec = cur_msec - pitd->start_msec;
61 if (elapsed_msec == pitd->interval_msec) {
62 pitd->remaining = pitd->estimated;
63 pitd->start_msec = cur_msec;
64 pitd->misses = 0;
65 return TRUE; // Say interval expired
66 }
67
68 pitd->misses++;
69 err_msec = (cur_msec - pitd->start_msec) - pitd->interval_msec;
70 // Estimate counts per msec
71#if 0 // 05 Jan 08 SHL fixme to be gone when no longer needed for testing
72 DbgMsg(pszSrcFile, __LINE__,
73 "err_msec %d elapsed_msec %d estimated %u misses %u",
74 err_msec, elapsed_msec, pitd->estimated, pitd->misses);
75#endif
76 if (err_msec > 0) {
77 // Late - need to reduce estimated count
78 if (elapsed_msec)
79 pitd->estimated = pitd->estimated * pitd->interval_msec / elapsed_msec;
80 else {
81 // Should not occur
82 if (pitd->estimated)
83 pitd->estimated--;
84 }
85 // Calc counts for next interval
86 pitd->remaining = pitd->estimated -
87 (pitd->estimated * err_msec / pitd->interval_msec);
88 pitd->start_msec += pitd->interval_msec;
89 return TRUE;
90 }
91
92 // Early - need to increase estimated count
93 cnt = pitd->estimated * (-err_msec) / pitd->interval_msec;
94 if (!cnt) {
95 if (pitd->estimated)
96 cnt = pitd->estimated * 2;
97 else
98 cnt = 1;
99 }
100 pitd->estimated += cnt;
101 pitd->remaining = cnt;
102 }
103 return FALSE; // Keep waiting
104}
105
106VOID SleepIfNeeded(ITIMER_DESC *pitd, UINT sleepTime)
107{
108 if (IsITimerExpired(pitd)) {
109 DosSleep(sleepTime);
110 InitITimer(pitd, 0);
111 }
112}
113
114#pragma alloc_text(TMRSVCS,InitITimer,IsITimerExpired,SleepIfNeeded)
Note: See TracBrowser for help on using the repository browser.