source: other-projects/fft-ddr/open-day-2015/trunk/FFTDDR/MicroLibrary.cs@ 29911

Last change on this file since 29911 was 29911, checked in by cct9, 9 years ago

Reworked version of the project undertaken for open day 2015

File size: 7.0 KB
Line 
1using System;
2
3namespace MicroLibrary
4{
5 /// <summary>
6 /// MicroStopwatch class
7 /// </summary>
8 public class MicroStopwatch : System.Diagnostics.Stopwatch
9 {
10 readonly double _microSecPerTick =
11 1000000D / System.Diagnostics.Stopwatch.Frequency;
12
13 public MicroStopwatch()
14 {
15 if (!System.Diagnostics.Stopwatch.IsHighResolution)
16 {
17 throw new Exception("On this system the high-resolution " +
18 "performance counter is not available");
19 }
20 }
21
22 public long ElapsedMicroseconds
23 {
24 get
25 {
26 return (long)(ElapsedTicks * _microSecPerTick);
27 }
28 }
29 }
30
31 /// <summary>
32 /// MicroTimer class
33 /// </summary>
34 public class MicroTimer
35 {
36 public delegate void MicroTimerElapsedEventHandler(
37 object sender,
38 MicroTimerEventArgs timerEventArgs);
39 public event MicroTimerElapsedEventHandler MicroTimerElapsed;
40
41 System.Threading.Thread _threadTimer = null;
42 long _ignoreEventIfLateBy = long.MaxValue;
43 long _timerIntervalInMicroSec = 0;
44 bool _stopTimer = true;
45
46 public MicroTimer()
47 {
48 }
49
50 public MicroTimer(long timerIntervalInMicroseconds)
51 {
52 Interval = timerIntervalInMicroseconds;
53 }
54
55 public long Interval
56 {
57 get
58 {
59 return System.Threading.Interlocked.Read(
60 ref _timerIntervalInMicroSec);
61 }
62 set
63 {
64 System.Threading.Interlocked.Exchange(
65 ref _timerIntervalInMicroSec, value);
66 }
67 }
68
69 public long IgnoreEventIfLateBy
70 {
71 get
72 {
73 return System.Threading.Interlocked.Read(
74 ref _ignoreEventIfLateBy);
75 }
76 set
77 {
78 System.Threading.Interlocked.Exchange(
79 ref _ignoreEventIfLateBy, value <= 0 ? long.MaxValue : value);
80 }
81 }
82
83 public bool Enabled
84 {
85 set
86 {
87 if (value)
88 {
89 Start();
90 }
91 else
92 {
93 Stop();
94 }
95 }
96 get
97 {
98 return (_threadTimer != null && _threadTimer.IsAlive);
99 }
100 }
101
102 public void Start()
103 {
104 if (Enabled || Interval <= 0)
105 {
106 return;
107 }
108
109 _stopTimer = false;
110
111 System.Threading.ThreadStart threadStart = delegate()
112 {
113 NotificationTimer(ref _timerIntervalInMicroSec,
114 ref _ignoreEventIfLateBy,
115 ref _stopTimer);
116 };
117
118 _threadTimer = new System.Threading.Thread(threadStart);
119 _threadTimer.Priority = System.Threading.ThreadPriority.Highest;
120 _threadTimer.Start();
121 }
122
123 public void Stop()
124 {
125 _stopTimer = true;
126 }
127
128 public void StopAndWait()
129 {
130 StopAndWait(System.Threading.Timeout.Infinite);
131 }
132
133 public bool StopAndWait(int timeoutInMilliSec)
134 {
135 _stopTimer = true;
136
137 if (!Enabled || _threadTimer.ManagedThreadId ==
138 System.Threading.Thread.CurrentThread.ManagedThreadId)
139 {
140 return true;
141 }
142
143 return _threadTimer.Join(timeoutInMilliSec);
144 }
145
146 public void Abort()
147 {
148 _stopTimer = true;
149
150 if (Enabled)
151 {
152 _threadTimer.Abort();
153 }
154 }
155
156 void NotificationTimer(ref long timerIntervalInMicroSec,
157 ref long ignoreEventIfLateBy,
158 ref bool stopTimer)
159 {
160 int timerCount = 0;
161 long nextNotification = 0;
162
163 MicroStopwatch microStopwatch = new MicroStopwatch();
164 microStopwatch.Start();
165
166 while (!stopTimer)
167 {
168 long callbackFunctionExecutionTime =
169 microStopwatch.ElapsedMicroseconds - nextNotification;
170
171 long timerIntervalInMicroSecCurrent =
172 System.Threading.Interlocked.Read(ref timerIntervalInMicroSec);
173 long ignoreEventIfLateByCurrent =
174 System.Threading.Interlocked.Read(ref ignoreEventIfLateBy);
175
176 nextNotification += timerIntervalInMicroSecCurrent;
177 timerCount++;
178 long elapsedMicroseconds = 0;
179
180 while ( (elapsedMicroseconds = microStopwatch.ElapsedMicroseconds)
181 < nextNotification)
182 {
183 System.Threading.Thread.SpinWait(10);
184 }
185
186 long timerLateBy = elapsedMicroseconds - nextNotification;
187
188 if (timerLateBy >= ignoreEventIfLateByCurrent)
189 {
190 continue;
191 }
192
193 MicroTimerEventArgs microTimerEventArgs =
194 new MicroTimerEventArgs(timerCount,
195 elapsedMicroseconds,
196 timerLateBy,
197 callbackFunctionExecutionTime);
198 MicroTimerElapsed(this, microTimerEventArgs);
199 }
200
201 microStopwatch.Stop();
202 }
203 }
204
205 /// <summary>
206 /// MicroTimer Event Argument class
207 /// </summary>
208 public class MicroTimerEventArgs : EventArgs
209 {
210 // Simple counter, number times timed event (callback function) executed
211 public int TimerCount { get; private set; }
212
213 // Time when timed event was called since timer started
214 public long ElapsedMicroseconds { get; private set; }
215
216 // How late the timer was compared to when it should have been called
217 public long TimerLateBy { get; private set; }
218
219 // Time it took to execute previous call to callback function (OnTimedEvent)
220 public long CallbackFunctionExecutionTime { get; private set; }
221
222 public MicroTimerEventArgs(int timerCount,
223 long elapsedMicroseconds,
224 long timerLateBy,
225 long callbackFunctionExecutionTime)
226 {
227 TimerCount = timerCount;
228 ElapsedMicroseconds = elapsedMicroseconds;
229 TimerLateBy = timerLateBy;
230 CallbackFunctionExecutionTime = callbackFunctionExecutionTime;
231 }
232 }
233}
Note: See TracBrowser for help on using the repository browser.