yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
7b570feed
master
1// unit-test-free-list.cpp 2 3#include "../../source/core/slang-list.h" 4#include "../../source/core/slang-memory-arena.h" 5#include "../../source/core/slang-random-generator.h" 6#include "unit-test/slang-unit-test.h" 7 8#include <stdio.h> 9#include <stdlib.h> 10 11using namespace Slang ; 12 13 14namespace // anonymous 15{ 16 17struct Block 18{ 19void * m_data ; 20size_t m_size ; 21uint8_t m_value ; 22}; 23 24enum class TestMode 25{ 26eUnaligned , 27eImplicitAligned ,///< Alignment is kept implicitly with Unaligned allocs of the right size 28eDefaultAligned , 29eExplicitAligned , 30eCount , 31}; 32 33}// namespace 34 35static size_t getAlignment (TestMode mode ) 36{ 37switch (mode ) 38 { 39default : 40case TestMode ::eUnaligned : 41return 1 ; 42case TestMode ::eExplicitAligned : 43return 16 ; 44case TestMode ::eImplicitAligned : 45return 32 ; 46case TestMode ::eDefaultAligned : 47return MemoryArena ::kMinAlignment ; 48 } 49} 50 51static bool hasValueShort (const uint8_t * data ,size_t size ,uint8_t value ) 52{ 53for (size_t i = 0 ;i < size ;++ i ) 54 { 55if (data [i ]!= value ) 56 { 57return false; 58 } 59 } 60return true; 61} 62 63static bool hasValue (const uint8_t * data ,size_t size ,uint8_t value ) 64{ 65const size_t alignMask = sizeof (size_t )- 1 ; 66 67if (size <=sizeof (size_t )* 2 ) 68 { 69return hasValueShort (data ,size ,value ); 70 } 71 72if (size_t (data )& alignMask ) 73 { 74size_t firstSize = sizeof (size_t )- (size_t (data )& alignMask ); 75if (!hasValueShort (data ,firstSize ,value )) 76 { 77return false; 78 } 79size -= firstSize ; 80data += firstSize ; 81 82assert ((size_t (data )& alignMask )== 0 ); 83 } 84 85// Now do the middle 86size_t numWords = size /sizeof (size_t ); 87 88// Expand the byte up to a word size 89size_t wordValue = (size_t (value ) <<8 ) |value ; 90wordValue = (wordValue <<16 ) |wordValue ; 91wordValue = (sizeof (size_t )> 4 ) ?size_t ((uint64_t (wordValue ) <<32 ) |wordValue ) :wordValue ; 92 93const size_t * wordData = (const size_t * )data ; 94for (size_t i = 0 ;i < numWords ;++ i ) 95 { 96if (wordData [i ]!= wordValue ) 97 { 98return false; 99 } 100 } 101 102// Do the end piece 103return hasValueShort (data + sizeof (size_t )* numWords ,size & alignMask ,value ); 104} 105 106SLANG_UNIT_TEST (memoryArena ) 107{ 108DefaultRandomGenerator randGen (0x5346536a ); 109 110 { 111const size_t blockSize = 1024 ; 112MemoryArena arena ; 113arena .init (blockSize ); 114 115List < void *> blocks ; 116 117blocks .add (arena .allocate (100 )); 118blocks .add (arena .allocate (blockSize * 2 )); 119blocks .add (arena .allocate (100 )); 120blocks .add (arena .allocate (blockSize * 2 )); 121blocks .add (arena .allocate (100 )); 122 123arena .deallocateAll (); 124blocks .add (arena .allocate (100 )); 125blocks .add (arena .allocate (blockSize * 2 )); 126 127arena .reset (); 128 129 { 130uint32_t data []= {1 ,2 ,3 }; 131 132const uint32_t * copy = arena .allocateAndCopyArray (data ,SLANG_COUNT_OF (data )); 133 134SLANG_CHECK (::memcmp (copy ,data ,sizeof (data ))== 0 ); 135 } 136 } 137 138 { 139int count = 0 ; 140const size_t blockSize = 1024 ; 141 142for (TestMode mode = TestMode (0 );int (mode )< int (TestMode ::eCount ); 143mode = TestMode (int (mode )+ 1 )) 144 { 145const size_t alignment = getAlignment (mode ); 146 147MemoryArena arena ; 148arena .init (blockSize ,alignment ); 149 150List < Block > blocks ; 151 152for (int i = 0 ;i < 10000 ;i ++ ) 153 { 154count ++ ; 155 156const int var = randGen .nextInt32 ()& 0x3ff ; 157if (var < 3 && blocks .getCount ()> 0 ) 158 { 159if (var == 1 ) 160 { 161// Deallocate everything 162arena .deallocateAll (); 163blocks .clear (); 164 } 165else if (var == 2 ) 166 { 167arena .reset (); 168blocks .clear (); 169 } 170else if (var == 3 ) 171 { 172arena .rewindToCursor (nullptr ); 173blocks .clear (); 174 } 175else if (var == 4 ) 176 { 177// Rewind to a random position 178int rewindIndex = randGen .nextInt32UpTo (int32_t (blocks .getCount ())); 179// rewind to this block 180arena .rewindToCursor (blocks [rewindIndex ].m_data ); 181// All the blocks (includign this one) and now deallocated 182blocks .setCount (rewindIndex ); 183 } 184else 185 { 186size_t usedMemory = arena .calcTotalMemoryUsed (); 187size_t allocatedMemory = arena .calcTotalMemoryAllocated (); 188 189SLANG_CHECK (allocatedMemory >=usedMemory ); 190 } 191 } 192else 193 { 194size_t sizeInBytes = (randGen .nextInt32 ()& 255 )+ 1 ; 195 196// Lets go for an oversized block 197if ((randGen .nextInt32 ()& 0xff )< 2 ) 198 { 199sizeInBytes += blockSize ; 200 } 201else if ((randGen .nextInt32 ()& 0xff )< 2 ) 202 { 203// Let's try for a block that's awkwardly sized 204sizeInBytes = blockSize /3 + 10 ; 205 } 206 207const uint8_t value = uint8_t (randGen .nextInt32 ()); 208 209void * mem = nullptr ; 210switch (mode ) 211 { 212default : 213case TestMode ::eUnaligned : 214 { 215mem = arena .allocateUnaligned (sizeInBytes ); 216break ; 217 } 218case TestMode ::eImplicitAligned : 219 { 220// Fix the size to get implicit alignment 221sizeInBytes = (sizeInBytes & ~(alignment - 1 ))+ alignment ; 222mem = arena .allocateUnaligned (sizeInBytes ); 223break ; 224 } 225case TestMode ::eExplicitAligned : 226 { 227mem = arena .allocateAligned (sizeInBytes ,alignment ); 228break ; 229 } 230case TestMode ::eDefaultAligned : 231 { 232mem = arena .allocate (sizeInBytes ); 233break ; 234 } 235 } 236 237// Check it is aligned 238SLANG_CHECK ((size_t (mem )& (alignment - 1 ))== 0 ); 239 240 ::memset (mem ,value ,sizeInBytes ); 241 242Block block ; 243 244block .m_data = mem ; 245block .m_size = sizeInBytes ; 246block .m_value = value ; 247 248blocks .add (block ); 249 } 250 251// Check the blocks 252for (Index j = 0 ;j < blocks .getCount ();++ j ) 253 { 254const Block & block = blocks [j ]; 255 256SLANG_CHECK (arena .isValid (block .m_data ,block .m_size )); 257 258SLANG_CHECK (hasValue ((uint8_t * )block .m_data ,block .m_size ,block .m_value )); 259 } 260 } 261 } 262 } 263 { 264// Do lots of allocations and test out rewind 265 } 266}