diff options
author | Jiyoung Yun <jy910.yun@samsung.com> | 2016-12-27 16:46:08 +0900 |
---|---|---|
committer | Jiyoung Yun <jy910.yun@samsung.com> | 2016-12-27 16:46:08 +0900 |
commit | db20f3f1bb8595633a7e16c8900fd401a453a6b5 (patch) | |
tree | e5435159cd1bf0519276363a6fe1663d1721bed3 /src/mscorlib/corefx/System/Runtime/InteropServices/SafeHeapHandleCache.cs | |
parent | 4b4aad7217d3292650e77eec2cf4c198ea9c3b4b (diff) | |
download | coreclr-db20f3f1bb8595633a7e16c8900fd401a453a6b5.tar.gz coreclr-db20f3f1bb8595633a7e16c8900fd401a453a6b5.tar.bz2 coreclr-db20f3f1bb8595633a7e16c8900fd401a453a6b5.zip |
Imported Upstream version 1.0.0.9127upstream/1.0.0.9127
Diffstat (limited to 'src/mscorlib/corefx/System/Runtime/InteropServices/SafeHeapHandleCache.cs')
-rw-r--r-- | src/mscorlib/corefx/System/Runtime/InteropServices/SafeHeapHandleCache.cs | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/src/mscorlib/corefx/System/Runtime/InteropServices/SafeHeapHandleCache.cs b/src/mscorlib/corefx/System/Runtime/InteropServices/SafeHeapHandleCache.cs new file mode 100644 index 0000000000..725076ed66 --- /dev/null +++ b/src/mscorlib/corefx/System/Runtime/InteropServices/SafeHeapHandleCache.cs @@ -0,0 +1,97 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Threading; + +namespace System.Runtime.InteropServices +{ + /// <summary> + /// Allows limited thread safe reuse of heap buffers to limit memory pressure. + /// + /// This cache does not ensure that multiple copies of handles are not released back into the cache. + /// </summary> + internal sealed class SafeHeapHandleCache : IDisposable + { + private readonly ulong _minSize; + private readonly ulong _maxSize; + + // internal for testing + internal readonly SafeHeapHandle[] _handleCache; + + /// <param name="minSize">Smallest buffer size to allocate in bytes.</param> + /// <param name="maxSize">The largest buffer size to cache in bytes.</param> + /// <param name="maxHandles">The maximum number of handles to cache.</param> + public SafeHeapHandleCache(ulong minSize = 64, ulong maxSize = 1024 * 2, int maxHandles = 0) + { + _minSize = minSize; + _maxSize = maxSize; + _handleCache = new SafeHeapHandle[maxHandles > 0 ? maxHandles : Environment.ProcessorCount * 4]; + } + + /// <summary> + /// Get a HeapHandle + /// </summary> + public SafeHeapHandle Acquire(ulong minSize = 0) + { + if (minSize < _minSize) minSize = _minSize; + + SafeHeapHandle handle = null; + + for (int i = 0; i < _handleCache.Length; i++) + { + handle = Interlocked.Exchange(ref _handleCache[i], null); + if (handle != null) break; + } + + if (handle != null) + { + // One possible future consideration is to attempt cycling through to + // find one that might already have sufficient capacity + if (handle.ByteLength < minSize) + handle.Resize(minSize); + } + else + { + handle = new SafeHeapHandle(minSize); + } + + return handle; + } + + /// <summary> + /// Give a HeapHandle back for potential reuse + /// </summary> + public void Release(SafeHeapHandle handle) + { + if (handle.ByteLength <= _maxSize) + { + for (int i = 0; i < _handleCache.Length; i++) + { + // Push the handles down, walking the last one off the end to keep + // the top of the "stack" fresh + handle = Interlocked.Exchange(ref _handleCache[i], handle); + if (handle == null) return; + } + } + + handle.Dispose(); + } + + public void Dispose() + { + Dispose(disposing: true); + } + + private void Dispose(bool disposing) + { + if (disposing && _handleCache != null) + { + foreach (SafeHeapHandle handle in _handleCache) + { + if (handle != null) handle.Dispose(); + } + } + } + } +} |