hlsf wrong alloc solved

This commit is contained in:
Youmu Liu
2025-11-24 17:00:10 +08:00
parent 67a4ac385f
commit b7b960a604
12 changed files with 357 additions and 290 deletions
+13
View File
@@ -78,10 +78,23 @@ namespace StgSharp.HighPerformance
return !(left == right);
}
public static M64 operator <<(M64 value, int shift)
{
M64 result = new M64();
result.value = value.value << shift;
return result;
}
public static bool operator ==(M64 left, M64 right)
{
return left.value == right.value;
}
public static M64 operator >>(M64 value, int shift)
{
M64 result = new M64();
result.value = value.value << shift;
return result;
}
}
}
@@ -2,8 +2,8 @@
// -----------------------------------------------------------------------
// file="HLSFAllocator.Alloc"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
// AuthorGroup: Nitload
// Copyright (c) Nitload. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -74,7 +74,6 @@ namespace StgSharp.HighPerformance.Memory
SliceMemory(handle, (segmentIndex + 1) * levelSizeArray[level]);
}
handle->State = EntryState.Allocated;
Console.WriteLine($"handle alloced at {handle->Position}");
return new hlsfHandle(handle, size);
}
@@ -213,7 +212,8 @@ namespace StgSharp.HighPerformance.Memory
_spareMemory->Position = newPos;
BucketNode* b = (BucketNode*)handle->Position;
b->EntryRef = handle;
PushLevel(handle->Level, DetermineSegmentIndex((uint)blockSize, handle->Level), b);
// PushLevel(handle->Level, DetermineSegmentIndex((uint)blockSize, handle->Level), b);
// update position linked list
handle->NextNear = (ulong)_spareMemory;
@@ -2,8 +2,8 @@
// -----------------------------------------------------------------------
// file="HLSFAllocator.BucketNode"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
// AuthorGroup: Nitload
// Copyright (c) Nitload. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -55,6 +55,10 @@ namespace StgSharp.HighPerformance.Memory
{
_bucketHeads[index] = (nuint)node;
node->IsInBucket = true;
node->NextLevel = EmptyHandle;
node->PreviousLevel = EmptyHandle;
// Console.WriteLine($"Push to empty level of {levelIndex} {sizeIndex}, bucket pos {(ulong)node}");
return;
} else
{
@@ -62,7 +66,10 @@ namespace StgSharp.HighPerformance.Memory
node->NextLevel = head;
BucketNode* headNode = (BucketNode*)head;
node->IsInBucket = true;
if (headNode != null) {
// Console.WriteLine($"Push to head of level of {levelIndex} {sizeIndex}, bucket pos {(ulong)node}, previous head is at {head}");
if (headNode != null)
{
headNode->PreviousLevel = (ulong)node;
}
return;
@@ -111,6 +118,7 @@ namespace StgSharp.HighPerformance.Memory
return false;
}
// Console.WriteLine($"level popped from level {levelIndex} {sizeIndex}, node is at {(ulong)head}");
BucketNode* next = (BucketNode*)head->NextLevel;
if (next == null)
@@ -123,14 +131,8 @@ namespace StgSharp.HighPerformance.Memory
node = head;
node->IsInBucket = false;
node->NextLevel = EmptyHandle;
if (next != null)
{
Console.WriteLine("////////////// catching error ///////////////");
Console.WriteLine($"ref next: {(ulong)next}");
Console.WriteLine($"base pos: {(ulong)m_Buffer}");
Console.WriteLine(_size);
if (next != null) {
next->PreviousLevel = EmptyHandle;
Console.WriteLine("///////////// no error caught ///////////////");
}
return true;
}
@@ -157,6 +159,8 @@ namespace StgSharp.HighPerformance.Memory
node->NextLevel = EmptyHandle;
node->PreviousLevel = EmptyHandle;
node->IsInBucket = false;
return true;
}
@@ -164,30 +168,15 @@ namespace StgSharp.HighPerformance.Memory
/// BucketNode structure - specialized node for bucket linked lists Stored in main
/// allocation area (user-overwritable region)
/// </summary>
[StructLayout(LayoutKind.Explicit, Size = 40)]
[StructLayout(LayoutKind.Explicit)]
internal struct BucketNode
{
[FieldOffset(0)] internal Entry* EntryRef; // Pointer to corresponding Entry
[FieldOffset(32)] internal bool IsInBucket; // Whether in bucket
[FieldOffset(8)] internal ulong _nextLevel; // Bucket stack linked list: next pointer
[FieldOffset(16)] internal ulong LockBuffer;
[FieldOffset(24)] internal ulong PreviousLevel; // Bucket stack linked list: previous pointer
internal ulong NextLevel
{
get
{
Console.WriteLine($"get next level {_nextLevel}");
return _nextLevel;
}
set
{
Console.WriteLine($"NextLevel set to {value}.");
_nextLevel = value;
}
}
[FieldOffset(8)] internal ulong NextLevel; // Bucket stack linked list: next pointer
[FieldOffset(24)] internal ulong PreviousLevel; // Bucket stack linked list: previous pointer
}
@@ -38,6 +38,21 @@ namespace StgSharp.HighPerformance.Memory
public unsafe partial class HybridLayerSegregatedFitAllocator
{
/// <summary>
/// check out if a bucket is within the same higher-level boundary as currentOffset
/// </summary>
/// <param name="currentOffset">
///
/// </param>
/// <param name="target">
///
/// </param>
/// <param name="level">
///
/// </param>
/// <returns>
///
/// </returns>
private bool AssertBackwardBoundary(ulong currentOffset, Entry* target, int level)
{
int nextLevelSize = levelSizeArray[level] * 4;
@@ -45,6 +60,21 @@ namespace StgSharp.HighPerformance.Memory
return (currentOffset / (ulong)nextLevelSize) == (targetHead / (ulong)nextLevelSize);
}
/// <summary>
/// check out if a bucket is within the same higher-level boundary as currentOffset
/// </summary>
/// <param name="currentOffset">
///
/// </param>
/// <param name="target">
///
/// </param>
/// <param name="level">
///
/// </param>
/// <returns>
///
/// </returns>
private bool AssertForwardBoundary(ulong currentOffset, Entry* target, int level)
{
int nextLevelSize = levelSizeArray[level] * 4;
@@ -75,7 +105,7 @@ namespace StgSharp.HighPerformance.Memory
/// <summary>
/// Used in Free operations, efficiently remove from buckets and merge adjacent blocks.
/// Current Entry will serve as the final merged block. The Merge will be in lazy
/// strategy, any fail in acquiring spin lock will end a merging process.
/// strategy.
/// </summary>
private void MergeAndRemoveFromBuckets(Entry* entry)
{
@@ -99,8 +129,7 @@ namespace StgSharp.HighPerformance.Memory
ulong p = entry->PreviousNear;
Entry* prev = (Entry*)p;
// 计算当前块相对于分配空间基址的偏移量
// compute offset of current block and base position
ulong currentOffset = entry->Position - (ulong)m_Buffer;
if (prev == null ||
@@ -2,8 +2,8 @@
// -----------------------------------------------------------------------
// file="HLSFAllocator"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
// AuthorGroup: Nitload
// Copyright (c) Nitload. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -28,6 +28,7 @@
using System;
using System.Buffers;
using System.Runtime.InteropServices;
using System.Text;
namespace StgSharp.HighPerformance.Memory
{