2 // System.Diagnostics.PerformanceCounter.cs
5 // Jonathan Pryor (jonpryor@vt.edu)
6 // Andreas Nahr (ClassDevelopment@A-SoftTech.com)
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:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
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.
34 using System.ComponentModel;
35 using System.ComponentModel.Design;
36 using System.Diagnostics;
37 using System.Runtime.InteropServices;
38 using System.Runtime.CompilerServices;
39 using System.Runtime.ConstrainedExecution;
41 namespace System.Diagnostics {
43 // must be safe for multithreaded operations
44 [InstallerType (typeof (PerformanceCounterInstaller))]
45 public sealed class PerformanceCounter : Component, ISupportInitialize
48 private string categoryName;
49 private string counterName;
50 private string instanceName;
51 private string machineName;
53 PerformanceCounterType type;
54 CounterSample old_sample;
55 private bool readOnly;
59 private PerformanceCounterInstanceLifetime lifetime;
62 public static int DefaultFileMappingSize = 524288;
64 // set catname, countname, instname to "", machname to "."
65 public PerformanceCounter ()
67 categoryName = counterName = instanceName = "";
71 // throws: InvalidOperationException (if catName or countName
72 // is ""); ArgumentNullException if either is null
73 // sets instName to "", machname to "."
74 public PerformanceCounter (String categoryName,
76 : this (categoryName, counterName, false)
80 public PerformanceCounter (string categoryName,
83 : this (categoryName, counterName, "", readOnly)
87 public PerformanceCounter (string categoryName,
90 : this (categoryName, counterName, instanceName, false)
94 public PerformanceCounter (string categoryName,
100 if (categoryName == null)
101 throw new ArgumentNullException ("categoryName");
102 if (counterName == null)
103 throw new ArgumentNullException ("counterName");
104 if (instanceName == null)
105 throw new ArgumentNullException ("instanceName");
106 CategoryName = categoryName;
107 CounterName = counterName;
109 if (categoryName == "" || counterName == "")
110 throw new InvalidOperationException ();
112 InstanceName = instanceName;
113 this.instanceName = instanceName;
114 this.machineName = ".";
115 this.readOnly = readOnly;
119 public PerformanceCounter (string categoryName,
123 : this (categoryName, counterName, instanceName, false)
125 this.machineName = machineName;
128 [MethodImplAttribute (MethodImplOptions.InternalCall)]
129 static extern IntPtr GetImpl (string category, string counter,
130 string instance, string machine, out PerformanceCounterType ctype, out bool custom);
132 [MethodImplAttribute (MethodImplOptions.InternalCall)]
133 static extern bool GetSample (IntPtr impl, bool only_value, out CounterSample sample);
135 [MethodImplAttribute (MethodImplOptions.InternalCall)]
136 static extern long UpdateValue (IntPtr impl, bool do_incr, long value);
138 [MethodImplAttribute (MethodImplOptions.InternalCall)]
139 static extern void FreeData (IntPtr impl);
141 /* the perf counter has changed, ensure it's valid and setup it to
142 * be able to collect/update data
146 // need to free the previous info
147 if (impl != IntPtr.Zero)
149 impl = GetImpl (categoryName, counterName, instanceName, machineName, out type, out is_custom);
150 // system counters are always readonly
153 // invalid counter, need to handle out of mem
155 // TODO: reenable this
156 //if (impl == IntPtr.Zero)
157 // throw new InvalidOperationException ();
161 // may throw ArgumentNullException
162 [DefaultValue (""), ReadOnly (true), RecommendedAsConfigurable (true)]
163 [TypeConverter ("System.Diagnostics.Design.CategoryValueConverter, " + Consts.AssemblySystem_Design)]
164 [SRDescription ("The category name for this performance counter.")]
165 public string CategoryName {
166 get {return categoryName;}
169 throw new ArgumentNullException ("categoryName");
170 categoryName = value;
175 // may throw InvalidOperationException
177 [ReadOnly (true), DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
178 [MonitoringDescription ("A description describing the counter.")]
179 public string CounterHelp {
183 // may throw ArgumentNullException
184 [DefaultValue (""), ReadOnly (true), RecommendedAsConfigurable (true)]
185 [TypeConverter ("System.Diagnostics.Design.CounterNameConverter, " + Consts.AssemblySystem_Design)]
186 [SRDescription ("The name of this performance counter.")]
187 public string CounterName
189 get {return counterName;}
192 throw new ArgumentNullException ("counterName");
198 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
199 [MonitoringDescription ("The type of the counter.")]
200 public PerformanceCounterType CounterType {
209 [DefaultValue (PerformanceCounterInstanceLifetime.Global)]
210 public PerformanceCounterInstanceLifetime InstanceLifetime {
211 get { return lifetime; }
212 set { lifetime = value; }
215 [DefaultValue (""), ReadOnly (true), RecommendedAsConfigurable (true)]
216 [TypeConverter ("System.Diagnostics.Design.InstanceNameConverter, " + Consts.AssemblySystem_Design)]
217 [SRDescription ("The instance name for this performance counter.")]
218 public string InstanceName {
219 get {return instanceName;}
222 throw new ArgumentNullException ("value");
223 instanceName = value;
228 // may throw ArgumentException if machine name format is wrong
229 [MonoTODO("What's the machine name format?")]
230 [DefaultValue ("."), Browsable (false), RecommendedAsConfigurable (true)]
231 [SRDescription ("The machine where this performance counter resides.")]
232 public string MachineName {
233 get {return machineName;}
236 throw new ArgumentNullException ("value");
237 if (value == "" || value == ".") {
242 throw new PlatformNotSupportedException ();
246 // may throw InvalidOperationException, Win32Exception
247 [Browsable (false), DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
248 [MonitoringDescription ("The raw value of the counter.")]
249 public long RawValue {
251 CounterSample sample;
254 GetSample (impl, true, out sample);
255 // should this update old_sample as well?
256 return sample.RawValue;
262 throw new InvalidOperationException ();
263 UpdateValue (impl, false, value);
267 [Browsable (false), DefaultValue (true)]
268 [MonitoringDescription ("The accessability level of the counter.")]
269 public bool ReadOnly {
270 get {return readOnly;}
271 set {readOnly = value;}
274 public void BeginInit ()
276 // we likely don't need to do anything significant here
279 public void EndInit ()
281 // we likely don't need to do anything significant here
288 if (p != IntPtr.Zero)
292 public static void CloseSharedResources ()
294 // we likely don't need to do anything significant here
297 // may throw InvalidOperationException, Win32Exception
298 public long Decrement ()
300 return IncrementBy (-1);
303 protected override void Dispose (bool disposing)
308 // may throw InvalidOperationException, Win32Exception
309 public long Increment ()
311 return IncrementBy (1);
314 // may throw InvalidOperationException, Win32Exception
315 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.MayFail)]
316 public long IncrementBy (long value)
321 // FIXME: This should really throw, but by now set this workaround in place.
322 //throw new InvalidOperationException ();
325 return UpdateValue (impl, true, value);
328 // may throw InvalidOperationException, Win32Exception
329 public CounterSample NextSample ()
331 CounterSample sample;
334 GetSample (impl, false, out sample);
340 // may throw InvalidOperationException, Win32Exception
341 public float NextValue ()
343 CounterSample sample;
346 GetSample (impl, false, out sample);
349 val = CounterSampleCalculator.ComputeCounterValue (old_sample, sample);
351 val = CounterSampleCalculator.ComputeCounterValue (sample);
357 // may throw InvalidOperationException, Win32Exception
359 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.MayFail)]
360 public void RemoveInstance ()
362 throw new NotImplementedException ();