mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Skeleton BlockCacheBufferedStorage
This commit is contained in:
parent
c765ab999e
commit
eaff8059ba
6 changed files with 286 additions and 3 deletions
src/LibHac
|
@ -287,4 +287,11 @@ public enum SdmmcPort
|
|||
Mmc = 0,
|
||||
SdCard = 1,
|
||||
GcAsic = 2
|
||||
}
|
||||
|
||||
public enum StorageType
|
||||
{
|
||||
SaveData = 0,
|
||||
RomFs = 1,
|
||||
Authoring = 2
|
||||
}
|
14
src/LibHac/FsSystem/BitmapUtils.cs
Normal file
14
src/LibHac/FsSystem/BitmapUtils.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using LibHac.Diag;
|
||||
|
||||
namespace LibHac.FsSystem;
|
||||
|
||||
public static class BitmapUtils
|
||||
{
|
||||
public static uint ILog2(uint value)
|
||||
{
|
||||
Assert.SdkRequiresGreater(value, 0u);
|
||||
|
||||
const uint intBitCount = 32;
|
||||
return intBitCount - 1 - (uint)Util.BitUtil.CountLeadingZeros(value);
|
||||
}
|
||||
}
|
249
src/LibHac/FsSystem/BlockCacheBufferedStorage.cs
Normal file
249
src/LibHac/FsSystem/BlockCacheBufferedStorage.cs
Normal file
|
@ -0,0 +1,249 @@
|
|||
using System;
|
||||
using LibHac.Diag;
|
||||
using LibHac.Fs;
|
||||
using LibHac.FsSystem.Impl;
|
||||
using LibHac.Os;
|
||||
using Buffer = LibHac.Mem.Buffer;
|
||||
|
||||
// Todo: Remove warning suppressions after implementing
|
||||
// ReSharper disable All
|
||||
#pragma warning disable CS0414
|
||||
|
||||
namespace LibHac.FsSystem;
|
||||
|
||||
public class BlockCacheBufferedStorage : IStorage
|
||||
{
|
||||
public struct CacheEntry : IBlockCacheManagerEntry<AccessRange>
|
||||
{
|
||||
public AccessRange Range { get; }
|
||||
public bool IsValid { get; set; }
|
||||
public bool IsWriteBack { get; set; }
|
||||
public bool IsCached { get; set; }
|
||||
public bool IsFlushing { get; set; }
|
||||
public short Age { get; set; }
|
||||
public ulong Handle { get; set; }
|
||||
public Buffer Buffer { get; set; }
|
||||
|
||||
public void Invalidate()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public readonly bool IsAllocated()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public struct AccessRange : IBlockCacheManagerRange
|
||||
{
|
||||
public long Offset { get; set; }
|
||||
public long Size { get; set; }
|
||||
|
||||
public readonly long GetEndOffset()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public readonly long IsIncluded(long offset)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
private SdkRecursiveMutex _mutex;
|
||||
private IStorage _storageData;
|
||||
private Result _lastResult;
|
||||
private long _sizeBytesData;
|
||||
private int _sizeBytesVerificationBlock;
|
||||
private int _shiftBytesVerificationBlock;
|
||||
private int _flags;
|
||||
private int _bufferLevel;
|
||||
private StorageType _storageType;
|
||||
private BlockCacheManager<CacheEntry, AccessRange> _cacheManager;
|
||||
|
||||
public BlockCacheBufferedStorage()
|
||||
{
|
||||
_bufferLevel = -1;
|
||||
_cacheManager = new BlockCacheManager<CacheEntry, AccessRange>();
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
FinalizeObject();
|
||||
_cacheManager.Dispose();
|
||||
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
public bool IsEnabledKeepBurstMode()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void SetKeepBurstMode(bool isEnabled)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void SetRealDataCache(bool isEnabled)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result Initialize(IBufferManager bufferManager, SdkRecursiveMutex mutex, IStorage data, long dataSize,
|
||||
int sizeBytesVerificationBlock, int maxCacheEntries, bool useRealDataCache, sbyte bufferLevel,
|
||||
bool useKeepBurstMode, StorageType storageType)
|
||||
{
|
||||
Assert.SdkNotNull(data);
|
||||
Assert.SdkNotNull(mutex);
|
||||
Assert.SdkNull(_mutex);
|
||||
Assert.SdkNull(_storageData);
|
||||
Assert.SdkGreater(maxCacheEntries, 0);
|
||||
|
||||
Result rc = _cacheManager.Initialize(bufferManager, maxCacheEntries);
|
||||
if (rc.IsFailure()) return rc.Miss();
|
||||
|
||||
_mutex = mutex;
|
||||
_storageData = data;
|
||||
_sizeBytesData = dataSize;
|
||||
_sizeBytesVerificationBlock = sizeBytesVerificationBlock;
|
||||
_lastResult = Result.Success;
|
||||
_flags = 0;
|
||||
_bufferLevel = bufferLevel;
|
||||
_storageType = storageType;
|
||||
_shiftBytesVerificationBlock = (int)BitmapUtils.ILog2((uint)sizeBytesVerificationBlock);
|
||||
|
||||
Assert.SdkEqual(1 << _shiftBytesVerificationBlock, _sizeBytesVerificationBlock);
|
||||
|
||||
SetKeepBurstMode(useKeepBurstMode);
|
||||
SetRealDataCache(useRealDataCache);
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public void FinalizeObject()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override Result GetSize(out long size)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override Result SetSize(long size)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override Result Read(long offset, Span<byte> destination)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override Result Write(long offset, ReadOnlySpan<byte> source)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override Result Flush()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override Result OperateRange(Span<byte> outBuffer, OperationId operationId, long offset, long size,
|
||||
ReadOnlySpan<byte> inBuffer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result Commit()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result OnRollback()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private Result FillZeroImpl(long offset, long size)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private Result DestroySignatureImpl(long offset, long size)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private Result InvalidateImpl()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private Result QueryRangeImpl(Span<byte> outBuffer, long offset, long size)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private Result GetAssociateBuffer(out Buffer outRange, out CacheEntry outEntry, long offset, int idealSize,
|
||||
bool isAllocateForWrite)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private Result StoreOrDestroyBuffer(in Buffer memoryRange, ref CacheEntry entry)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private Result StoreOrDestroyBuffer(out int outCacheIndex, in Buffer memoryRange, ref CacheEntry entry)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private Result FlushCacheEntry(int index, bool isWithInvalidate)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private Result FlushRangeCacheEntries(long offset, long size, bool isWithInvalidate)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private Result FlushAllCacheEntries()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private Result ControlDirtiness()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private Result UpdateLastResult(Result result)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private Result ReadHeadCache(out Buffer outMemoryRange, out CacheEntry outEntry, out bool outIsCacheNeeded,
|
||||
ref long offset, ref long offsetAligned, long offsetAlignedEnd, ref Span<byte> buffer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private Result ReadTailCache(out Buffer outMemoryRange, out CacheEntry outEntry, out bool outIsCacheNeeded,
|
||||
long offset, long offsetAligned, long offsetAlignedEnd, Span<byte> buffer, ref long size)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private Result BulkRead(long offset, Span<byte> buffer, ref Buffer memoryRangeHead, ref Buffer memoryRangeTail,
|
||||
ref CacheEntry entryHead, ref CacheEntry entryTail, bool isHeadCacheNeeded, bool isTailCacheNeeded)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
|
@ -162,8 +162,8 @@ public class CompressedStorage : IStorage, IAsynchronousAccessSplitter
|
|||
public long Offset { get; set; }
|
||||
public uint Size { get; set; }
|
||||
|
||||
public long GetEndOffset() => Offset + Size;
|
||||
public bool IsIncluded(long offset) => Offset <= offset && offset < GetEndOffset();
|
||||
public readonly long GetEndOffset() => Offset + Size;
|
||||
public readonly bool IsIncluded(long offset) => Offset <= offset && offset < GetEndOffset();
|
||||
}
|
||||
|
||||
public struct AccessRange
|
||||
|
|
|
@ -28,6 +28,13 @@ public interface IBlockCacheManagerRange
|
|||
long GetEndOffset();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles caching buffers with the given <see cref="IBufferManager"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntry">The type of the entries to be stores in the cache manager.</typeparam>
|
||||
/// <typeparam name="TRange">The type that <typeparamref name="TEntry"/> uses
|
||||
/// to represent the range cached by an entry.</typeparam>
|
||||
/// <remarks>Based on FS 13.1.0 (nnSdk 13.4.0)</remarks>
|
||||
public class BlockCacheManager<TEntry, TRange> : IDisposable
|
||||
where TEntry : struct, IBlockCacheManagerEntry<TRange>
|
||||
where TRange : struct, IBlockCacheManagerRange
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.Runtime.CompilerServices;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace LibHac.Util;
|
||||
|
||||
|
@ -36,6 +37,11 @@ public static class BitUtil
|
|||
return value & (value - 1);
|
||||
}
|
||||
|
||||
public static int CountLeadingZeros(uint value)
|
||||
{
|
||||
return BitOperations.LeadingZeroCount(value);
|
||||
}
|
||||
|
||||
// DivideUp comes from a C++ template that always casts to unsigned types
|
||||
public static uint DivideUp(uint value, uint divisor) => (value + divisor - 1) / divisor;
|
||||
public static ulong DivideUp(ulong value, ulong divisor) => (value + divisor - 1) / divisor;
|
||||
|
|
Loading…
Reference in a new issue