Skip to content

Commit

Permalink
Reduce allocations by FatFileSystem
Browse files Browse the repository at this point in the history
  • Loading branch information
GoldenretriverYT committed Dec 10, 2023
1 parent fb46536 commit c92678f
Showing 1 changed file with 18 additions and 13 deletions.
31 changes: 18 additions & 13 deletions source/Cosmos.System2/FileSystem/FAT/FatFileSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ internal class Fat

private readonly ulong mFatSector;

/// <summary>
/// A reused buffer for <see cref="GetFatEntry(uint, out uint)"/>s read operations to save on allocations.
/// </summary>
private byte[] _getFatEntryReadBuffer;

/// <summary>
/// Initializes a new instance of the <see cref="Fat"/> class.
/// </summary>
Expand All @@ -43,6 +48,7 @@ public Fat(FatFileSystem aFileSystem, ulong aFatSector)

mFileSystem = aFileSystem;
mFatSector = aFatSector;
_getFatEntryReadBuffer = mFileSystem.NewBlockArray();
}

/// <summary>
Expand Down Expand Up @@ -271,8 +277,8 @@ public void ClearAllFat()
Global.Debugger.SendInternal($"RootCluster is {mFileSystem.RootCluster}");
Global.Debugger.SendInternal("Clearing all Fat Table");

byte[] xFatTableFirstSector;
ReadFatSector(0, out xFatTableFirstSector);
byte[] xFatTableFirstSector = mFileSystem.NewBlockArray();
ReadFatSector(0, ref xFatTableFirstSector);

/* Change 3rd entry (RootDirectory) to be EOC */
SetValueInFat(2, FatEntryEofValue(), xFatTableFirstSector);
Expand Down Expand Up @@ -311,10 +317,8 @@ public void ClearAllFat()
/// <param name="aData">Output data byte.</param>
/// <exception cref="OverflowException">Thrown when data lenght is greater then Int32.MaxValue.</exception>
/// <exception cref="Exception">Thrown when data size invalid.</exception>
private void ReadFatSector(ulong aSector, out byte[] aData)
{
private void ReadFatSector(ulong aSector, ref byte[] aData) {
Global.Debugger.SendInternal("-- FatFileSystem.ReadFatSector --");
aData = mFileSystem.NewBlockArray();
ulong xSector = mFatSector + aSector;
Global.Debugger.SendInternal("xSector =" + xSector);
mFileSystem.Device.ReadBlock(xSector, mFileSystem.SectorsPerCluster, ref aData);
Expand Down Expand Up @@ -364,15 +368,15 @@ internal void GetFatEntry(uint aEntryNumber, out uint aValue)
ulong xSector = xEntryOffset / mFileSystem.BytesPerSector;
Global.Debugger.SendInternal("xSector = " + xSector);

ReadFatSector(xSector, out byte[] xData);
ReadFatSector(xSector, ref _getFatEntryReadBuffer);

switch (mFileSystem.mFatType)
{
case FatTypeEnum.Fat12:
// We now access the FAT entry as a WORD just as we do for FAT16, but if the cluster number is
// EVEN, we only want the low 12-bits of the 16-bits we fetch. If the cluster number is ODD
// we want the high 12-bits of the 16-bits we fetch.
uint xResult = BitConverter.ToUInt16(xData, (int)xEntryOffset);
uint xResult = BitConverter.ToUInt16(_getFatEntryReadBuffer, (int)xEntryOffset);
if ((aEntryNumber & 0x01) == 0)
{
aValue = xResult & 0x0FFF; // Even
Expand All @@ -384,12 +388,12 @@ internal void GetFatEntry(uint aEntryNumber, out uint aValue)
break;

case FatTypeEnum.Fat16:
aValue = BitConverter.ToUInt16(xData, (int)xEntryOffset);
aValue = BitConverter.ToUInt16(_getFatEntryReadBuffer, (int)xEntryOffset);
break;

case FatTypeEnum.Fat32:
int localOffset = (int)(xEntryOffset % mFileSystem.BytesPerSector);
aValue = BitConverter.ToUInt32(xData, localOffset) & 0x0FFFFFFF;
aValue = BitConverter.ToUInt32(_getFatEntryReadBuffer, localOffset) & 0x0FFFFFFF;
break;

default:
Expand Down Expand Up @@ -420,8 +424,8 @@ internal void SetFatEntry(ulong aEntryNumber, ulong aValue)
ulong xSector = xEntryOffset / mFileSystem.BytesPerSector;
int localOffset = (int)(xEntryOffset % mFileSystem.BytesPerSector);

byte[] xData;
ReadFatSector(xSector, out xData);
byte[] xData = mFileSystem.NewBlockArray();
ReadFatSector(xSector, ref xData);

switch (mFileSystem.mFatType)
{
Expand All @@ -442,6 +446,7 @@ internal void SetFatEntry(ulong aEntryNumber, ulong aValue)
}

WriteFatSector(xSector, xData);
GCImplementation.Free(xData);
Global.Debugger.SendInternal("Returning from --- Fat.SetFatEntry ---");
}

Expand All @@ -468,8 +473,8 @@ internal void SetFatEntry(ulong aEntryNumber, byte[] aData, uint aOffset, uint a
ulong xSector = xEntryOffset / mFileSystem.BytesPerSector;
ulong xSectorOffset = xSector * mFileSystem.BytesPerSector - xEntryOffset;

byte[] xData;
ReadFatSector(xSectorOffset, out xData);
byte[] xData = mFileSystem.NewBlockArray();
ReadFatSector(xSectorOffset, ref xData);

switch (mFileSystem.mFatType)
{
Expand Down

0 comments on commit c92678f

Please sign in to comment.