82 lines
2.6 KiB
C#
82 lines
2.6 KiB
C#
// -----------------------------------------------------------------------------
|
|
// file="L4"
|
|
// Project: StgSharp
|
|
// Copyright (c) Nitload.
|
|
// SPDX-License-Identifier: MIT
|
|
// -----------------------------------------------------------------------------
|
|
|
|
using Nitload.Common.HighPerformance.ProcessorAbstraction;
|
|
|
|
namespace Nitload.Common.HighPerformance.Memory
|
|
{
|
|
public sealed unsafe partial class L4 : IDisposable
|
|
{
|
|
|
|
private const nuint PageSize = 4096;
|
|
|
|
private bool _disposed;
|
|
private readonly int _bindedNuma;
|
|
private readonly nuint _baseAddress;
|
|
private SwissTable _addressMap;
|
|
private TLSF _bufferAllocator;
|
|
|
|
public L4(
|
|
int bindedNuma,
|
|
uint bufferSize = 8192 * 8192,
|
|
int align = 16,
|
|
uint maxCacheLineSize = 8192
|
|
)
|
|
{
|
|
ArgumentOutOfRangeException.ThrowIfGreaterThan(bufferSize, CacheLineMetadata.MaxBufferSize);
|
|
ArgumentOutOfRangeException.ThrowIfGreaterThan(maxCacheLineSize, CacheLineMetadata.MaxBufferSize);
|
|
_bindedNuma = bindedNuma;
|
|
nuint normalizedBufferSize = (bufferSize + (PageSize - 1)) & (~(PageSize - 1));
|
|
ByteCapacity = normalizedBufferSize;
|
|
nuint swissBufferOffset = normalizedBufferSize + TLSF.RequestedAllocation;
|
|
AllocSize = swissBufferOffset + (nuint)BufferSize;
|
|
_baseAddress = (nuint)Numa.Alloc(bindedNuma, AllocSize);
|
|
_bufferAllocator = new TLSF(bufferSize, maxCacheLineSize, (void*)_baseAddress);
|
|
_addressMap = SwissTable.Create((byte*)(_baseAddress + swissBufferOffset));
|
|
}
|
|
|
|
public nuint ByteCapacity { get; init; }
|
|
|
|
public nuint AllocSize { get; init; }
|
|
|
|
public void Dispose()
|
|
{
|
|
if (_disposed) {
|
|
return;
|
|
}
|
|
_disposed = true;
|
|
_addressMap.Dispose();
|
|
Numa.Free((void*)_baseAddress, _bindedNuma, AllocSize);
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
internal void Collect()
|
|
{
|
|
ObjectDisposedException.ThrowIf(_disposed, this);
|
|
_bufferAllocator.Collect();
|
|
}
|
|
|
|
internal void Free(
|
|
int handle
|
|
)
|
|
{
|
|
ObjectDisposedException.ThrowIf(_disposed, this);
|
|
_bufferAllocator.Free(handle);
|
|
}
|
|
|
|
internal bool TryAllocate(
|
|
uint size,
|
|
out int handle
|
|
)
|
|
{
|
|
ObjectDisposedException.ThrowIf(_disposed, this);
|
|
return _bufferAllocator.TryAlloc(size, out handle);
|
|
}
|
|
|
|
}
|
|
}
|