diff --git a/doc/readme.md b/doc/readme.md index 17a9133..53fa7bb 100644 --- a/doc/readme.md +++ b/doc/readme.md @@ -1,3 +1,90 @@ # XenoAtom.Allocators User Guide -This is a default project description. +## Overview + +The main entry point of the library is the `TlsfAllocator` class. This class provides a TLSF (Two-Level Segregated Fit) allocator implementation. The TLSF allocator is a low-level memory allocator that provides a good balance between speed, fragmentation, and memory overhead. It is particularly well suited for real-time systems. + + +### Creating a TLSF allocator + +In order to use the TLSF allocator, you need to provide a Chunk allocator. The chunk allocator is responsible for allocating and deallocating memory chunks. The TLSF allocator will then use these chunks to allocate and deallocate memory blocks within these chunks. + +You simply need to implement the interface `IMemoryChunkAllocator` that will provide the basic blocks for allocation / deallocation. + +For example: + +```csharp +/// +/// Implementation of a chunk allocator for the TLSF allocator using native memory. +/// +public unsafe class BasicChunkAllocator : IMemoryChunkAllocator +{ + private readonly Dictionary _chunks = new Dictionary(); + private const int ChunkSize = 65536; + + public MemoryChunk AllocateChunk(MemorySize minSize) + { + var blockSize = (uint)Math.Max(ChunkSize, (int)minSize.Value); + var address = NativeMemory.AlignedAlloc(blockSize, 64); + var chunk = new MemoryChunk((ulong)_chunks.Count, (ulong)address, blockSize); + _chunks.Add(_chunks.Count, chunk); + return chunk; + } + + public void FreeChunk(in MemoryChunk chunk) + { + NativeMemory.AlignedFree((void*)(ulong)chunk.BaseAddress); + _chunks.Remove((int)chunk.Id.Value); + } +} +``` + +Then you can create a TLSF allocator with this chunk allocator: + +```csharp +var chunkAllocator = new BasicChunkAllocator(); +// Create an allocator with a minimum alignment of 64 bytes +var allocator = new TlsfAllocator(chunkAllocator, 64); +``` + +### Allocating memory + +You can allocate memory using the `Allocate` method: + +```csharp +var allocation = allocator.Allocate(128); +``` + +The `Allocate` method returns an `TlsfAllocation` structure that represents the allocated memory. + +A TlsfAllocation has the following properties, with Address and Size representing the address and size of the allocated block: + +```csharp +public readonly record struct TlsfAllocation +{ + /// + /// Gets the index of the block allocated (used internally by the allocator). + /// + public readonly TlsfAllocationToken Token; + + /// + /// Gets the address of the allocated block. + /// + public readonly MemoryAddress Address; + + /// + /// Gets the size of the allocated block. + /// + public readonly MemorySize Size; +} +``` + +### Freeing memory + +You can free memory using the `Free` method by passing a `TlsfAllocationToken` stored in the `TlsfAllocation` structure via the `Token` property: + +```csharp +allocator.Free(allocation.Token); +// Or you can use the implicit cast operator: +// allocator.Free(allocation); +```