yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f65d756bf
master
1#ifndef SLANG_VIRTUAL_POOL_ALLOCATOR_H 2#define SLANG_VIRTUAL_POOL_ALLOCATOR_H 3 4namespace Slang 5{ 6 7/// A virtual free-list allocater. 8/// This class doesn't actually allocates memory, instead it operates on a 9/// virtual integer space. Can be used to implement various types of object pools 10/// that needs to support contiguous allocations of more than one elements. 11class VirtualObjectPool 12{ 13public : 14struct FreeListNode 15 { 16int Offset ; 17int Length ; 18FreeListNode * prev ; 19FreeListNode * next ; 20 }; 21FreeListNode * freeListHead = nullptr ; 22 23public : 24void destroy () 25{ 26auto list = freeListHead; 27while (list) 28{ 29auto next = list -> next ; 30delete list; 31list = next; 32} 33freeListHead = nullptr ; 34} 35 36~ VirtualObjectPool () { destroy (); } 37 38void initPool ( int numElements) 39{ 40freeListHead = new FreeListNode (); 41freeListHead -> prev = freeListHead -> next = nullptr ; 42freeListHead -> Offset = 0 ; 43freeListHead -> Length = numElements; 44} 45 46int alloc ( int size) 47{ 48if (!freeListHead) 49return -1 ; 50auto freeBlock = freeListHead; 51while (freeBlock && freeBlock -> Length < size) 52freeBlock = freeBlock -> next ; 53if (!freeBlock || freeBlock -> Length < size) 54return -1 ; 55int result = freeBlock -> Offset ; 56freeBlock -> Offset += size; 57freeBlock -> Length -= size; 58if (freeBlock -> Length == 0 ) 59{ 60if (freeBlock -> prev ) 61freeBlock -> prev -> next = freeBlock -> next ; 62if (freeBlock -> next ) 63freeBlock -> next -> prev = freeBlock -> prev ; 64if (freeBlock == freeListHead) 65freeListHead = freeBlock -> next ; 66delete freeBlock; 67} 68return result; 69} 70void free ( int offset, int size) 71{ 72if (!freeListHead) 73{ 74freeListHead = new FreeListNode (); 75freeListHead -> next = freeListHead -> prev = nullptr ; 76freeListHead -> Length = size; 77freeListHead -> Offset = offset; 78return ; 79} 80auto freeListNode = freeListHead; 81FreeListNode * prevFreeNode = nullptr ; 82while (freeListNode && freeListNode -> Offset < offset + size) 83{ 84prevFreeNode = freeListNode; 85freeListNode = freeListNode -> next ; 86} 87FreeListNode * newNode = new FreeListNode (); 88newNode -> Offset = offset; 89newNode -> Length = size; 90newNode -> prev = prevFreeNode; 91newNode -> next = freeListNode; 92if (freeListNode) 93freeListNode -> prev = newNode; 94if (prevFreeNode) 95prevFreeNode -> next = newNode; 96if (freeListNode == freeListHead) 97freeListHead = newNode; 98if (prevFreeNode && prevFreeNode -> Offset + prevFreeNode -> Length == newNode -> Offset ) 99{ 100prevFreeNode -> Length += newNode -> Length ; 101prevFreeNode -> next = freeListNode; 102if (freeListNode) 103freeListNode -> prev = prevFreeNode; 104delete newNode; 105newNode = prevFreeNode; 106} 107if (freeListNode && newNode -> Offset + newNode -> Length == freeListNode -> Offset ) 108{ 109newNode -> Length += freeListNode -> Length ; 110newNode -> next = freeListNode -> next ; 111if (freeListNode -> next ) 112freeListNode -> next -> prev = newNode; 113delete freeListNode; 114} 115} 116}; 117 118} // namespace Slang 119#endif