diff --git a/Timer.cs b/Timer.cs
index b60287f..caa8716 100644
--- a/Timer.cs
+++ b/Timer.cs
@@ -5,7 +5,284 @@ using System.Threading;
namespace lib
{
- public class Timer
+
+ public class MicroStopwatch : System.Diagnostics.Stopwatch
+ {
+ readonly double _microSecPerTick
+ = 1000000D / System.Diagnostics.Stopwatch.Frequency;
+
+ public MicroStopwatch()
+ {
+ if (!System.Diagnostics.Stopwatch.IsHighResolution)
+ {
+ throw new Exception("On this system the high-resolution " +
+ "performance counter is not available");
+ }
+ }
+
+ public long ElapsedMicroseconds
+ {
+ get
+ {
+ return (long)(ElapsedTicks * _microSecPerTick);
+ }
+ }
+ }
+
+ ///
+ /// MicroTimer class
+ ///
+ public class MicroTimer
+ {
+ public delegate void MicroTimerElapsedEventHandler(
+ object sender,
+ MicroTimerEventArgs timerEventArgs);
+ public event MicroTimerElapsedEventHandler MicroTimerElapsed;
+
+ System.Threading.Thread _threadTimer = null;
+ long _ignoreEventIfLateBy = long.MaxValue;
+ long _timerIntervalInMicroSec = 0;
+ bool _stopTimer = true;
+
+ public MicroTimer()
+ {
+ }
+
+ public MicroTimer(long timerIntervalInMicroseconds)
+ {
+ Interval = timerIntervalInMicroseconds;
+ }
+
+ public long Interval
+ {
+ get
+ {
+ return System.Threading.Interlocked.Read(
+ ref _timerIntervalInMicroSec);
+ }
+ set
+ {
+ System.Threading.Interlocked.Exchange(
+ ref _timerIntervalInMicroSec, value);
+ }
+ }
+
+ public long IgnoreEventIfLateBy
+ {
+ get
+ {
+ return System.Threading.Interlocked.Read(
+ ref _ignoreEventIfLateBy);
+ }
+ set
+ {
+ System.Threading.Interlocked.Exchange(
+ ref _ignoreEventIfLateBy, value <= 0 ? long.MaxValue : value);
+ }
+ }
+
+ public bool Enabled
+ {
+ set
+ {
+ if (value)
+ {
+ Start();
+ }
+ else
+ {
+ Stop();
+ }
+ }
+ get
+ {
+ return (_threadTimer != null && _threadTimer.IsAlive);
+ }
+ }
+
+ public void Start()
+ {
+ if (Enabled || Interval <= 0)
+ {
+ return;
+ }
+
+ _stopTimer = false;
+
+ System.Threading.ThreadStart threadStart = delegate()
+ {
+ NotificationTimer(ref _timerIntervalInMicroSec,
+ ref _ignoreEventIfLateBy,
+ ref _stopTimer);
+ };
+
+ _threadTimer = new System.Threading.Thread(threadStart);
+ _threadTimer.Priority = System.Threading.ThreadPriority.Highest;
+ _threadTimer.Start();
+ }
+
+ public void Stop()
+ {
+ _stopTimer = true;
+
+ if (_threadTimer != null && _threadTimer.ManagedThreadId ==
+ System.Threading.Thread.CurrentThread.ManagedThreadId)
+ {
+ return;
+ }
+
+ while (Enabled)
+ {
+ System.Threading.Thread.SpinWait(10);
+ }
+ }
+
+ void NotificationTimer(ref long timerIntervalInMicroSec,
+ ref long ignoreEventIfLateBy,
+ ref bool stopTimer)
+ {
+ int timerCount = 0;
+ long nextNotification = 0;
+
+ MicroStopwatch microStopwatch = new MicroStopwatch();
+ microStopwatch.Start();
+
+ while (!stopTimer)
+ {
+ long callbackFunctionExecutionTime =
+ microStopwatch.ElapsedMicroseconds - nextNotification;
+
+ long timerIntervalInMicroSecCurrent =
+ System.Threading.Interlocked.Read(ref timerIntervalInMicroSec);
+ long ignoreEventIfLateByCurrent =
+ System.Threading.Interlocked.Read(ref ignoreEventIfLateBy);
+
+ nextNotification += timerIntervalInMicroSecCurrent;
+ timerCount++;
+ long elapsedMicroseconds = 0;
+
+ while ( (elapsedMicroseconds = microStopwatch.ElapsedMicroseconds)
+ < nextNotification)
+ {
+ System.Threading.Thread.SpinWait(10);
+ }
+
+ long timerLateBy = elapsedMicroseconds - nextNotification;
+
+ if (timerLateBy >= ignoreEventIfLateByCurrent)
+ {
+ continue;
+ }
+
+ MicroTimerEventArgs microTimerEventArgs =
+ new MicroTimerEventArgs(timerCount,
+ elapsedMicroseconds,
+ timerLateBy,
+ callbackFunctionExecutionTime);
+ MicroTimerElapsed(this, microTimerEventArgs);
+ }
+
+ microStopwatch.Stop();
+ }
+ }
+
+ ///
+ /// MicroTimer Event Argument class
+ ///
+ public class MicroTimerEventArgs : EventArgs
+ {
+ // Simple counter, number times timed event (callback function) executed
+ public int TimerCount { get; private set; }
+
+ // Time when timed event was called since timer started
+ public long ElapsedMicroseconds { get; private set; }
+
+ // How late the timer was compared to when it should have been called
+ public long TimerLateBy { get; private set; }
+
+ // Time it took to execute previous call to callback function (OnTimedEvent)
+ public long CallbackFunctionExecutionTime { get; private set; }
+
+ public MicroTimerEventArgs(int timerCount,
+ long elapsedMicroseconds,
+ long timerLateBy,
+ long callbackFunctionExecutionTime)
+ {
+ TimerCount = timerCount;
+ ElapsedMicroseconds = elapsedMicroseconds;
+ TimerLateBy = timerLateBy;
+ CallbackFunctionExecutionTime = callbackFunctionExecutionTime;
+ }
+ }
+
+
+ public class Timer
+ {
+ MicroStopwatch m_watch;
+ private long startTime;
+ private long stopTime;
+ private long freq;
+ private long freq_millis;
+
+ public Timer()
+ {
+ m_watch = new MicroStopwatch();
+ //startTime = m_watch.ElapsedMicroseconds;
+ //stopTime = m_watch.ElapsedMicroseconds;
+ freq = 1000 * 1000;
+ freq_millis = freq / 1000;
+
+ }
+
+ // Start the timer
+
+ public void Start()
+ {
+ startTime = m_watch.ElapsedMicroseconds;
+ stopTime = m_watch.ElapsedMicroseconds;
+ }
+
+ // Stop the timer
+
+ public void Stop()
+ {
+ stopTime = m_watch.ElapsedMicroseconds;
+ }
+
+ public double Seconds
+ {
+ get
+ {
+ long current = m_watch.ElapsedMicroseconds;
+ return (double)( current - startTime ) / freq;
+ }
+ }
+
+ public long Current
+ {
+ get
+ {
+ long current = m_watch.ElapsedMicroseconds;
+ return ( current - startTime ) / freq_millis;
+ }
+ }
+
+ public double Duration
+ {
+ get
+ {
+ return (double)( stopTime - startTime ) / (double)freq;
+ }
+ }
+
+ public long DurationMS
+ {
+ get { return ( stopTime - startTime ) / freq_millis; }
+ }
+ }
+
+
+ public class TimerWin
{
[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceCounter(
@@ -22,7 +299,7 @@ namespace lib
// Constructor
- public Timer()
+ public TimerWin()
{
startTime = 0;
stopTime = 0;