Index: trunk/src/helpers/apmh.c
===================================================================
--- trunk/src/helpers/apmh.c	(revision 92)
+++ trunk/src/helpers/apmh.c	(revision 93)
@@ -15,5 +15,5 @@
  *            numbering.
  *
- *@@header "helpers\apm.h"
+ *@@header "helpers\apmh.h"
  *@@added V0.9.14 (2001-08-01) [umoeller]
  */
Index: trunk/src/helpers/memdebug.c
===================================================================
--- trunk/src/helpers/memdebug.c	(revision 92)
+++ trunk/src/helpers/memdebug.c	(revision 93)
@@ -91,5 +91,5 @@
 
 /*
- *      Copyright (C) 2000 Ulrich Mller.
+ *      Copyright (C) 2000-2001 Ulrich Mller.
  *      This program is part of the XWorkplace package.
  *      This program is free software; you can redistribute it and/or modify
Index: trunk/src/helpers/timer.c
===================================================================
--- trunk/src/helpers/timer.c	(revision 92)
+++ trunk/src/helpers/timer.c	(revision 93)
@@ -250,4 +250,9 @@
     PLINKLIST pllXTimers = (PLINKLIST)pSet->pvllXTimers;
     ULONG   cTimers = lstCountItems(pllXTimers);
+
+    #ifdef DEBUG_XTIMERS
+        _Pmpf((__FUNCTION__ ": entering"));
+    #endif
+
     if (!cTimers)
     {
@@ -278,4 +283,8 @@
             // only one timer:
             // that's easy
+            #ifdef DEBUG_XTIMERS
+                _Pmpf(("  got 1 timer"));
+            #endif
+
             pSet->ulPMTimeout = pTimer1->ulTimeout;
         }
@@ -285,4 +294,7 @@
             // find the greatest common denominator
             PXTIMER pTimer2 = (PXTIMER)pNode->pNext->pItemData;
+            #ifdef DEBUG_XTIMERS
+                _Pmpf(("  got 2 timers"));
+            #endif
 
             pSet->ulPMTimeout = mathGCD(pTimer1->ulTimeout,
@@ -297,5 +309,7 @@
                     i = 0;
 
-            // _Pmpf(("Recalculating, got %d timers", cTimers));
+            #ifdef DEBUG_XTIMERS
+                _Pmpf(("  got %d timers", cTimers));
+            #endif
 
             // fill an array of integers with the
@@ -305,5 +319,7 @@
                 pTimer1 = (PXTIMER)pNode->pItemData;
 
-                // _Pmpf(("  timeout %d is %d", i, pTimer1->ulTimeout));
+                #ifdef DEBUG_XTIMERS
+                    _Pmpf(("    timeout %d is %d", i, pTimer1->ulTimeout));
+                #endif
 
                 paInts[i++] = pTimer1->ulTimeout;
@@ -314,10 +330,14 @@
             pSet->ulPMTimeout = mathGCDMulti(paInts,
                                              cTimers);
-            // _Pmpf(("--> GCD is %d", pSet->ulPMTimeout));
-        }
+        }
+
+        #ifdef DEBUG_XTIMERS
+            _Pmpf(("--> GCD is %d", pSet->ulPMTimeout));
+        #endif
 
         if (    (!pSet->idPMTimerRunning)       // timer not running?
              || (pSet->ulPMTimeout != ulOldPMTimeout) // timeout changed?
            )
+        {
             // start or restart PM timer
             pSet->idPMTimerRunning = WinStartTimer(pSet->hab,
@@ -325,4 +345,5 @@
                                                    pSet->idPMTimer,
                                                    pSet->ulPMTimeout);
+        }
     }
 }
@@ -434,4 +455,5 @@
  *@@changed V0.9.12 (2001-05-24) [umoeller]: fixed crash if this got called during tmrTimerTick
  *@@changed V0.9.14 (2001-08-01) [umoeller]: fixed mem overwrite which might have caused crashes if this got called during tmrTimerTick
+ *@@changed V0.9.14 (2001-08-03) [umoeller]: fixed "half frequency" regression caused by frequency optimizations
  */
 
@@ -475,4 +497,8 @@
                                     &ulTimeNow, sizeof(ulTimeNow));
 
+                    #ifdef DEBUG_XTIMERS
+                        _Pmpf((__FUNCTION__ ": ulTimeNow = %d", ulTimeNow));
+                    #endif
+
                     while (pTimerNode)
                     {
@@ -484,10 +510,29 @@
                         PXTIMER pTimer = (PXTIMER)pTimerNode->pItemData;
 
+                        #ifdef DEBUG_XTIMERS
+                            _Pmpf(("   timer %d: ulNextFire = %d",
+                                    lstIndexFromItem(pllXTimers, pTimer),
+                                    pTimer->ulNextFire));
+                        #endif
+
                         if (    (pTimer)
-                             && (pTimer->ulNextFire < ulTimeNow)
+                             // && (pTimer->ulNextFire < ulTimeNow)
+                                // V0.9.14 (2001-08-01) [umoeller]
+                                // use <= because otherwise we'll get
+                                // only half the frequency...
+                                // we get here frequently where the
+                                // two values are EXACTLY equal due
+                                // to the above optimization (DosQuerySysInfo
+                                // called once only for the entire loop)
+                             && (pTimer->ulNextFire <= ulTimeNow)
                            )
                         {
                             // this timer has elapsed:
                             // fire!
+
+                            #ifdef DEBUG_XTIMERS
+                                _Pmpf(("   --> fire!"));
+                            #endif
+
                             if (WinIsWindow(pSet->hab,
                                             pTimer->hwndTarget))
