Update on 20260511-001810 by Nitload Youmu. Additional Message : Abort HLSF design, use a non-standard TLSF as instead

Signed-off-by: Nitload <YoumuLiu_NSI@whv0t.onmicrosoft.com>
This commit is contained in:
Nitload
2026-05-11 00:18:10 +08:00
parent 5e73469c2e
commit 8105af6ca3
@@ -2,8 +2,8 @@
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// file="TwoLayerSegregatedFitAllocator" // file="TwoLayerSegregatedFitAllocator"
// Project: StgSharp // Project: StgSharp
// AuthorGroup: Nitload // AuthorGroup: Nitload Space
// Copyright (c) Nitload. All rights reserved. // Copyright (c) Nitload Space. All rights reserved.
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
@@ -31,6 +31,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
using System.Reflection.Metadata;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -43,12 +44,13 @@ namespace StgSharp.HighPerformance.Memory
private const ulong Mask48Bits = 0x0000FFFFFFFFFFFF; private const ulong Mask48Bits = 0x0000FFFFFFFFFFFF;
private Metadata* _allocEnd;
private readonly Metadata*[] _bucket; private readonly Metadata*[] _bucket;
private readonly Metadata* _spareMemory; private readonly Metadata* _spareMemory;
private readonly Action<nuint> _freeHandle; private readonly Action<nuint> _freeHandle;
private bool disposedValue; private bool disposedValue;
private readonly int _align; private readonly int _align;
private int _allocEnd;
private readonly Ptr64 _basePtr; private readonly Ptr64 _basePtr;
private readonly ulong _maxAllocSize; private readonly ulong _maxAllocSize;
private readonly ulong _totalSize; private readonly ulong _totalSize;
@@ -58,8 +60,7 @@ namespace StgSharp.HighPerformance.Memory
int align, int align,
ulong maxBlockSize, ulong maxBlockSize,
Func<nuint, int, nuint> allocator, Func<nuint, int, nuint> allocator,
Action<nuint> freeHandle Action<nuint> freeHandle)
)
: this(byteSize, align, maxBlockSize, (void*)allocator(byteSize, align), freeHandle) { } : this(byteSize, align, maxBlockSize, (void*)allocator(byteSize, align), freeHandle) { }
internal TwoLayerSegregatedFitAllocator( internal TwoLayerSegregatedFitAllocator(
@@ -67,8 +68,7 @@ namespace StgSharp.HighPerformance.Memory
int align, int align,
ulong maxBlockSize, ulong maxBlockSize,
void* externalPointer, void* externalPointer,
Action<nuint> freeHandle Action<nuint> freeHandle)
)
{ {
_totalSize = byteSize; _totalSize = byteSize;
_basePtr = (Ptr64)(ulong)externalPointer; _basePtr = (Ptr64)(ulong)externalPointer;
@@ -77,7 +77,7 @@ namespace StgSharp.HighPerformance.Memory
_bucket = new Metadata*[58 - BitOperations.LeadingZeroCount(_maxAllocSize)]; _bucket = new Metadata*[58 - BitOperations.LeadingZeroCount(_maxAllocSize)];
_spareMemory = &((Metadata*)(ulong)(_basePtr + _totalSize))[-1]; _spareMemory = &((Metadata*)(ulong)(_basePtr + _totalSize))[-1];
_freeHandle = freeHandle ?? (static_ => { }); _freeHandle = freeHandle ?? (static_ => { });
_allocEnd = _spareMemory; _allocEnd = 0;
// init spare memory node // init spare memory node
@@ -89,37 +89,23 @@ namespace StgSharp.HighPerformance.Memory
_spareMemory->PreviousNear = 0; _spareMemory->PreviousNear = 0;
} }
public TwoLayerSegregatedFitAllocator( public TwoLayerSegregatedFitAllocator(nuint byteSize)
nuint byteSize
)
: this(byteSize, 16, 32U * 1024U * 1024U, NativeMemory.AlignedAlloc(byteSize, 16), : this(byteSize, 16, 32U * 1024U * 1024U, NativeMemory.AlignedAlloc(byteSize, 16),
ptr => NativeMemory.AlignedFree((void*)ptr)) { } ptr => NativeMemory.AlignedFree((void*)ptr)) { }
public TwoLayerSegregatedFitAllocator( public TwoLayerSegregatedFitAllocator(nuint byteSize, uint maxBlockSize)
nuint byteSize,
uint maxBlockSize
)
: this(byteSize, 16, maxBlockSize, NativeMemory.AlignedAlloc(byteSize, 16), : this(byteSize, 16, maxBlockSize, NativeMemory.AlignedAlloc(byteSize, 16),
ptr => NativeMemory.AlignedFree((void*)ptr)) { } ptr => NativeMemory.AlignedFree((void*)ptr)) { }
public TwoLayerSegregatedFitAllocator( public TwoLayerSegregatedFitAllocator(nuint byteSize, int align)
nuint byteSize,
int align
)
: this(byteSize, align, 32U * 1024U * 1024U, NativeMemory.AlignedAlloc(byteSize, 16), : this(byteSize, align, 32U * 1024U * 1024U, NativeMemory.AlignedAlloc(byteSize, 16),
ptr => NativeMemory.AlignedFree((void*)ptr)) { } ptr => NativeMemory.AlignedFree((void*)ptr)) { }
public TwoLayerSegregatedFitAllocator( public TwoLayerSegregatedFitAllocator(nuint byteSize, int align, nuint maxBlockSize)
nuint byteSize,
int align,
nuint maxBlockSize
)
: this(byteSize, align, maxBlockSize, NativeMemory.AlignedAlloc(byteSize, 16), : this(byteSize, align, maxBlockSize, NativeMemory.AlignedAlloc(byteSize, 16),
ptr => NativeMemory.AlignedFree((void*)ptr)) { } ptr => NativeMemory.AlignedFree((void*)ptr)) { }
public Handle Alloc( public Handle Alloc(nuint size)
nuint size
)
{ {
ulong allocSize = nuint.Max(64, (~64U) & (size + 63)); ulong allocSize = nuint.Max(64, (~64U) & (size + 63));
if (allocSize > _maxAllocSize) { if (allocSize > _maxAllocSize) {
@@ -136,11 +122,11 @@ namespace StgSharp.HighPerformance.Memory
break; break;
} }
} }
if (entry is null) if (entry is null && !TryGetNewMetadata(allocSize, out entry)) {
{ throw new OverflowException("No available ");
// alloc new from spare
} }
ulong remain = entry->Size - allocSize; ulong remain = entry->Size - allocSize;
throw new NotImplementedException(); throw new NotImplementedException();
} }
@@ -150,16 +136,12 @@ namespace StgSharp.HighPerformance.Memory
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
public void Free( public void Free(Handle handle)
Handle handle
)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
protected virtual void Dispose( protected virtual void Dispose(bool disposing)
bool disposing
)
{ {
if (!disposedValue) if (!disposedValue)
{ {
@@ -171,12 +153,49 @@ namespace StgSharp.HighPerformance.Memory
} }
} }
private bool TryGetNewMetadata(ulong size, out Metadata* meta)
{
int idx = _spareMemory->NextLevel;
if (idx != 0)
{
meta = &_spareMemory[-idx];
_spareMemory->NextLevel = meta->NextLevel;
return true;
}
ulong spareSize = _spareMemory->Size;
if (spareSize < 32UL + size)
{
meta = null;
return false;
}
_allocEnd++;
meta = &_spareMemory[-_allocEnd];
spareSize -= 32UL - size;
_spareMemory->Size = spareSize;
_spareMemory->Position += size;
meta->Size = size;
return true;
}
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct Handle public readonly struct Handle
{ {
internal readonly Metadata* Meta; internal readonly Metadata* _meta;
public readonly void* Pointer; public readonly void* Pointer;
public readonly Ptr64 Size;
internal Handle(Metadata* meta, Ptr64 baseAddress)
{
_meta = meta;
Pointer = (void*)(ulong)(meta->Position + baseAddress);
Size = meta->Size;
}
[Obsolete("You should not create instance from default. Alloc from allocator please")]
public Handle() { }
public ref byte this[int offset] => ref ((byte*)Pointer)[offset];
} }
@@ -207,6 +226,12 @@ namespace StgSharp.HighPerformance.Memory
set => SizeMask = (SizeMask & ~Mask48Bits) | ((ulong)value & Mask48Bits); set => SizeMask = (SizeMask & ~Mask48Bits) | ((ulong)value & Mask48Bits);
} }
public Ptr64 SizeForSpare
{
get => SizeMask;
set => SizeMask = value;
}
public static uint SizeOf { get; } = (uint)Unsafe.SizeOf<Metadata>(); public static uint SizeOf { get; } = (uint)Unsafe.SizeOf<Metadata>();
} }