using System; using System.Diagnostics; using System.Threading; namespace UdtSharp { public class Timer { ulong m_ullSchedTime; // next schedulled time static ulong s_ullCPUFrequency = readCPUFrequency();// CPU frequency : clock cycles per microsecond EventWaitHandle m_TickCond = new EventWaitHandle(false, EventResetMode.AutoReset); object m_TickLock = new object(); static EventWaitHandle m_EventCond = new EventWaitHandle(false, EventResetMode.AutoReset); static object m_EventLock = new object(); static bool m_bUseMicroSecond = false; // sepcial handling if timer frequency is low (< 10 ticks per microsecond) public Timer() { } public static ulong rdtsc() { if (m_bUseMicroSecond) { return getTime(); } return (ulong)Stopwatch.GetTimestamp(); } public void Stop() { m_TickCond.Close(); } static ulong readCPUFrequency() { long ticksPerSecond = Stopwatch.Frequency; long ticksPerMicroSecond = ticksPerSecond / 1000000L; if (ticksPerMicroSecond < 10) { m_bUseMicroSecond = true; return 1; } return (ulong)ticksPerMicroSecond; } public static ulong getCPUFrequency() { // ticks per microsecond return (ulong)s_ullCPUFrequency; } void sleep(ulong interval) { ulong t = rdtsc(); // sleep next "interval" time sleepto(t + interval); } public void sleepto(ulong nexttime) { // Use class member such that the method can be interrupted by others m_ullSchedTime = nexttime; ulong t = rdtsc(); while (t < m_ullSchedTime) { m_TickCond.WaitOne(1); t = rdtsc(); } } public void interrupt() { // schedule the sleepto time to the current CCs, so that it will stop m_ullSchedTime = rdtsc(); tick(); } public void tick() { m_TickCond.Set(); } public static ulong getTime() { // microsecond resolution return (ulong)DateTime.Now.Ticks / 10; } public static void triggerEvent() { m_EventCond.Set(); } static void waitForEvent() { m_EventCond.WaitOne(1); } static void sleep() { Thread.Sleep(1); } } }