115 lines
2.7 KiB
C#
115 lines
2.7 KiB
C#
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);
|
|
}
|
|
}
|
|
} |