HLSF single thread pass, dead lock on multi thread test

Signed-off-by: Youmu Liu <105042599+Nitload-NSI@users.noreply.github.com>
This commit is contained in:
Youmu Liu
2025-08-22 22:10:05 +08:00
parent fb9398e8be
commit 539300b3fa
172 changed files with 2660 additions and 1862 deletions
@@ -63,7 +63,6 @@ namespace StgSharp.HighPerformance.Memory
return new hlsfHandle(handle, size);
}
fallback:
i = level;
s = segmentIndex;
while (!TryPopLevelForAllocation(i, s, out handle))
@@ -79,8 +78,7 @@ namespace StgSharp.HighPerformance.Memory
throw new OverflowException("Out of memory: Unable to allocate new 16MB block or find suitable bucket for allocation.");
}
Thread.Sleep(0);
goto fallback;
break;
}
}
@@ -89,15 +87,17 @@ namespace StgSharp.HighPerformance.Memory
if (handle != null)
{
AcquireEntryNextLock(handle);
uint allocSize = (uint)((segmentIndex + 1) * levelSizeArray[level]);
SliceMemory(handle, (segmentIndex + 1) * levelSizeArray[level]);
handle->Level = level;
handle->Size = allocSize;
SetEntryState(handle, EntryState.Allocated);
}
return new hlsfHandle(handle, size);
}
finally
{
ReleaseEntryNextLock(handle);
ReleaseEntrySpinLock(handle);
}
}
@@ -105,26 +105,32 @@ namespace StgSharp.HighPerformance.Memory
{
Entry* current = e;
ulong n = e->NextNear;
Entry* next = e;
Entry* next = (Entry*)n;
ulong originOffset = e->Position - (ulong)m_Buffer;
ulong finalOffset = originOffset + (ulong)offset;
ulong end = e->Position + e->Size - (ulong)m_Buffer;
int remainSize = (int)(e->Size - offset);
AcquireEntryNextLock(e);
AcquireEntryPrevLock(next);
AcquireEntryBothLocks(e);
if (next != null) {
AcquireEntryPrevLock(next);
}
try
{
if ((originOffset & 63) != 0) {
throw new InvalidOperationException("Entry position offset is not aligned to 64 bytes.");
}
int minLevel = Math.Max((BitOperations.TrailingZeroCount(originOffset) - 6) / 2, 0);
int i = minLevel >= levelSizeArray.Length ? levelSizeArray.Length - 1 : minLevel;
for (; i < levelSizeArray.Length; i++)
{
int levelSize = levelSizeArray[i];
int blockCount = remainSize / levelSize % 4;
ulong board = (finalOffset + (ulong)levelSize - 1) & ~((ulong)levelSize - 1);
int blockCount = (int)(ulong.Min(board, end) / (ulong)levelSize);
if (blockCount == 0)
{
break;
@@ -145,7 +151,9 @@ namespace StgSharp.HighPerformance.Memory
newEntry->PreviousNear = (ulong)current;
newEntry->NextNear = n;
current->NextNear = (ulong)newEntry;
next->PreviousNear = (ulong)newEntry;
if (next != null) {
next->PreviousNear = (ulong)newEntry;
}
newEntry->Level = i;
PushLevel(i, blockCount - 1, bucket);
@@ -160,16 +168,16 @@ namespace StgSharp.HighPerformance.Memory
ReleaseEntryNextLock(old);
AcquireEntryNextLock(current);
}
if (remainSize <= 0)
{
ReleaseEntryNextLock(current);
ReleaseEntryPrevLock(next);
if (remainSize <= 0) {
return;
}
for (; i >= 0; i--)
{
int levelSize = levelSizeArray[i];
int blockCount = remainSize / levelSize % 4;
ulong board = (finalOffset + (ulong)levelSize - 1) & ~((ulong)levelSize - 1);
int blockCount = (int)(ulong.Min(board, end) / (ulong)levelSize);
if (blockCount == 0)
{
continue;
@@ -188,9 +196,11 @@ namespace StgSharp.HighPerformance.Memory
// link new entry
newEntry->PreviousNear = (ulong)current;
current->NextNear = (ulong)newEntry;
newEntry->NextNear = n;
next->PreviousNear = (ulong)newEntry;
current->NextNear = (ulong)newEntry;
if (next != null) {
next->PreviousNear = (ulong)newEntry;
}
newEntry->Level = i;
PushLevel(i, blockCount - 1, bucket);
@@ -216,9 +226,10 @@ namespace StgSharp.HighPerformance.Memory
}
finally
{
// Release locks in reverse order
ReleaseEntryNextLock(current);
ReleaseEntryPrevLock(next);
ReleaseEntryBothLocks(e);
if (next != null) {
ReleaseEntryPrevLock(next);
}
}
}