hlsf gong on rewrite again

This commit is contained in:
Youmu Liu
2025-11-27 20:13:09 +08:00
parent 83537c7be7
commit a3570bf20a
7 changed files with 267 additions and 242 deletions
@@ -39,6 +39,54 @@ namespace StgSharp.HighPerformance.Memory
public unsafe partial class HybridLayerSegregatedFitAllocator
{
/// <summary>
/// Minimal collect: linear scan, merge contiguous empty Blocks into one, push merged head
/// back to bucket. Caller-responsible design: no slicing or redistribution.
/// </summary>
public void Collect()
{
Entry* cur = _positionHead;
while (cur != null && cur != _spareMemory)
{
if (cur->State != EntryState.Empty)
{
cur = cur->NextNear;
continue;
}
Entry* runHead = cur;
Entry* next = runHead->NextNear;
// Remove head from bucket if currently registered
int headLevel = runHead->Level;
int headSeg = DetermineSegmentIndex(runHead->Size, headLevel);
TryRemoveFromBucket(headLevel, headSeg, (BucketNode*)runHead->Position);
while (next != null &&
next != _spareMemory &&
next->State == EntryState.Empty &&
IsAdjacentTo(runHead, next))
{
int lvl = next->Level;
int seg = DetermineSegmentIndex(next->Size, lvl);
TryRemoveFromBucket(lvl, seg, (BucketNode*)next->Position);
runHead->Size += next->Size;
RemoveFromPositionChain(next);
next = runHead->NextNear;
}
// Recompute level for merged block and push once
runHead->Level = GetLevelFromSize(runHead->Size);
int finalLevel = runHead->Level;
int finalSeg = DetermineSegmentIndex(runHead->Size, finalLevel);
((BucketNode*)runHead->Position)->EntryRef = runHead; // ensure consistency
PushLevel(finalLevel, finalSeg, (BucketNode*)runHead->Position);
cur = next;
}
}
/// <summary>
/// Free allocated memory block and perform adjacent block merging
/// </summary>
@@ -55,7 +103,7 @@ namespace StgSharp.HighPerformance.Memory
return;
}
// Set to ThreadOccupied to prevent other operations
// Mark as empty so it can be merged
e->State = EntryState.Empty;
// Try merge with adjacent free blocks and remove them from buckets
@@ -66,9 +114,6 @@ namespace StgSharp.HighPerformance.Memory
int finalLevel = GetLevelFromSize(finalSize);
int finalSegment = DetermineSegmentIndex(finalSize, finalLevel);
// Set the merged entry state to Empty (ready to be reused)
e->State = EntryState.Empty;
// Push the merged entry back to appropriate bucket
PushLevel(finalLevel, finalSegment, (BucketNode*)e->Position);
}