2010-04-06 Jb Evain <jbevain@novell.com>
[mcs.git] / class / System / System.Diagnostics / PerformanceCounter.cs
blobd29edfc7d944f0b6be4dfc7971665a4c1483c5b3
1 //
2 // System.Diagnostics.PerformanceCounter.cs
3 //
4 // Authors:
5 // Jonathan Pryor (jonpryor@vt.edu)
6 // Andreas Nahr (ClassDevelopment@A-SoftTech.com)
7 //
8 // (C) 2002
9 // (C) 2003 Andreas Nahr
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System;
34 using System.ComponentModel;
35 using System.ComponentModel.Design;
36 using System.Diagnostics;
37 using System.Runtime.InteropServices;
38 using System.Runtime.CompilerServices;
39 #if NET_2_0
40 using System.Runtime.ConstrainedExecution;
41 #endif
43 namespace System.Diagnostics {
45 // must be safe for multithreaded operations
46 #if !NET_2_0
47 [Designer ("Microsoft.VisualStudio.Install.PerformanceCounterDesigner, " + Consts.AssemblyMicrosoft_VisualStudio)]
48 #endif
49 [InstallerType (typeof (PerformanceCounterInstaller))]
50 public sealed class PerformanceCounter : Component, ISupportInitialize
53 private string categoryName;
54 private string counterName;
55 private string instanceName;
56 private string machineName;
57 IntPtr impl;
58 PerformanceCounterType type;
59 CounterSample old_sample;
60 private bool readOnly;
61 bool valid_old;
62 bool changed;
63 bool is_custom;
64 #if NET_2_0
65 private PerformanceCounterInstanceLifetime lifetime;
66 #endif
68 #if NET_2_0
69 [Obsolete]
70 #endif
71 public static int DefaultFileMappingSize = 524288;
73 // set catname, countname, instname to "", machname to "."
74 public PerformanceCounter ()
76 categoryName = counterName = instanceName = "";
77 machineName = ".";
80 // throws: InvalidOperationException (if catName or countName
81 // is ""); ArgumentNullException if either is null
82 // sets instName to "", machname to "."
83 public PerformanceCounter (String categoryName,
84 string counterName)
85 : this (categoryName, counterName, false)
89 public PerformanceCounter (string categoryName,
90 string counterName,
91 bool readOnly)
92 : this (categoryName, counterName, "", readOnly)
96 public PerformanceCounter (string categoryName,
97 string counterName,
98 string instanceName)
99 : this (categoryName, counterName, instanceName, false)
103 public PerformanceCounter (string categoryName,
104 string counterName,
105 string instanceName,
106 bool readOnly)
109 if (categoryName == null)
110 throw new ArgumentNullException ("categoryName");
111 if (counterName == null)
112 throw new ArgumentNullException ("counterName");
113 if (instanceName == null)
114 throw new ArgumentNullException ("instanceName");
115 CategoryName = categoryName;
116 CounterName = counterName;
118 if (categoryName == "" || counterName == "")
119 throw new InvalidOperationException ();
121 InstanceName = instanceName;
122 this.instanceName = instanceName;
123 this.machineName = ".";
124 this.readOnly = readOnly;
125 changed = true;
128 public PerformanceCounter (string categoryName,
129 string counterName,
130 string instanceName,
131 string machineName)
132 : this (categoryName, counterName, instanceName, false)
134 this.machineName = machineName;
137 [MethodImplAttribute (MethodImplOptions.InternalCall)]
138 static extern IntPtr GetImpl (string category, string counter,
139 string instance, string machine, out PerformanceCounterType ctype, out bool custom);
141 [MethodImplAttribute (MethodImplOptions.InternalCall)]
142 static extern bool GetSample (IntPtr impl, bool only_value, out CounterSample sample);
144 [MethodImplAttribute (MethodImplOptions.InternalCall)]
145 static extern long UpdateValue (IntPtr impl, bool do_incr, long value);
147 [MethodImplAttribute (MethodImplOptions.InternalCall)]
148 static extern void FreeData (IntPtr impl);
150 /* the perf counter has changed, ensure it's valid and setup it to
151 * be able to collect/update data
153 void UpdateInfo ()
155 // need to free the previous info
156 if (impl != IntPtr.Zero)
157 Close ();
158 impl = GetImpl (categoryName, counterName, instanceName, machineName, out type, out is_custom);
159 // system counters are always readonly
160 if (!is_custom)
161 readOnly = true;
162 // invalid counter, need to handle out of mem
164 // TODO: reenable this
165 //if (impl == IntPtr.Zero)
166 // throw new InvalidOperationException ();
167 changed = false;
170 // may throw ArgumentNullException
171 [DefaultValue (""), ReadOnly (true), RecommendedAsConfigurable (true)]
172 [TypeConverter ("System.Diagnostics.Design.CategoryValueConverter, " + Consts.AssemblySystem_Design)]
173 [SRDescription ("The category name for this performance counter.")]
174 public string CategoryName {
175 get {return categoryName;}
176 set {
177 if (value == null)
178 throw new ArgumentNullException ("categoryName");
179 categoryName = value;
180 changed = true;
184 // may throw InvalidOperationException
185 [MonoTODO]
186 [ReadOnly (true), DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
187 [MonitoringDescription ("A description describing the counter.")]
188 public string CounterHelp {
189 get {return "";}
192 // may throw ArgumentNullException
193 [DefaultValue (""), ReadOnly (true), RecommendedAsConfigurable (true)]
194 [TypeConverter ("System.Diagnostics.Design.CounterNameConverter, " + Consts.AssemblySystem_Design)]
195 [SRDescription ("The name of this performance counter.")]
196 public string CounterName
198 get {return counterName;}
199 set {
200 if (value == null)
201 throw new ArgumentNullException ("counterName");
202 counterName = value;
203 changed = true;
207 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
208 [MonitoringDescription ("The type of the counter.")]
209 public PerformanceCounterType CounterType {
210 get {
211 if (changed)
212 UpdateInfo ();
213 return type;
217 #if NET_2_0
218 [MonoTODO]
219 [DefaultValue (PerformanceCounterInstanceLifetime.Global)]
220 public PerformanceCounterInstanceLifetime InstanceLifetime {
221 get { return lifetime; }
222 set { lifetime = value; }
224 #endif
226 [DefaultValue (""), ReadOnly (true), RecommendedAsConfigurable (true)]
227 [TypeConverter ("System.Diagnostics.Design.InstanceNameConverter, " + Consts.AssemblySystem_Design)]
228 [SRDescription ("The instance name for this performance counter.")]
229 public string InstanceName {
230 get {return instanceName;}
231 set {
232 if (value == null)
233 throw new ArgumentNullException ("value");
234 instanceName = value;
235 changed = true;
239 // may throw ArgumentException if machine name format is wrong
240 [MonoTODO("What's the machine name format?")]
241 [DefaultValue ("."), Browsable (false), RecommendedAsConfigurable (true)]
242 [SRDescription ("The machine where this performance counter resides.")]
243 public string MachineName {
244 get {return machineName;}
245 set {
246 if (value == null)
247 throw new ArgumentNullException ("value");
248 if (value == "" || value == ".") {
249 machineName = ".";
250 changed = true;
251 return;
253 throw new PlatformNotSupportedException ();
257 // may throw InvalidOperationException, Win32Exception
258 [Browsable (false), DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
259 [MonitoringDescription ("The raw value of the counter.")]
260 public long RawValue {
261 get {
262 CounterSample sample;
263 if (changed)
264 UpdateInfo ();
265 GetSample (impl, true, out sample);
266 // should this update old_sample as well?
267 return sample.RawValue;
269 set {
270 if (changed)
271 UpdateInfo ();
272 if (readOnly)
273 throw new InvalidOperationException ();
274 UpdateValue (impl, false, value);
278 [Browsable (false), DefaultValue (true)]
279 [MonitoringDescription ("The accessability level of the counter.")]
280 public bool ReadOnly {
281 get {return readOnly;}
282 set {readOnly = value;}
285 public void BeginInit ()
287 // we likely don't need to do anything significant here
290 public void EndInit ()
292 // we likely don't need to do anything significant here
295 public void Close ()
297 IntPtr p = impl;
298 impl = IntPtr.Zero;
299 if (p != IntPtr.Zero)
300 FreeData (p);
303 public static void CloseSharedResources ()
305 // we likely don't need to do anything significant here
308 // may throw InvalidOperationException, Win32Exception
309 public long Decrement ()
311 return IncrementBy (-1);
314 protected override void Dispose (bool disposing)
316 Close ();
319 // may throw InvalidOperationException, Win32Exception
320 public long Increment ()
322 return IncrementBy (1);
325 // may throw InvalidOperationException, Win32Exception
326 #if NET_2_0
327 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.MayFail)]
328 #endif
329 public long IncrementBy (long value)
331 if (changed)
332 UpdateInfo ();
333 if (readOnly) {
334 // FIXME: This should really throw, but by now set this workaround in place.
335 //throw new InvalidOperationException ();
336 return 0;
338 return UpdateValue (impl, true, value);
341 // may throw InvalidOperationException, Win32Exception
342 public CounterSample NextSample ()
344 CounterSample sample;
345 if (changed)
346 UpdateInfo ();
347 GetSample (impl, false, out sample);
348 valid_old = true;
349 old_sample = sample;
350 return sample;
353 // may throw InvalidOperationException, Win32Exception
354 public float NextValue ()
356 CounterSample sample;
357 if (changed)
358 UpdateInfo ();
359 GetSample (impl, false, out sample);
360 float val;
361 if (valid_old)
362 val = CounterSampleCalculator.ComputeCounterValue (old_sample, sample);
363 else
364 val = CounterSampleCalculator.ComputeCounterValue (sample);
365 valid_old = true;
366 old_sample = sample;
367 return val;
370 // may throw InvalidOperationException, Win32Exception
371 [MonoTODO]
372 #if NET_2_0
373 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.MayFail)]
374 #endif
375 public void RemoveInstance ()
377 throw new NotImplementedException ();