//
// Authors:
// Jonathan Pryor (jonpryor@vt.edu)
+// Andreas Nahr (ClassDevelopment@A-SoftTech.com)
//
// (C) 2002
+// (C) 2003 Andreas Nahr
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.ComponentModel;
+using System.ComponentModel.Design;
using System.Diagnostics;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+using System.Runtime.ConstrainedExecution;
namespace System.Diagnostics {
// must be safe for multithreaded operations
- public class PerformanceCounter : Component, ISupportInitialize {
+ [InstallerType (typeof (PerformanceCounterInstaller))]
+ public sealed class PerformanceCounter : Component, ISupportInitialize
+ {
private string categoryName;
private string counterName;
private string instanceName;
private string machineName;
+ IntPtr impl;
+ PerformanceCounterType type;
+ CounterSample old_sample;
private bool readOnly;
+ bool valid_old;
+ bool changed;
+ bool is_custom;
+ private PerformanceCounterInstanceLifetime lifetime;
- [MonoTODO("Find the actual value")]
- public static int DefaultFileMappingSize = 0x80000;
+ [Obsolete]
+ public static int DefaultFileMappingSize = 524288;
// set catname, countname, instname to "", machname to "."
public PerformanceCounter ()
bool readOnly)
{
+ if (categoryName == null)
+ throw new ArgumentNullException ("categoryName");
+ if (counterName == null)
+ throw new ArgumentNullException ("counterName");
+ if (instanceName == null)
+ throw new ArgumentNullException ("instanceName");
CategoryName = categoryName;
CounterName = counterName;
this.instanceName = instanceName;
this.machineName = ".";
this.readOnly = readOnly;
+ changed = true;
}
public PerformanceCounter (string categoryName,
this.machineName = machineName;
}
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ static extern IntPtr GetImpl (string category, string counter,
+ string instance, string machine, out PerformanceCounterType ctype, out bool custom);
+
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ static extern bool GetSample (IntPtr impl, bool only_value, out CounterSample sample);
+
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ static extern long UpdateValue (IntPtr impl, bool do_incr, long value);
+
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ static extern void FreeData (IntPtr impl);
+
+ /* the perf counter has changed, ensure it's valid and setup it to
+ * be able to collect/update data
+ */
+ void UpdateInfo ()
+ {
+ // need to free the previous info
+ if (impl != IntPtr.Zero)
+ Close ();
+ impl = GetImpl (categoryName, counterName, instanceName, machineName, out type, out is_custom);
+ // system counters are always readonly
+ if (!is_custom)
+ readOnly = true;
+ // invalid counter, need to handle out of mem
+
+ // TODO: reenable this
+ //if (impl == IntPtr.Zero)
+ // throw new InvalidOperationException ();
+ changed = false;
+ }
+
// may throw ArgumentNullException
+ [DefaultValue (""), ReadOnly (true), RecommendedAsConfigurable (true)]
+ [TypeConverter ("System.Diagnostics.Design.CategoryValueConverter, " + Consts.AssemblySystem_Design)]
+ [SRDescription ("The category name for this performance counter.")]
public string CategoryName {
get {return categoryName;}
set {
if (value == null)
throw new ArgumentNullException ("categoryName");
categoryName = value;
+ changed = true;
}
}
-// // may throw InvalidOperationException
-// [MonoTODO]
-// public string CounterHelp {
-// get {return "";}
-// }
-//
+ // may throw InvalidOperationException
+ [MonoTODO]
+ [ReadOnly (true), DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+ [MonitoringDescription ("A description describing the counter.")]
+ public string CounterHelp {
+ get {return "";}
+ }
+
// may throw ArgumentNullException
- public string CounterName {
+ [DefaultValue (""), ReadOnly (true), RecommendedAsConfigurable (true)]
+ [TypeConverter ("System.Diagnostics.Design.CounterNameConverter, " + Consts.AssemblySystem_Design)]
+ [SRDescription ("The name of this performance counter.")]
+ public string CounterName
+ {
get {return counterName;}
set {
if (value == null)
throw new ArgumentNullException ("counterName");
counterName = value;
+ changed = true;
}
}
-// // may throw InvalidOperationException
-// [MonoTODO]
-// public PerformanceCounterType CounterType {
-// get {return 0;}
-// }
-//
+ [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+ [MonitoringDescription ("The type of the counter.")]
+ public PerformanceCounterType CounterType {
+ get {
+ if (changed)
+ UpdateInfo ();
+ return type;
+ }
+ }
+
+ [MonoTODO]
+ [DefaultValue (PerformanceCounterInstanceLifetime.Global)]
+ public PerformanceCounterInstanceLifetime InstanceLifetime {
+ get { return lifetime; }
+ set { lifetime = value; }
+ }
+
+ [DefaultValue (""), ReadOnly (true), RecommendedAsConfigurable (true)]
+ [TypeConverter ("System.Diagnostics.Design.InstanceNameConverter, " + Consts.AssemblySystem_Design)]
+ [SRDescription ("The instance name for this performance counter.")]
public string InstanceName {
get {return instanceName;}
- set {instanceName = value;}
+ set {
+ if (value == null)
+ throw new ArgumentNullException ("value");
+ instanceName = value;
+ changed = true;
+ }
+ }
+
+ // may throw ArgumentException if machine name format is wrong
+ [MonoTODO("What's the machine name format?")]
+ [DefaultValue ("."), Browsable (false), RecommendedAsConfigurable (true)]
+ [SRDescription ("The machine where this performance counter resides.")]
+ public string MachineName {
+ get {return machineName;}
+ set {
+ if (value == null)
+ throw new ArgumentNullException ("value");
+ if (value == "" || value == ".") {
+ machineName = ".";
+ changed = true;
+ return;
+ }
+ throw new PlatformNotSupportedException ();
+ }
+ }
+
+ // may throw InvalidOperationException, Win32Exception
+ [Browsable (false), DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+ [MonitoringDescription ("The raw value of the counter.")]
+ public long RawValue {
+ get {
+ CounterSample sample;
+ if (changed)
+ UpdateInfo ();
+ GetSample (impl, true, out sample);
+ // should this update old_sample as well?
+ return sample.RawValue;
+ }
+ set {
+ if (changed)
+ UpdateInfo ();
+ if (readOnly)
+ throw new InvalidOperationException ();
+ UpdateValue (impl, false, value);
+ }
+ }
+
+ [Browsable (false), DefaultValue (true)]
+ [MonitoringDescription ("The accessability level of the counter.")]
+ public bool ReadOnly {
+ get {return readOnly;}
+ set {readOnly = value;}
}
-// // may throw ArgumentException if machine name format is wrong
-// [MonoTODO("What's the machine name format?")]
-// public string MachineName {
-// get {return machineName;}
-// set {machineName = value;}
-// }
-//
-// // may throw InvalidOperationException, Win32Exception
-// [MonoTODO]
-// public long RawValue {
-// get {return 0;}
-// set {
-// throw new NotImplementedException ();
-// }
-// }
-//
-// public bool ReadOnly {
-// get {return readOnly;}
-// set {readOnly = value;}
-// }
-//
- [MonoTODO]
public void BeginInit ()
{
- throw new NotImplementedException ();
+ // we likely don't need to do anything significant here
}
-// [MonoTODO]
-// public void Close ()
-// {
-// throw new NotImplementedException ();
-// }
-//
-// [MonoTODO]
-// public static void CloseSharedResources ()
-// {
-// throw new NotImplementedException ();
-// }
-//
-// // may throw InvalidOperationException, Win32Exception
-// [MonoTODO]
-// public long Decrement ()
-// {
-// throw new NotImplementedException ();
-// }
-//
-// [MonoTODO]
-// protected override void Dispose (bool disposing)
-// {
-// throw new NotImplementedException ();
-// }
-//
- [MonoTODO]
public void EndInit ()
{
- throw new NotImplementedException ();
+ // we likely don't need to do anything significant here
}
-// // may throw InvalidOperationException, Win32Exception
-// [MonoTODO]
-// public long Increment ()
-// {
-// throw new NotImplementedException ();
-// }
-//
-// // may throw InvalidOperationException, Win32Exception
-// [MonoTODO]
-// public long IncrementBy (long value)
-// {
-// throw new NotImplementedException ();
-// }
-//
-// // may throw InvalidOperationException, Win32Exception
-// [MonoTODO]
-// public CounterSample NextSample ()
-// {
-// throw new NotImplementedException ();
-// }
-//
-// // may throw InvalidOperationException, Win32Exception
-// [MonoTODO]
-// public float NextValue ()
-// {
-// throw new NotImplementedException ();
-// }
-//
-// // may throw InvalidOperationException, Win32Exception
-// [MonoTODO]
-// public void RemoveInstance ()
-// {
-// throw new NotImplementedException ();
-// }
+ public void Close ()
+ {
+ IntPtr p = impl;
+ impl = IntPtr.Zero;
+ if (p != IntPtr.Zero)
+ FreeData (p);
+ }
+
+ public static void CloseSharedResources ()
+ {
+ // we likely don't need to do anything significant here
+ }
+
+ // may throw InvalidOperationException, Win32Exception
+ public long Decrement ()
+ {
+ return IncrementBy (-1);
+ }
+
+ protected override void Dispose (bool disposing)
+ {
+ Close ();
+ }
+
+ // may throw InvalidOperationException, Win32Exception
+ public long Increment ()
+ {
+ return IncrementBy (1);
+ }
+
+ // may throw InvalidOperationException, Win32Exception
+ [ReliabilityContract (Consistency.WillNotCorruptState, Cer.MayFail)]
+ public long IncrementBy (long value)
+ {
+ if (changed)
+ UpdateInfo ();
+ if (readOnly) {
+ // FIXME: This should really throw, but by now set this workaround in place.
+ //throw new InvalidOperationException ();
+ return 0;
+ }
+ return UpdateValue (impl, true, value);
+ }
+
+ // may throw InvalidOperationException, Win32Exception
+ public CounterSample NextSample ()
+ {
+ CounterSample sample;
+ if (changed)
+ UpdateInfo ();
+ GetSample (impl, false, out sample);
+ valid_old = true;
+ old_sample = sample;
+ return sample;
+ }
+
+ // may throw InvalidOperationException, Win32Exception
+ public float NextValue ()
+ {
+ CounterSample sample;
+ if (changed)
+ UpdateInfo ();
+ GetSample (impl, false, out sample);
+ float val;
+ if (valid_old)
+ val = CounterSampleCalculator.ComputeCounterValue (old_sample, sample);
+ else
+ val = CounterSampleCalculator.ComputeCounterValue (sample);
+ valid_old = true;
+ old_sample = sample;
+ return val;
+ }
+
+ // may throw InvalidOperationException, Win32Exception
+ [MonoTODO]
+ [ReliabilityContract (Consistency.WillNotCorruptState, Cer.MayFail)]
+ public void RemoveInstance ()
+ {
+ throw new NotImplementedException ();
+ }
}
}