hlsf error is solving
This commit is contained in:
@@ -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
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user