From 7969fb6bbaf49a7a84df379d072b94286e4f7ada Mon Sep 17 00:00:00 2001 From: jhorv <38920027+jhorv@users.noreply.github.com> Date: Mon, 5 Aug 2024 20:09:08 -0400 Subject: Replace and remove obsolete ByteMemoryPool type (#7155) * refactor: replace usage of ByteMemoryPool with MemoryOwner<byte> * refactor: delete unused ByteMemoryPool and ByteMemoryPool.ByteMemoryPoolBuffer types * refactor: change IMemoryOwner<byte> return types to MemoryOwner<byte> * fix(perf): get span via `MemoryOwner<T>.Span` directly instead of `MemoryOwner<T>.Memory.Span` * fix(perf): get span via MemoryOwner<T>.Span directly instead of `MemoryOwner<T>.Memory.Span` * fix(perf): get span via MemoryOwner<T>.Span directly instead of `MemoryOwner<T>.Memory.Span` --- .../Memory/ByteMemoryPool.ByteMemoryPoolBuffer.cs | 51 ---------- src/Ryujinx.Common/Memory/ByteMemoryPool.cs | 106 --------------------- src/Ryujinx.Common/Utilities/EmbeddedResources.cs | 6 +- src/Ryujinx.Common/Utilities/StreamUtils.cs | 13 ++- src/Ryujinx.Cpu/Jit/MemoryManagerHostTracked.cs | 4 +- src/Ryujinx.Memory/VirtualMemoryManagerBase.cs | 4 +- 6 files changed, 13 insertions(+), 171 deletions(-) delete mode 100644 src/Ryujinx.Common/Memory/ByteMemoryPool.ByteMemoryPoolBuffer.cs delete mode 100644 src/Ryujinx.Common/Memory/ByteMemoryPool.cs diff --git a/src/Ryujinx.Common/Memory/ByteMemoryPool.ByteMemoryPoolBuffer.cs b/src/Ryujinx.Common/Memory/ByteMemoryPool.ByteMemoryPoolBuffer.cs deleted file mode 100644 index 05fb29ac..00000000 --- a/src/Ryujinx.Common/Memory/ByteMemoryPool.ByteMemoryPoolBuffer.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.Buffers; -using System.Threading; - -namespace Ryujinx.Common.Memory -{ - public partial class ByteMemoryPool - { - /// <summary> - /// Represents a <see cref="IMemoryOwner{Byte}"/> that wraps an array rented from - /// <see cref="ArrayPool{Byte}.Shared"/> and exposes it as <see cref="Memory{Byte}"/> - /// with a length of the requested size. - /// </summary> - private sealed class ByteMemoryPoolBuffer : IMemoryOwner<byte> - { - private byte[] _array; - private readonly int _length; - - public ByteMemoryPoolBuffer(int length) - { - _array = ArrayPool<byte>.Shared.Rent(length); - _length = length; - } - - /// <summary> - /// Returns a <see cref="Memory{Byte}"/> belonging to this owner. - /// </summary> - public Memory<byte> Memory - { - get - { - byte[] array = _array; - - ObjectDisposedException.ThrowIf(array is null, this); - - return new Memory<byte>(array, 0, _length); - } - } - - public void Dispose() - { - var array = Interlocked.Exchange(ref _array, null); - - if (array != null) - { - ArrayPool<byte>.Shared.Return(array); - } - } - } - } -} diff --git a/src/Ryujinx.Common/Memory/ByteMemoryPool.cs b/src/Ryujinx.Common/Memory/ByteMemoryPool.cs deleted file mode 100644 index 6fd6a98a..00000000 --- a/src/Ryujinx.Common/Memory/ByteMemoryPool.cs +++ /dev/null @@ -1,106 +0,0 @@ -using System; -using System.Buffers; - -namespace Ryujinx.Common.Memory -{ - /// <summary> - /// Provides a pool of re-usable byte array instances. - /// </summary> - public static partial class ByteMemoryPool - { - /// <summary> - /// Returns the maximum buffer size supported by this pool. - /// </summary> - public static int MaxBufferSize => Array.MaxLength; - - /// <summary> - /// Rents a byte memory buffer from <see cref="ArrayPool{Byte}.Shared"/>. - /// The buffer may contain data from a prior use. - /// </summary> - /// <param name="length">The buffer's required length in bytes</param> - /// <returns>A <see cref="IMemoryOwner{Byte}"/> wrapping the rented memory</returns> - /// <exception cref="ArgumentOutOfRangeException"></exception> - public static IMemoryOwner<byte> Rent(long length) - => RentImpl(checked((int)length)); - - /// <summary> - /// Rents a byte memory buffer from <see cref="ArrayPool{Byte}.Shared"/>. - /// The buffer may contain data from a prior use. - /// </summary> - /// <param name="length">The buffer's required length in bytes</param> - /// <returns>A <see cref="IMemoryOwner{Byte}"/> wrapping the rented memory</returns> - /// <exception cref="ArgumentOutOfRangeException"></exception> - public static IMemoryOwner<byte> Rent(ulong length) - => RentImpl(checked((int)length)); - - /// <summary> - /// Rents a byte memory buffer from <see cref="ArrayPool{Byte}.Shared"/>. - /// The buffer may contain data from a prior use. - /// </summary> - /// <param name="length">The buffer's required length in bytes</param> - /// <returns>A <see cref="IMemoryOwner{Byte}"/> wrapping the rented memory</returns> - /// <exception cref="ArgumentOutOfRangeException"></exception> - public static IMemoryOwner<byte> Rent(int length) - => RentImpl(length); - - /// <summary> - /// Rents a byte memory buffer from <see cref="ArrayPool{Byte}.Shared"/>. - /// The buffer's contents are cleared (set to all 0s) before returning. - /// </summary> - /// <param name="length">The buffer's required length in bytes</param> - /// <returns>A <see cref="IMemoryOwner{Byte}"/> wrapping the rented memory</returns> - /// <exception cref="ArgumentOutOfRangeException"></exception> - public static IMemoryOwner<byte> RentCleared(long length) - => RentCleared(checked((int)length)); - - /// <summary> - /// Rents a byte memory buffer from <see cref="ArrayPool{Byte}.Shared"/>. - /// The buffer's contents are cleared (set to all 0s) before returning. - /// </summary> - /// <param name="length">The buffer's required length in bytes</param> - /// <returns>A <see cref="IMemoryOwner{Byte}"/> wrapping the rented memory</returns> - /// <exception cref="ArgumentOutOfRangeException"></exception> - public static IMemoryOwner<byte> RentCleared(ulong length) - => RentCleared(checked((int)length)); - - /// <summary> - /// Rents a byte memory buffer from <see cref="ArrayPool{Byte}.Shared"/>. - /// The buffer's contents are cleared (set to all 0s) before returning. - /// </summary> - /// <param name="length">The buffer's required length in bytes</param> - /// <returns>A <see cref="IMemoryOwner{Byte}"/> wrapping the rented memory</returns> - /// <exception cref="ArgumentOutOfRangeException"></exception> - public static IMemoryOwner<byte> RentCleared(int length) - { - var buffer = RentImpl(length); - - buffer.Memory.Span.Clear(); - - return buffer; - } - - /// <summary> - /// Copies <paramref name="buffer"/> into a newly rented byte memory buffer. - /// </summary> - /// <param name="buffer">The byte buffer to copy</param> - /// <returns>A <see cref="IMemoryOwner{Byte}"/> wrapping the rented memory with <paramref name="buffer"/> copied to it</returns> - public static IMemoryOwner<byte> RentCopy(ReadOnlySpan<byte> buffer) - { - var copy = RentImpl(buffer.Length); - - buffer.CopyTo(copy.Memory.Span); - - return copy; - } - - private static ByteMemoryPoolBuffer RentImpl(int length) - { - if ((uint)length > Array.MaxLength) - { - throw new ArgumentOutOfRangeException(nameof(length), length, null); - } - - return new ByteMemoryPoolBuffer(length); - } - } -} diff --git a/src/Ryujinx.Common/Utilities/EmbeddedResources.cs b/src/Ryujinx.Common/Utilities/EmbeddedResources.cs index e22571c9..7530c012 100644 --- a/src/Ryujinx.Common/Utilities/EmbeddedResources.cs +++ b/src/Ryujinx.Common/Utilities/EmbeddedResources.cs @@ -1,6 +1,6 @@ +using Ryujinx.Common.Memory; using Ryujinx.Common.Utilities; using System; -using System.Buffers; using System.IO; using System.Linq; using System.Reflection; @@ -42,14 +42,14 @@ namespace Ryujinx.Common return StreamUtils.StreamToBytes(stream); } - public static IMemoryOwner<byte> ReadFileToRentedMemory(string filename) + public static MemoryOwner<byte> ReadFileToRentedMemory(string filename) { var (assembly, path) = ResolveManifestPath(filename); return ReadFileToRentedMemory(assembly, path); } - public static IMemoryOwner<byte> ReadFileToRentedMemory(Assembly assembly, string filename) + public static MemoryOwner<byte> ReadFileToRentedMemory(Assembly assembly, string filename) { using var stream = GetStream(assembly, filename); diff --git a/src/Ryujinx.Common/Utilities/StreamUtils.cs b/src/Ryujinx.Common/Utilities/StreamUtils.cs index 74b6af5e..aeb6e0d5 100644 --- a/src/Ryujinx.Common/Utilities/StreamUtils.cs +++ b/src/Ryujinx.Common/Utilities/StreamUtils.cs @@ -1,6 +1,5 @@ using Microsoft.IO; using Ryujinx.Common.Memory; -using System.Buffers; using System.IO; using System.Threading; using System.Threading.Tasks; @@ -16,7 +15,7 @@ namespace Ryujinx.Common.Utilities return output.ToArray(); } - public static IMemoryOwner<byte> StreamToRentedMemory(Stream input) + public static MemoryOwner<byte> StreamToRentedMemory(Stream input) { if (input is MemoryStream inputMemoryStream) { @@ -26,9 +25,9 @@ namespace Ryujinx.Common.Utilities { long bytesExpected = input.Length; - IMemoryOwner<byte> ownedMemory = ByteMemoryPool.Rent(bytesExpected); + MemoryOwner<byte> ownedMemory = MemoryOwner<byte>.Rent(checked((int)bytesExpected)); - var destSpan = ownedMemory.Memory.Span; + var destSpan = ownedMemory.Span; int totalBytesRead = 0; @@ -66,14 +65,14 @@ namespace Ryujinx.Common.Utilities return stream.ToArray(); } - private static IMemoryOwner<byte> MemoryStreamToRentedMemory(MemoryStream input) + private static MemoryOwner<byte> MemoryStreamToRentedMemory(MemoryStream input) { input.Position = 0; - IMemoryOwner<byte> ownedMemory = ByteMemoryPool.Rent(input.Length); + MemoryOwner<byte> ownedMemory = MemoryOwner<byte>.Rent(checked((int)input.Length)); // Discard the return value because we assume reading a MemoryStream always succeeds completely. - _ = input.Read(ownedMemory.Memory.Span); + _ = input.Read(ownedMemory.Span); return ownedMemory; } diff --git a/src/Ryujinx.Cpu/Jit/MemoryManagerHostTracked.cs b/src/Ryujinx.Cpu/Jit/MemoryManagerHostTracked.cs index 663d0aeb..501109b8 100644 --- a/src/Ryujinx.Cpu/Jit/MemoryManagerHostTracked.cs +++ b/src/Ryujinx.Cpu/Jit/MemoryManagerHostTracked.cs @@ -303,9 +303,9 @@ namespace Ryujinx.Cpu.Jit } else { - IMemoryOwner<byte> memoryOwner = ByteMemoryPool.Rent(size); + MemoryOwner<byte> memoryOwner = MemoryOwner<byte>.Rent(size); - Read(va, memoryOwner.Memory.Span); + Read(va, memoryOwner.Span); return new WritableRegion(this, va, memoryOwner); } diff --git a/src/Ryujinx.Memory/VirtualMemoryManagerBase.cs b/src/Ryujinx.Memory/VirtualMemoryManagerBase.cs index 506e25f6..f4107224 100644 --- a/src/Ryujinx.Memory/VirtualMemoryManagerBase.cs +++ b/src/Ryujinx.Memory/VirtualMemoryManagerBase.cs @@ -130,9 +130,9 @@ namespace Ryujinx.Memory } else { - IMemoryOwner<byte> memoryOwner = ByteMemoryPool.Rent(size); + MemoryOwner<byte> memoryOwner = MemoryOwner<byte>.Rent(size); - Read(va, memoryOwner.Memory.Span); + Read(va, memoryOwner.Span); return new WritableRegion(this, va, memoryOwner); } -- cgit v1.2.3-70-g09d2