Skip to content

Commit

Permalink
Add counters to System.Runtime.Caching.MemoryCache (dotnet#51760)
Browse files Browse the repository at this point in the history
* Bring back counters for Core via EventSource et al.

* Change turnover to a rate counter. Add a test for counters.

* Exclude counter tests on wasm.
  • Loading branch information
StephenMolloy authored May 7, 2021
1 parent 10645f9 commit b2046c7
Show file tree
Hide file tree
Showing 8 changed files with 289 additions and 52 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TargetFrameworks>netcoreapp3.1;netcoreapp3.1-windows;netstandard2.0;netstandard2.0-windows</TargetFrameworks>
<IncludePlatformAttributes>true</IncludePlatformAttributes>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1' or '$(TargetFramework)' == 'netcoreapp3.1-windows'" >
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1' or '$(TargetFramework)' == 'netcoreapp3.1-windows'">
<Reference Include="System.Collections" />
<Reference Include="System.Collections.NonGeneric" />
<Reference Include="System.Collections.Specialized" />
Expand All @@ -13,6 +13,7 @@
<Reference Include="System.ComponentModel.TypeConverter" />
<Reference Include="System.Data.Common" />
<Reference Include="System.Diagnostics.Debug" />
<Reference Include="System.Diagnostics.Tracing" />
<Reference Include="System.IO.FileSystem" />
<Reference Include="System.IO.FileSystem.Watcher" />
<Reference Include="System.ObjectModel" />
Expand All @@ -27,7 +28,7 @@
<Reference Include="System.Threading.Timer" />
</ItemGroup>
<ItemGroup>
<Compile Include="System\Runtime\Caching\_shims.cs" />
<Compile Include="System\Runtime\Caching\Counters.cs" />
<Compile Include="System\Runtime\Caching\CacheEntryChangeMonitor.cs" />
<Compile Include="System\Runtime\Caching\CacheEntryRemovedArguments.cs" />
<Compile Include="System\Runtime\Caching\CacheEntryRemovedCallback.cs" />
Expand Down Expand Up @@ -57,7 +58,7 @@
<Compile Include="System\Runtime\Caching\MemoryMonitor.cs" />
<Compile Include="System\Runtime\Caching\ObjectCache.cs" />
<Compile Include="System\Runtime\Caching\OnChangedCallback.cs" />
<Compile Include="System\Runtime\Caching\PerfCounterName.cs" />
<Compile Include="System\Runtime\Caching\CounterName.cs" />
<Compile Include="System\Runtime\Caching\PhysicalMemoryMonitor.cs" />
<Compile Include="System\Runtime\Caching\SafeBitVector32.cs" />
<Compile Include="System\Runtime\Caching\SRef.cs" />
Expand All @@ -74,12 +75,9 @@
<ItemGroup Condition="'$(TargetsWindows)' == 'true'">
<Compile Include="System\Runtime\Caching\MemoryMonitor.Windows.cs" />
<Compile Include="System\Runtime\Caching\PhysicalMemoryMonitor.Windows.cs" />
<Compile Include="$(CommonPath)Interop\Windows\Kernel32\Interop.GlobalMemoryStatusEx.cs"
Link="Common\Interop\Windows\Kernel32\Interop.GlobalMemoryStatusEx.cs" />
<Compile Include="$(CommonPath)Interop\Windows\Kernel32\Interop.MEMORYSTATUSEX.cs"
Link="Common\Interop\Windows\Kernel32\Interop.MEMORYSTATUSEX.cs" />
<Compile Include="$(CommonPath)Interop\Windows\Interop.Libraries.cs"
Link="Common\Interop\Windows\Interop.Libraries.cs" />
<Compile Include="$(CommonPath)Interop\Windows\Kernel32\Interop.GlobalMemoryStatusEx.cs" Link="Common\Interop\Windows\Kernel32\Interop.GlobalMemoryStatusEx.cs" />
<Compile Include="$(CommonPath)Interop\Windows\Kernel32\Interop.MEMORYSTATUSEX.cs" Link="Common\Interop\Windows\Kernel32\Interop.MEMORYSTATUSEX.cs" />
<Compile Include="$(CommonPath)Interop\Windows\Interop.Libraries.cs" Link="Common\Interop\Windows\Interop.Libraries.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetsWindows)' != 'true'">
<Compile Include="System\Runtime\Caching\PhysicalMemoryMonitor.Unix.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace System.Runtime.Caching
{
internal enum PerfCounterName
internal enum CounterName
{
Entries = 0,
Hits,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Collections.Generic;
using System.Diagnostics.Tracing;
using System.Threading;

namespace System.Runtime.Caching
{
internal sealed class Counters : EventSource
{
#if NETCOREAPP3_1_OR_GREATER
private const string EVENT_SOURCE_NAME_ROOT = "System.Runtime.Caching.";
private const int NUM_COUNTERS = 7;

private DiagnosticCounter[] _counters;
private long[] _counterValues;

internal Counters(string cacheName) : base(EVENT_SOURCE_NAME_ROOT + cacheName)
{
if (cacheName == null)
{
throw new ArgumentNullException(nameof(cacheName));
}

InitDisposableMembers(cacheName);
}

private void InitDisposableMembers(string cacheName)
{
bool dispose = true;

try
{
_counters = new DiagnosticCounter[NUM_COUNTERS];
_counterValues = new long[NUM_COUNTERS];
_counters[(int)CounterName.Entries] = CreatePollingCounter("entries", "Cache Entries", (int)CounterName.Entries);
_counters[(int)CounterName.Hits] = CreatePollingCounter("hits", "Cache Hits", (int)CounterName.Hits);
_counters[(int)CounterName.Misses] = CreatePollingCounter("misses", "Cache Misses", (int)CounterName.Misses);
_counters[(int)CounterName.Trims] = CreatePollingCounter("trims", "Cache Trims", (int)CounterName.Trims);

_counters[(int)CounterName.Turnover] = new IncrementingPollingCounter("turnover", this,
() => (double)_counterValues[(int)CounterName.Turnover])
{
DisplayName = "Cache Turnover Rate",
};

// This two-step dance with hit-ratio was an old perf-counter artifact. There only needs
// to be one polling counter here, rather than the two-part perf counter. Still keeping array
// indexes and raw counter values consistent between NetFx and Core code though.
_counters[(int)CounterName.HitRatio] = new PollingCounter("hit-ratio", this,
() =>((double)_counterValues[(int)CounterName.HitRatio]/(double)_counterValues[(int)CounterName.HitRatioBase]) * 100d)
{
DisplayName = "Cache Hit Ratio",
};
//_counters[(int)CounterName.HitRatioBase] = n/a;

dispose = false;
}
finally
{
if (dispose)
Dispose();
}
}

private PollingCounter CreatePollingCounter(string name, string displayName, int counterIndex)
{
return new PollingCounter(name, this, () => (double)_counterValues[counterIndex])
{
DisplayName = displayName,
};
}

public new void Dispose()
{
DiagnosticCounter[] counters = _counters;

// ensure this only happens once
if (counters != null && Interlocked.CompareExchange(ref _counters, null, counters) == counters)
{
for (int i = 0; i < NUM_COUNTERS; i++)
{
var counter = counters[i];
if (counter != null)
{
counter.Dispose();
}
}
}
}

internal void Increment(CounterName name)
{
int idx = (int)name;
Interlocked.Increment(ref _counterValues[idx]);
}
internal void IncrementBy(CounterName name, long value)
{
int idx = (int)name;
Interlocked.Add(ref _counterValues[idx], value);
}
internal void Decrement(CounterName name)
{
int idx = (int)name;
Interlocked.Decrement(ref _counterValues[idx]);
}
#else
internal Counters(string cacheName)
{
}
public new void Dispose()
{
}
internal void Increment(CounterName name)
{
}
internal void IncrementBy(CounterName name, long value)
{
}
internal void Decrement(CounterName name)
{
}
#endif
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class MemoryCache : ObjectCache, IEnumerable, IDisposable
private int _disposed;
private MemoryCacheStatistics _stats;
private readonly string _name;
private PerfCounters _perfCounters;
private Counters _perfCounters;
private readonly bool _configLess;
private bool _useMemoryCacheManager = true;
private EventHandler _onAppDomainUnload;
Expand Down Expand Up @@ -196,7 +196,7 @@ private void InitDisposableMembers(NameValueCollection config)
{
try
{
_perfCounters = new PerfCounters(_name);
_perfCounters = new Counters(_name);
}
catch
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ internal sealed class MemoryCacheStore : IDisposable
private ManualResetEvent _insertBlock;
private volatile bool _useInsertBlock;
private readonly MemoryCache _cache;
private readonly PerfCounters _perfCounters;
private readonly Counters _perfCounters;

internal MemoryCacheStore(MemoryCache cache, PerfCounters perfCounters)
internal MemoryCacheStore(MemoryCache cache, Counters perfCounters)
{
_cache = cache;
_perfCounters = perfCounters;
Expand Down Expand Up @@ -75,8 +75,8 @@ private void AddToCache(MemoryCacheEntry entry)
entry.CallNotifyOnChanged();
if (_perfCounters != null)
{
_perfCounters.Increment(PerfCounterName.Entries);
_perfCounters.Increment(PerfCounterName.Turnover);
_perfCounters.Increment(CounterName.Entries);
_perfCounters.Increment(CounterName.Turnover);
}
}

Expand Down Expand Up @@ -110,8 +110,8 @@ private void RemoveFromCache(MemoryCacheEntry entry, CacheEntryRemovedReason rea
}
if (_perfCounters != null)
{
_perfCounters.Decrement(PerfCounterName.Entries);
_perfCounters.Increment(PerfCounterName.Turnover);
_perfCounters.Decrement(CounterName.Entries);
_perfCounters.Increment(CounterName.Turnover);
}
}
}
Expand All @@ -138,17 +138,17 @@ internal void UpdateExpAndUsage(MemoryCacheEntry entry, bool updatePerfCounters

if (updatePerfCounters && _perfCounters != null)
{
_perfCounters.Increment(PerfCounterName.Hits);
_perfCounters.Increment(PerfCounterName.HitRatio);
_perfCounters.Increment(PerfCounterName.HitRatioBase);
_perfCounters.Increment(CounterName.Hits);
_perfCounters.Increment(CounterName.HitRatio);
_perfCounters.Increment(CounterName.HitRatioBase);
}
}
else
{
if (updatePerfCounters && _perfCounters != null)
{
_perfCounters.Increment(PerfCounterName.Misses);
_perfCounters.Increment(PerfCounterName.HitRatioBase);
_perfCounters.Increment(CounterName.Misses);
_perfCounters.Increment(CounterName.HitRatioBase);
}
}
}
Expand Down Expand Up @@ -407,7 +407,7 @@ internal long TrimInternal(int percent)
if (trimmed > 0 && _perfCounters != null)
{
// Update values for perfcounters
_perfCounters.IncrementBy(PerfCounterName.Trims, trimmed);
_perfCounters.IncrementBy(CounterName.Trims, trimmed);
}

#if DEBUG
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
<Compile Include="Common\PokerObjectCache.cs" />
<Compile Include="Common\TestNotificationSystem.cs" />
<Compile Include="System.Runtime.Caching\HostFileChangeMonitorTest.cs" />
<Compile Include="System.Runtime.Caching\CountersTest.cs" />
<Compile Include="System.Runtime.Caching\ObjectCacheTest.cs" />
<Compile Include="System.Runtime.Caching\MemoryCacheTest.cs" />
<Compile Include="$(CommonTestPath)System\Diagnostics\Tracing\TestEventListener.cs" Link="Common\System\Diagnostics\Tracing\TestEventListener.cs" />

<TrimmerRootDescriptor Include="$(MSBuildThisFileDirectory)ILLink.Descriptors.xml" />
</ItemGroup>
Expand Down
Loading

0 comments on commit b2046c7

Please sign in to comment.