hlsf error is solving

This commit is contained in:
Youmu Liu
2025-11-28 18:18:08 +08:00
parent a3570bf20a
commit 0c90461d35
8 changed files with 253 additions and 281 deletions
@@ -34,6 +34,17 @@ namespace StgSharp.HighPerformance.Memory
public unsafe partial class HybridLayerSegregatedFitAllocator
{
/// <summary>
/// Check if two Entries are adjacent in memory
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool AssertAdjacentTo(Entry* current, Entry* other)
{
// Only a predicate; never throw here. Callers rely on false to skip merging.
return other->Position + (nuint)other->Size == current->Position ||
current->Position + (nuint)current->Size == other->Position;
}
/// <summary>
/// check out if a bucket is within the same higher-level boundary as currentOffset
/// </summary>
@@ -50,21 +61,10 @@ namespace StgSharp.HighPerformance.Memory
/// Determine segment index based on size and originLevel
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private int DetermineSegmentIndex(uint size, int level)
private int DetermineSegmentIndex(long size, int level)
{
level = int.Min(level, MaxLevel);
return (int)(size - 1) / levelSizeArray[level];
}
/// <summary>
/// Check if two Entries are adjacent in memory
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool IsAdjacentTo(Entry* current, Entry* other)
{
// Check if this immediately follows other
return other->Position + other->Size == current->Position ||
current->Position + current->Size == other->Position;
return (int)((size - 1) / levelSizeArray[level]);
}
/// <summary>
@@ -80,19 +80,16 @@ namespace StgSharp.HighPerformance.Memory
return;
}
Entry* result = entry;
uint size = entry->Size;
long size = entry->Size;
int originLevel = entry->Level;
int segment = DetermineSegmentIndex(size, originLevel);
do
{
// previous direction merge
Entry* p = entry->PreviousNear;
if (p == null ||
p->State != EntryState.Empty ||
!IsAdjacentTo(result, p) ||
!AssertAdjacentTo(entry, p) ||
p->Level != entry->Level ||
!AssertBoundary(p, entry, originLevel))
{
@@ -112,7 +109,7 @@ namespace StgSharp.HighPerformance.Memory
Entry* n = entry->NextNear;
if (n == null ||
n->State != EntryState.Empty ||
!IsAdjacentTo(result, n) ||
!AssertAdjacentTo(entry, n) ||
n->Level != entry->Level ||
!AssertBoundary(n, entry, originLevel))
{
@@ -133,24 +130,16 @@ namespace StgSharp.HighPerformance.Memory
}
/// <summary>
/// Remove node from position linked list
/// Remove node from position linked list, this method does not recycle a BucketNode from
/// size bucket
/// </summary>
private void RemoveFromPositionChain(Entry* entry)
{
Entry* prev = entry->PreviousNear;
Entry* next = entry->NextNear;
if (prev != null)
{
prev->NextNear = entry->NextNear;
} else
{
_positionHead = entry->NextNear;
}
if (next != null) {
next->PreviousNear = entry->PreviousNear;
}
prev->NextNear = next;
next->PreviousNear = prev;
// Clear node pointers
entry->NextNear = null;
@@ -164,25 +153,28 @@ namespace StgSharp.HighPerformance.Memory
/// Entry structure - streamlined version (only position and state information) Stored in
/// external SLAB
/// </summary>
[StructLayout(LayoutKind.Explicit, Size = 36)]
[StructLayout(LayoutKind.Explicit, Size = 40)]
internal struct Entry
{
[FieldOffset(8)] internal Entry* NextNear; // Position linked list: next pointer
[FieldOffset(16)] internal Entry* PreviousNear; // Position linked list: previous pointer
[FieldOffset(0)] internal Entry* NextNear; // Position linked list: next pointer
[FieldOffset(8)] internal Entry* PreviousNear; // Position linked list: previous pointer
[FieldOffset(28)] internal int _Level; // Level of the block in the allocator
[FieldOffset(24)] internal uint Size; // Block size information
[FieldOffset(32)] public EntryState State;
[FieldOffset(0)] public nuint Position; // Memory block position
[FieldOffset(24)] internal int _Level; // Level of the block in the allocator
[FieldOffset(16)] internal long Size; // Block size information
[FieldOffset(36)] public EntryState State;
[FieldOffset(28)] public nuint Position; // Memory block position
public int Level
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _Level;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set
{
if (value > 15 || value < 0) {
throw new InvalidOperationException();
int size = 64 * (1 << (value * 2));
if (Size / size > 3 && Size < 64 * 1024 * 1024L) {
throw new HLSFPositionChainBreakException();
}
_Level = value;
}
@@ -195,7 +187,8 @@ namespace StgSharp.HighPerformance.Memory
Spare,
Empty,
Allocated
Alloc,
Large
}