clockwerk-opensim-stable – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | vero | 1 | using System; |
2 | using System.Diagnostics; |
||
3 | using System.Threading; |
||
4 | |||
5 | namespace Amib.Threading |
||
6 | { |
||
7 | public interface ISTPPerformanceCountersReader |
||
8 | { |
||
9 | long InUseThreads { get; } |
||
10 | long ActiveThreads { get; } |
||
11 | long WorkItemsQueued { get; } |
||
12 | long WorkItemsProcessed { get; } |
||
13 | } |
||
14 | } |
||
15 | |||
16 | namespace Amib.Threading.Internal |
||
17 | { |
||
18 | internal interface ISTPInstancePerformanceCounters : IDisposable |
||
19 | { |
||
20 | void Close(); |
||
21 | void SampleThreads(long activeThreads, long inUseThreads); |
||
22 | void SampleWorkItems(long workItemsQueued, long workItemsProcessed); |
||
23 | void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime); |
||
24 | void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime); |
||
25 | } |
||
26 | #if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE) |
||
27 | |||
28 | internal enum STPPerformanceCounterType |
||
29 | { |
||
30 | // Fields |
||
31 | ActiveThreads = 0, |
||
32 | InUseThreads = 1, |
||
33 | OverheadThreads = 2, |
||
34 | OverheadThreadsPercent = 3, |
||
35 | OverheadThreadsPercentBase = 4, |
||
36 | |||
37 | WorkItems = 5, |
||
38 | WorkItemsInQueue = 6, |
||
39 | WorkItemsProcessed = 7, |
||
40 | |||
41 | WorkItemsQueuedPerSecond = 8, |
||
42 | WorkItemsProcessedPerSecond = 9, |
||
43 | |||
44 | AvgWorkItemWaitTime = 10, |
||
45 | AvgWorkItemWaitTimeBase = 11, |
||
46 | |||
47 | AvgWorkItemProcessTime = 12, |
||
48 | AvgWorkItemProcessTimeBase = 13, |
||
49 | |||
50 | WorkItemsGroups = 14, |
||
51 | |||
52 | LastCounter = 14, |
||
53 | } |
||
54 | |||
55 | |||
56 | /// <summary> |
||
57 | /// Summary description for STPPerformanceCounter. |
||
58 | /// </summary> |
||
59 | internal class STPPerformanceCounter |
||
60 | { |
||
61 | // Fields |
||
62 | private readonly PerformanceCounterType _pcType; |
||
63 | protected string _counterHelp; |
||
64 | protected string _counterName; |
||
65 | |||
66 | // Methods |
||
67 | public STPPerformanceCounter( |
||
68 | string counterName, |
||
69 | string counterHelp, |
||
70 | PerformanceCounterType pcType) |
||
71 | { |
||
72 | _counterName = counterName; |
||
73 | _counterHelp = counterHelp; |
||
74 | _pcType = pcType; |
||
75 | } |
||
76 | |||
77 | public void AddCounterToCollection(CounterCreationDataCollection counterData) |
||
78 | { |
||
79 | CounterCreationData counterCreationData = new CounterCreationData( |
||
80 | _counterName, |
||
81 | _counterHelp, |
||
82 | _pcType); |
||
83 | |||
84 | counterData.Add(counterCreationData); |
||
85 | } |
||
86 | |||
87 | // Properties |
||
88 | public string Name |
||
89 | { |
||
90 | get |
||
91 | { |
||
92 | return _counterName; |
||
93 | } |
||
94 | } |
||
95 | } |
||
96 | |||
97 | internal class STPPerformanceCounters |
||
98 | { |
||
99 | // Fields |
||
100 | internal STPPerformanceCounter[] _stpPerformanceCounters; |
||
101 | private static readonly STPPerformanceCounters _instance; |
||
102 | internal const string _stpCategoryHelp = "SmartThreadPool performance counters"; |
||
103 | internal const string _stpCategoryName = "SmartThreadPool"; |
||
104 | |||
105 | // Methods |
||
106 | static STPPerformanceCounters() |
||
107 | { |
||
108 | _instance = new STPPerformanceCounters(); |
||
109 | } |
||
110 | |||
111 | private STPPerformanceCounters() |
||
112 | { |
||
113 | STPPerformanceCounter[] stpPerformanceCounters = new STPPerformanceCounter[] |
||
114 | { |
||
115 | new STPPerformanceCounter("Active threads", "The current number of available in the thread pool.", PerformanceCounterType.NumberOfItems32), |
||
116 | new STPPerformanceCounter("In use threads", "The current number of threads that execute a work item.", PerformanceCounterType.NumberOfItems32), |
||
117 | new STPPerformanceCounter("Overhead threads", "The current number of threads that are active, but are not in use.", PerformanceCounterType.NumberOfItems32), |
||
118 | new STPPerformanceCounter("% overhead threads", "The current number of threads that are active, but are not in use in percents.", PerformanceCounterType.RawFraction), |
||
119 | new STPPerformanceCounter("% overhead threads base", "The current number of threads that are active, but are not in use in percents.", PerformanceCounterType.RawBase), |
||
120 | |||
121 | new STPPerformanceCounter("Work Items", "The number of work items in the Smart Thread Pool. Both queued and processed.", PerformanceCounterType.NumberOfItems32), |
||
122 | new STPPerformanceCounter("Work Items in queue", "The current number of work items in the queue", PerformanceCounterType.NumberOfItems32), |
||
123 | new STPPerformanceCounter("Work Items processed", "The number of work items already processed", PerformanceCounterType.NumberOfItems32), |
||
124 | |||
125 | new STPPerformanceCounter("Work Items queued/sec", "The number of work items queued per second", PerformanceCounterType.RateOfCountsPerSecond32), |
||
126 | new STPPerformanceCounter("Work Items processed/sec", "The number of work items processed per second", PerformanceCounterType.RateOfCountsPerSecond32), |
||
127 | |||
128 | new STPPerformanceCounter("Avg. Work Item wait time/sec", "The average time a work item supends in the queue waiting for its turn to execute.", PerformanceCounterType.AverageCount64), |
||
129 | new STPPerformanceCounter("Avg. Work Item wait time base", "The average time a work item supends in the queue waiting for its turn to execute.", PerformanceCounterType.AverageBase), |
||
130 | |||
131 | new STPPerformanceCounter("Avg. Work Item process time/sec", "The average time it takes to process a work item.", PerformanceCounterType.AverageCount64), |
||
132 | new STPPerformanceCounter("Avg. Work Item process time base", "The average time it takes to process a work item.", PerformanceCounterType.AverageBase), |
||
133 | |||
134 | new STPPerformanceCounter("Work Items Groups", "The current number of work item groups associated with the Smart Thread Pool.", PerformanceCounterType.NumberOfItems32), |
||
135 | }; |
||
136 | |||
137 | _stpPerformanceCounters = stpPerformanceCounters; |
||
138 | SetupCategory(); |
||
139 | } |
||
140 | |||
141 | private void SetupCategory() |
||
142 | { |
||
143 | if (!PerformanceCounterCategory.Exists(_stpCategoryName)) |
||
144 | { |
||
145 | CounterCreationDataCollection counters = new CounterCreationDataCollection(); |
||
146 | |||
147 | for (int i = 0; i < _stpPerformanceCounters.Length; i++) |
||
148 | { |
||
149 | _stpPerformanceCounters[i].AddCounterToCollection(counters); |
||
150 | } |
||
151 | |||
152 | PerformanceCounterCategory.Create( |
||
153 | _stpCategoryName, |
||
154 | _stpCategoryHelp, |
||
155 | PerformanceCounterCategoryType.MultiInstance, |
||
156 | counters); |
||
157 | |||
158 | } |
||
159 | } |
||
160 | |||
161 | // Properties |
||
162 | public static STPPerformanceCounters Instance |
||
163 | { |
||
164 | get |
||
165 | { |
||
166 | return _instance; |
||
167 | } |
||
168 | } |
||
169 | } |
||
170 | |||
171 | internal class STPInstancePerformanceCounter : IDisposable |
||
172 | { |
||
173 | // Fields |
||
174 | private bool _isDisposed; |
||
175 | private PerformanceCounter _pcs; |
||
176 | |||
177 | // Methods |
||
178 | protected STPInstancePerformanceCounter() |
||
179 | { |
||
180 | _isDisposed = false; |
||
181 | } |
||
182 | |||
183 | public STPInstancePerformanceCounter( |
||
184 | string instance, |
||
185 | STPPerformanceCounterType spcType) : this() |
||
186 | { |
||
187 | STPPerformanceCounters counters = STPPerformanceCounters.Instance; |
||
188 | _pcs = new PerformanceCounter( |
||
189 | STPPerformanceCounters._stpCategoryName, |
||
190 | counters._stpPerformanceCounters[(int) spcType].Name, |
||
191 | instance, |
||
192 | false); |
||
193 | _pcs.RawValue = _pcs.RawValue; |
||
194 | } |
||
195 | |||
196 | |||
197 | public void Close() |
||
198 | { |
||
199 | if (_pcs != null) |
||
200 | { |
||
201 | _pcs.RemoveInstance(); |
||
202 | _pcs.Close(); |
||
203 | _pcs = null; |
||
204 | } |
||
205 | } |
||
206 | |||
207 | public void Dispose() |
||
208 | { |
||
209 | Dispose(true); |
||
210 | } |
||
211 | |||
212 | public virtual void Dispose(bool disposing) |
||
213 | { |
||
214 | if (!_isDisposed) |
||
215 | { |
||
216 | if (disposing) |
||
217 | { |
||
218 | Close(); |
||
219 | } |
||
220 | } |
||
221 | _isDisposed = true; |
||
222 | } |
||
223 | |||
224 | public virtual void Increment() |
||
225 | { |
||
226 | _pcs.Increment(); |
||
227 | } |
||
228 | |||
229 | public virtual void IncrementBy(long val) |
||
230 | { |
||
231 | _pcs.IncrementBy(val); |
||
232 | } |
||
233 | |||
234 | public virtual void Set(long val) |
||
235 | { |
||
236 | _pcs.RawValue = val; |
||
237 | } |
||
238 | } |
||
239 | |||
240 | internal class STPInstanceNullPerformanceCounter : STPInstancePerformanceCounter |
||
241 | { |
||
242 | // Methods |
||
243 | public override void Increment() {} |
||
244 | public override void IncrementBy(long value) {} |
||
245 | public override void Set(long val) {} |
||
246 | } |
||
247 | |||
248 | |||
249 | |||
250 | internal class STPInstancePerformanceCounters : ISTPInstancePerformanceCounters |
||
251 | { |
||
252 | private bool _isDisposed; |
||
253 | // Fields |
||
254 | private STPInstancePerformanceCounter[] _pcs; |
||
255 | private static readonly STPInstancePerformanceCounter _stpInstanceNullPerformanceCounter; |
||
256 | |||
257 | // Methods |
||
258 | static STPInstancePerformanceCounters() |
||
259 | { |
||
260 | _stpInstanceNullPerformanceCounter = new STPInstanceNullPerformanceCounter(); |
||
261 | } |
||
262 | |||
263 | public STPInstancePerformanceCounters(string instance) |
||
264 | { |
||
265 | _isDisposed = false; |
||
266 | _pcs = new STPInstancePerformanceCounter[(int)STPPerformanceCounterType.LastCounter]; |
||
267 | |||
268 | // Call the STPPerformanceCounters.Instance so the static constructor will |
||
269 | // intialize the STPPerformanceCounters singleton. |
||
270 | STPPerformanceCounters.Instance.GetHashCode(); |
||
271 | |||
272 | for (int i = 0; i < _pcs.Length; i++) |
||
273 | { |
||
274 | if (instance != null) |
||
275 | { |
||
276 | _pcs[i] = new STPInstancePerformanceCounter( |
||
277 | instance, |
||
278 | (STPPerformanceCounterType) i); |
||
279 | } |
||
280 | else |
||
281 | { |
||
282 | _pcs[i] = _stpInstanceNullPerformanceCounter; |
||
283 | } |
||
284 | } |
||
285 | } |
||
286 | |||
287 | |||
288 | public void Close() |
||
289 | { |
||
290 | if (null != _pcs) |
||
291 | { |
||
292 | for (int i = 0; i < _pcs.Length; i++) |
||
293 | { |
||
294 | if (null != _pcs[i]) |
||
295 | { |
||
296 | _pcs[i].Dispose(); |
||
297 | } |
||
298 | } |
||
299 | _pcs = null; |
||
300 | } |
||
301 | } |
||
302 | |||
303 | public void Dispose() |
||
304 | { |
||
305 | Dispose(true); |
||
306 | } |
||
307 | |||
308 | public virtual void Dispose(bool disposing) |
||
309 | { |
||
310 | if (!_isDisposed) |
||
311 | { |
||
312 | if (disposing) |
||
313 | { |
||
314 | Close(); |
||
315 | } |
||
316 | } |
||
317 | _isDisposed = true; |
||
318 | } |
||
319 | |||
320 | private STPInstancePerformanceCounter GetCounter(STPPerformanceCounterType spcType) |
||
321 | { |
||
322 | return _pcs[(int) spcType]; |
||
323 | } |
||
324 | |||
325 | public void SampleThreads(long activeThreads, long inUseThreads) |
||
326 | { |
||
327 | GetCounter(STPPerformanceCounterType.ActiveThreads).Set(activeThreads); |
||
328 | GetCounter(STPPerformanceCounterType.InUseThreads).Set(inUseThreads); |
||
329 | GetCounter(STPPerformanceCounterType.OverheadThreads).Set(activeThreads-inUseThreads); |
||
330 | |||
331 | GetCounter(STPPerformanceCounterType.OverheadThreadsPercentBase).Set(activeThreads-inUseThreads); |
||
332 | GetCounter(STPPerformanceCounterType.OverheadThreadsPercent).Set(inUseThreads); |
||
333 | } |
||
334 | |||
335 | public void SampleWorkItems(long workItemsQueued, long workItemsProcessed) |
||
336 | { |
||
337 | GetCounter(STPPerformanceCounterType.WorkItems).Set(workItemsQueued+workItemsProcessed); |
||
338 | GetCounter(STPPerformanceCounterType.WorkItemsInQueue).Set(workItemsQueued); |
||
339 | GetCounter(STPPerformanceCounterType.WorkItemsProcessed).Set(workItemsProcessed); |
||
340 | |||
341 | GetCounter(STPPerformanceCounterType.WorkItemsQueuedPerSecond).Set(workItemsQueued); |
||
342 | GetCounter(STPPerformanceCounterType.WorkItemsProcessedPerSecond).Set(workItemsProcessed); |
||
343 | } |
||
344 | |||
345 | public void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime) |
||
346 | { |
||
347 | GetCounter(STPPerformanceCounterType.AvgWorkItemWaitTime).IncrementBy((long)workItemWaitTime.TotalMilliseconds); |
||
348 | GetCounter(STPPerformanceCounterType.AvgWorkItemWaitTimeBase).Increment(); |
||
349 | } |
||
350 | |||
351 | public void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime) |
||
352 | { |
||
353 | GetCounter(STPPerformanceCounterType.AvgWorkItemProcessTime).IncrementBy((long)workItemProcessTime.TotalMilliseconds); |
||
354 | GetCounter(STPPerformanceCounterType.AvgWorkItemProcessTimeBase).Increment(); |
||
355 | } |
||
356 | } |
||
357 | #endif |
||
358 | |||
359 | internal class NullSTPInstancePerformanceCounters : ISTPInstancePerformanceCounters, ISTPPerformanceCountersReader |
||
360 | { |
||
361 | private static readonly NullSTPInstancePerformanceCounters _instance = new NullSTPInstancePerformanceCounters(); |
||
362 | |||
363 | public static NullSTPInstancePerformanceCounters Instance |
||
364 | { |
||
365 | get { return _instance; } |
||
366 | } |
||
367 | |||
368 | public void Close() {} |
||
369 | public void Dispose() {} |
||
370 | |||
371 | public void SampleThreads(long activeThreads, long inUseThreads) {} |
||
372 | public void SampleWorkItems(long workItemsQueued, long workItemsProcessed) {} |
||
373 | public void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime) {} |
||
374 | public void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime) {} |
||
375 | public long InUseThreads |
||
376 | { |
||
377 | get { return 0; } |
||
378 | } |
||
379 | |||
380 | public long ActiveThreads |
||
381 | { |
||
382 | get { return 0; } |
||
383 | } |
||
384 | |||
385 | public long WorkItemsQueued |
||
386 | { |
||
387 | get { return 0; } |
||
388 | } |
||
389 | |||
390 | public long WorkItemsProcessed |
||
391 | { |
||
392 | get { return 0; } |
||
393 | } |
||
394 | } |
||
395 | |||
396 | internal class LocalSTPInstancePerformanceCounters : ISTPInstancePerformanceCounters, ISTPPerformanceCountersReader |
||
397 | { |
||
398 | public void Close() { } |
||
399 | public void Dispose() { } |
||
400 | |||
401 | private long _activeThreads; |
||
402 | private long _inUseThreads; |
||
403 | private long _workItemsQueued; |
||
404 | private long _workItemsProcessed; |
||
405 | |||
406 | public long InUseThreads |
||
407 | { |
||
408 | get { return _inUseThreads; } |
||
409 | } |
||
410 | |||
411 | public long ActiveThreads |
||
412 | { |
||
413 | get { return _activeThreads; } |
||
414 | } |
||
415 | |||
416 | public long WorkItemsQueued |
||
417 | { |
||
418 | get { return _workItemsQueued; } |
||
419 | } |
||
420 | |||
421 | public long WorkItemsProcessed |
||
422 | { |
||
423 | get { return _workItemsProcessed; } |
||
424 | } |
||
425 | |||
426 | public void SampleThreads(long activeThreads, long inUseThreads) |
||
427 | { |
||
428 | _activeThreads = activeThreads; |
||
429 | _inUseThreads = inUseThreads; |
||
430 | } |
||
431 | |||
432 | public void SampleWorkItems(long workItemsQueued, long workItemsProcessed) |
||
433 | { |
||
434 | _workItemsQueued = workItemsQueued; |
||
435 | _workItemsProcessed = workItemsProcessed; |
||
436 | } |
||
437 | |||
438 | public void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime) |
||
439 | { |
||
440 | // Not supported |
||
441 | } |
||
442 | |||
443 | public void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime) |
||
444 | { |
||
445 | // Not supported |
||
446 | } |
||
447 | } |
||
448 | } |