static void tlsTestThr (void* arg) { DE_UNREF(arg); DE_TEST_ASSERT(tls_testVar == 123); tls_testVar = 104; DE_TEST_ASSERT(tls_testVar == 104); }
static void runSingletonThreadedTest (int numThreads, int initTimeMs) { deMemPool* tmpPool = deMemPool_createRoot(DE_NULL, 0); deThreadArray* threads = tmpPool ? deThreadArray_create(tmpPool) : DE_NULL; int threadNdx; resetTestState(); for (threadNdx = 0; threadNdx < numThreads; threadNdx++) { deThread thread = deThread_create(singletonTestThread, &initTimeMs, DE_NULL); DE_TEST_ASSERT(thread); DE_TEST_ASSERT(deThreadArray_pushBack(threads, thread)); } /* All threads created - let them do initialization. */ deMemoryReadWriteFence(); s_singletonInitLock = DE_TRUE; deMemoryReadWriteFence(); for (threadNdx = 0; threadNdx < numThreads; threadNdx++) { deThread thread = deThreadArray_get(threads, threadNdx); DE_TEST_ASSERT(deThread_join(thread)); deThread_destroy(thread); } /* Verify results. */ DE_TEST_ASSERT(s_testSingletonInitialized); DE_TEST_ASSERT(s_testSingletonInitCount == 1); deMemPool_destroy(tmpPool); }
static void testParse (const char* cmdLine, const char* const* refArgs, int numArgs) { deCommandLine* parsedCmdLine = deCommandLine_parse(cmdLine); int argNdx; DE_TEST_ASSERT(parsedCmdLine); DE_TEST_ASSERT(parsedCmdLine->numArgs == numArgs); for (argNdx = 0; argNdx < numArgs; argNdx++) DE_TEST_ASSERT(deStringEqual(parsedCmdLine->args[argNdx], refArgs[argNdx])); deCommandLine_destroy(parsedCmdLine); }
static void singletonTestThread (void* arg) { waitForSingletonInitLock(); deInitSingleton(&s_testSingleton, initTestSingleton, arg); DE_TEST_ASSERT(s_testSingletonInitialized); }
static void mutexTestThr2 (void* arg) { MutexData2* data = (MutexData2*)arg; deInt32 numIncremented = 0; for (;;) { deInt32 localCounter; deMutex_lock(data->mutex); if (data->counter >= data->maxVal) { deMutex_unlock(data->mutex); break; } localCounter = data->counter; deYield(); DE_TEST_ASSERT(localCounter == data->counter); localCounter += 1; data->counter = localCounter; deMutex_unlock(data->mutex); numIncremented++; } deMutex_lock(data->mutex); data->counter2 += numIncremented; deMutex_unlock(data->mutex); }
void mutexTestThr3 (void* arg) { deMutex mutex = *((deMutex*)arg); deBool ret; ret = deMutex_tryLock(mutex); DE_TEST_ASSERT(!ret); }
void deSemaphore_selfTest (void) { /* Basic test. */ { deSemaphore semaphore = deSemaphore_create(1, DE_NULL); DE_TEST_ASSERT(semaphore); deSemaphore_increment(semaphore); deSemaphore_decrement(semaphore); deSemaphore_decrement(semaphore); deSemaphore_destroy(semaphore); } /* Producer-consumer test. */ { TestBuffer testBuffer; deThread producer; deThread consumer; deBool ret; deMemset(&testBuffer, 0, sizeof(testBuffer)); testBuffer.empty = deSemaphore_create(DE_LENGTH_OF_ARRAY(testBuffer.buffer), DE_NULL); testBuffer.fill = deSemaphore_create(0, DE_NULL); DE_TEST_ASSERT(testBuffer.empty && testBuffer.fill); consumer = deThread_create(consumerThread, &testBuffer, DE_NULL); producer = deThread_create(producerThread, &testBuffer, DE_NULL); DE_TEST_ASSERT(consumer && producer); ret = deThread_join(consumer) && deThread_join(producer); DE_TEST_ASSERT(ret); deThread_destroy(producer); deThread_destroy(consumer); deSemaphore_destroy(testBuffer.empty); deSemaphore_destroy(testBuffer.fill); DE_TEST_ASSERT(testBuffer.producerSum == testBuffer.consumerSum); } }
static void threadTestThr3 (void* arg) { ThreadData3* data = (ThreadData3*)arg; int ndx; for (ndx = 0; ndx < (int)DE_LENGTH_OF_ARRAY(data->bytes); ndx++) DE_TEST_ASSERT(data->bytes[ndx] == 0); for (ndx = 0; ndx < (int)DE_LENGTH_OF_ARRAY(data->bytes); ndx++) data->bytes[ndx] = 0xff; }
void dePoolHash_selfTest (void) { deMemPool* pool = deMemPool_createRoot(DE_NULL, 0); deTestHash* hash = deTestHash_create(pool); int iter; for (iter = 0; iter < 3; iter++) { int i; /* Test find() on empty hash. */ DE_TEST_ASSERT(deTestHash_getNumElements(hash) == 0); for (i = 0; i < 15000; i++) { const int* val = deTestHash_find(hash, (deInt16)i); DE_TEST_ASSERT(!val); } /* Test insert(). */ for (i = 0; i < 5000; i++) { deTestHash_insert(hash, (deInt16)i, -i); } DE_TEST_ASSERT(deTestHash_getNumElements(hash) == 5000); for (i = 0; i < 5000; i++) { const int* val = deTestHash_find(hash, (deInt16)i); DE_TEST_ASSERT(val && (*val == -i)); } /* Test delete(). */ for (i = 0; i < 1000; i++) deTestHash_delete(hash, (deInt16)i); DE_TEST_ASSERT(deTestHash_getNumElements(hash) == 4000); for (i = 0; i < 25000; i++) { const int* val = deTestHash_find(hash, (deInt16)i); if (deInBounds32(i, 1000, 5000)) DE_TEST_ASSERT(val && (*val == -i)); else DE_TEST_ASSERT(!val); } /* Test insert() after delete(). */ for (i = 10000; i < 12000; i++) deTestHash_insert(hash, (deInt16)i, -i); for (i = 0; i < 25000; i++) { const int* val = deTestHash_find(hash, (deInt16)i); if (deInBounds32(i, 1000, 5000) || deInBounds32(i, 10000, 12000)) DE_TEST_ASSERT(val && (*val == -i)); else DE_TEST_ASSERT(!val); } /* Test iterator. */ { deTestHashIter testIter; int numFound = 0; for (deTestHashIter_init(hash, &testIter); deTestHashIter_hasItem(&testIter); deTestHashIter_next(&testIter)) { deInt16 key = deTestHashIter_getKey(&testIter); int val = deTestHashIter_getValue(&testIter); DE_TEST_ASSERT(deInBounds32(key, 1000, 5000) || deInBounds32(key, 10000, 12000)); DE_TEST_ASSERT(*deTestHash_find(hash, key) == -key); DE_TEST_ASSERT(val == -key); numFound++; } DE_TEST_ASSERT(numFound == deTestHash_getNumElements(hash)); } /* Test copy-to-array. */ { deTestInt16Array* keyArray = deTestInt16Array_create(pool); deTestIntArray* valueArray = deTestIntArray_create(pool); int numElements = deTestHash_getNumElements(hash); int ndx; deTestHash_copyToArray(hash, keyArray, DE_NULL); DE_TEST_ASSERT(deTestInt16Array_getNumElements(keyArray) == numElements); deTestHash_copyToArray(hash, DE_NULL, valueArray); DE_TEST_ASSERT(deTestIntArray_getNumElements(valueArray) == numElements); deTestInt16Array_setSize(keyArray, 0); deTestIntArray_setSize(valueArray, 0); deTestHash_copyToArray(hash, keyArray, valueArray); DE_TEST_ASSERT(deTestInt16Array_getNumElements(keyArray) == numElements); DE_TEST_ASSERT(deTestIntArray_getNumElements(valueArray) == numElements); for (ndx = 0; ndx < numElements; ndx++) { deInt16 key = deTestInt16Array_get(keyArray, ndx); int val = deTestIntArray_get(valueArray, ndx); DE_TEST_ASSERT(val == -key); DE_TEST_ASSERT(*deTestHash_find(hash, key) == val); } } /* Test reset(). */ deTestHash_reset(hash); DE_TEST_ASSERT(deTestHash_getNumElements(hash) == 0); } deMemPool_destroy(pool); }
void deThread_selfTest (void) { /* Test sleep & yield. */ deSleep(0); deSleep(100); deYield(); /* Thread test 1. */ { deInt32 val = 123; deBool ret; deThread thread = deThread_create(threadTestThr1, &val, DE_NULL); DE_TEST_ASSERT(thread); ret = deThread_join(thread); DE_TEST_ASSERT(ret); deThread_destroy(thread); } /* Thread test 2. */ { deThread thread = deThread_create(threadTestThr2, DE_NULL, DE_NULL); deInt32 ret; DE_TEST_ASSERT(thread); ret = deThread_join(thread); DE_TEST_ASSERT(ret); deThread_destroy(thread); } /* Thread test 3. */ { ThreadData3 data; deThread thread; deBool ret; int ndx; deMemset(&data, 0, sizeof(ThreadData3)); thread = deThread_create(threadTestThr3, &data, DE_NULL); DE_TEST_ASSERT(thread); ret = deThread_join(thread); DE_TEST_ASSERT(ret); for (ndx = 0; ndx < (int)DE_LENGTH_OF_ARRAY(data.bytes); ndx++) DE_TEST_ASSERT(data.bytes[ndx] == 0xff); deThread_destroy(thread); } /* Test tls. */ { deThreadLocal tls; deThread thread; tls = deThreadLocal_create(); DE_TEST_ASSERT(tls); deThreadLocal_set(tls, (void*)(deUintptr)0xff); thread = deThread_create(threadTestThr4, &tls, DE_NULL); deThread_join(thread); deThread_destroy(thread); DE_TEST_ASSERT((deUintptr)deThreadLocal_get(tls) == 0xff); deThreadLocal_destroy(tls); } #if defined(DE_THREAD_LOCAL) { deThread thread; DE_TEST_ASSERT(tls_testVar == 123); tls_testVar = 1; DE_TEST_ASSERT(tls_testVar == 1); thread = deThread_create(tlsTestThr, DE_NULL, DE_NULL); deThread_join(thread); deThread_destroy(thread); DE_TEST_ASSERT(tls_testVar == 1); tls_testVar = 123; } #endif }
void deAtomic_selfTest (void) { /* Single-threaded tests. */ { volatile int a = 11; DE_TEST_ASSERT(deAtomicIncrement32(&a) == 12); DE_TEST_ASSERT(a == 12); DE_TEST_ASSERT(deAtomicIncrement32(&a) == 13); DE_TEST_ASSERT(a == 13); DE_TEST_ASSERT(deAtomicDecrement32(&a) == 12); DE_TEST_ASSERT(a == 12); DE_TEST_ASSERT(deAtomicDecrement32(&a) == 11); DE_TEST_ASSERT(a == 11); } { volatile deUint32 p; p = 0; DE_TEST_ASSERT(deAtomicCompareExchange32(&p, 0, 1) == 0); DE_TEST_ASSERT(p == 1); DE_TEST_ASSERT(deAtomicCompareExchange32(&p, 0, 2) == 1); DE_TEST_ASSERT(p == 1); p = 7; DE_TEST_ASSERT(deAtomicCompareExchange32(&p, 6, 8) == 7); DE_TEST_ASSERT(p == 7); DE_TEST_ASSERT(deAtomicCompareExchange32(&p, 7, 8) == 7); DE_TEST_ASSERT(p == 8); } /* \todo [2012-10-26 pyry] Implement multi-threaded tests. */ }
static void threadTestThr1 (void* arg) { deInt32 val = *((deInt32*)arg); DE_TEST_ASSERT(val == 123); }
void deMutex_selfTest (void) { /* Default mutex from single thread. */ { deMutex mutex = deMutex_create(DE_NULL); deBool ret; DE_TEST_ASSERT(mutex); deMutex_lock(mutex); deMutex_unlock(mutex); /* Should succeed. */ ret = deMutex_tryLock(mutex); DE_TEST_ASSERT(ret); deMutex_unlock(mutex); deMutex_destroy(mutex); } /* Recursive mutex. */ { deMutexAttributes attrs; deMutex mutex; int ndx; int numLocks = 10; deMemset(&attrs, 0, sizeof(attrs)); attrs.flags = DE_MUTEX_RECURSIVE; mutex = deMutex_create(&attrs); DE_TEST_ASSERT(mutex); for (ndx = 0; ndx < numLocks; ndx++) deMutex_lock(mutex); for (ndx = 0; ndx < numLocks; ndx++) deMutex_unlock(mutex); deMutex_destroy(mutex); } /* Mutex and threads. */ { deMutex mutex; deThread thread; mutex = deMutex_create(DE_NULL); DE_TEST_ASSERT(mutex); deMutex_lock(mutex); thread = deThread_create(mutexTestThr1, &mutex, DE_NULL); DE_TEST_ASSERT(thread); deSleep(100); deMutex_unlock(mutex); deMutex_lock(mutex); deMutex_unlock(mutex); deThread_join(thread); deThread_destroy(thread); deMutex_destroy(mutex); } /* A bit more complex mutex test. */ { MutexData2 data; deThread threads[2]; int ndx; data.mutex = deMutex_create(DE_NULL); DE_TEST_ASSERT(data.mutex); data.counter = 0; data.counter2 = 0; data.maxVal = 1000; deMutex_lock(data.mutex); for (ndx = 0; ndx < (int)DE_LENGTH_OF_ARRAY(threads); ndx++) { threads[ndx] = deThread_create(mutexTestThr2, &data, DE_NULL); DE_TEST_ASSERT(threads[ndx]); } deMutex_unlock(data.mutex); for (ndx = 0; ndx < (int)DE_LENGTH_OF_ARRAY(threads); ndx++) { deBool ret = deThread_join(threads[ndx]); DE_TEST_ASSERT(ret); deThread_destroy(threads[ndx]); } DE_TEST_ASSERT(data.counter == data.counter2); DE_TEST_ASSERT(data.maxVal == data.counter); deMutex_destroy(data.mutex); } /* tryLock() deadlock test. */ { deThread thread; deMutex mutex = deMutex_create(DE_NULL); deBool ret; DE_TEST_ASSERT(mutex); deMutex_lock(mutex); thread = deThread_create(mutexTestThr3, &mutex, DE_NULL); DE_TEST_ASSERT(mutex); ret = deThread_join(thread); DE_TEST_ASSERT(ret); deMutex_unlock(mutex); deMutex_destroy(mutex); deThread_destroy(thread); } }
void deAtomic_selfTest (void) { /* Single-threaded tests. */ { volatile deInt32 a = 11; DE_TEST_ASSERT(deAtomicIncrementInt32(&a) == 12); DE_TEST_ASSERT(a == 12); DE_TEST_ASSERT(deAtomicIncrementInt32(&a) == 13); DE_TEST_ASSERT(a == 13); a = -2; DE_TEST_ASSERT(deAtomicIncrementInt32(&a) == -1); DE_TEST_ASSERT(a == -1); DE_TEST_ASSERT(deAtomicIncrementInt32(&a) == 0); DE_TEST_ASSERT(a == 0); a = 11; DE_TEST_ASSERT(deAtomicDecrementInt32(&a) == 10); DE_TEST_ASSERT(a == 10); DE_TEST_ASSERT(deAtomicDecrementInt32(&a) == 9); DE_TEST_ASSERT(a == 9); a = 0; DE_TEST_ASSERT(deAtomicDecrementInt32(&a) == -1); DE_TEST_ASSERT(a == -1); DE_TEST_ASSERT(deAtomicDecrementInt32(&a) == -2); DE_TEST_ASSERT(a == -2); a = 0x7fffffff; DE_TEST_ASSERT(deAtomicIncrementInt32(&a) == (int)0x80000000); DE_TEST_ASSERT(a == (int)0x80000000); DE_TEST_ASSERT(deAtomicDecrementInt32(&a) == (int)0x7fffffff); DE_TEST_ASSERT(a == 0x7fffffff); } { volatile deUint32 a = 11; DE_TEST_ASSERT(deAtomicIncrementUint32(&a) == 12); DE_TEST_ASSERT(a == 12); DE_TEST_ASSERT(deAtomicIncrementUint32(&a) == 13); DE_TEST_ASSERT(a == 13); a = 0x7fffffff; DE_TEST_ASSERT(deAtomicIncrementUint32(&a) == 0x80000000); DE_TEST_ASSERT(a == 0x80000000); DE_TEST_ASSERT(deAtomicDecrementUint32(&a) == 0x7fffffff); DE_TEST_ASSERT(a == 0x7fffffff); a = 0xfffffffe; DE_TEST_ASSERT(deAtomicIncrementUint32(&a) == 0xffffffff); DE_TEST_ASSERT(a == 0xffffffff); DE_TEST_ASSERT(deAtomicDecrementUint32(&a) == 0xfffffffe); DE_TEST_ASSERT(a == 0xfffffffe); } { volatile deUint32 p; p = 0; DE_TEST_ASSERT(deAtomicCompareExchange32(&p, 0, 1) == 0); DE_TEST_ASSERT(p == 1); DE_TEST_ASSERT(deAtomicCompareExchange32(&p, 0, 2) == 1); DE_TEST_ASSERT(p == 1); p = 7; DE_TEST_ASSERT(deAtomicCompareExchange32(&p, 6, 8) == 7); DE_TEST_ASSERT(p == 7); DE_TEST_ASSERT(deAtomicCompareExchange32(&p, 7, 8) == 7); DE_TEST_ASSERT(p == 8); } #if (DE_PTR_SIZE == 8) { volatile deInt64 a = 11; DE_TEST_ASSERT(deAtomicIncrementInt64(&a) == 12); DE_TEST_ASSERT(a == 12); DE_TEST_ASSERT(deAtomicIncrementInt64(&a) == 13); DE_TEST_ASSERT(a == 13); a = -2; DE_TEST_ASSERT(deAtomicIncrementInt64(&a) == -1); DE_TEST_ASSERT(a == -1); DE_TEST_ASSERT(deAtomicIncrementInt64(&a) == 0); DE_TEST_ASSERT(a == 0); a = 11; DE_TEST_ASSERT(deAtomicDecrementInt64(&a) == 10); DE_TEST_ASSERT(a == 10); DE_TEST_ASSERT(deAtomicDecrementInt64(&a) == 9); DE_TEST_ASSERT(a == 9); a = 0; DE_TEST_ASSERT(deAtomicDecrementInt64(&a) == -1); DE_TEST_ASSERT(a == -1); DE_TEST_ASSERT(deAtomicDecrementInt64(&a) == -2); DE_TEST_ASSERT(a == -2); a = (deInt64)((1ull << 63) - 1ull); DE_TEST_ASSERT(deAtomicIncrementInt64(&a) == (deInt64)(1ull << 63)); DE_TEST_ASSERT(a == (deInt64)(1ull << 63)); DE_TEST_ASSERT(deAtomicDecrementInt64(&a) == (deInt64)((1ull << 63) - 1)); DE_TEST_ASSERT(a == (deInt64)((1ull << 63) - 1)); } #endif /* (DE_PTR_SIZE == 8) */ /* \todo [2012-10-26 pyry] Implement multi-threaded tests. */ }
void ArrayBuffer_selfTest (void) { // default constructor { de::ArrayBuffer<int> buf; DE_TEST_ASSERT(buf.size() == 0); DE_TEST_ASSERT(buf.getPtr() == DE_NULL); } // sized constructor { de::ArrayBuffer<int> buf(4); DE_TEST_ASSERT(buf.size() == 4); DE_TEST_ASSERT(buf.getPtr() != DE_NULL); } // copy constructor { de::ArrayBuffer<int> originalBuf(4); *originalBuf.getElementPtr(0) = 1; *originalBuf.getElementPtr(1) = 2; *originalBuf.getElementPtr(2) = 3; *originalBuf.getElementPtr(3) = 4; de::ArrayBuffer<int> targetBuf(originalBuf); DE_TEST_ASSERT(*originalBuf.getElementPtr(0) == 1); DE_TEST_ASSERT(*originalBuf.getElementPtr(1) == 2); DE_TEST_ASSERT(*originalBuf.getElementPtr(2) == 3); DE_TEST_ASSERT(*originalBuf.getElementPtr(3) == 4); DE_TEST_ASSERT(*targetBuf.getElementPtr(0) == 1); DE_TEST_ASSERT(*targetBuf.getElementPtr(1) == 2); DE_TEST_ASSERT(*targetBuf.getElementPtr(2) == 3); DE_TEST_ASSERT(*targetBuf.getElementPtr(3) == 4); } // assignment { de::ArrayBuffer<int> originalBuf(4); *originalBuf.getElementPtr(0) = 1; *originalBuf.getElementPtr(1) = 2; *originalBuf.getElementPtr(2) = 3; *originalBuf.getElementPtr(3) = 4; de::ArrayBuffer<int> targetBuf(1); targetBuf = originalBuf; DE_TEST_ASSERT(*originalBuf.getElementPtr(0) == 1); DE_TEST_ASSERT(*originalBuf.getElementPtr(1) == 2); DE_TEST_ASSERT(*originalBuf.getElementPtr(2) == 3); DE_TEST_ASSERT(*originalBuf.getElementPtr(3) == 4); DE_TEST_ASSERT(*targetBuf.getElementPtr(0) == 1); DE_TEST_ASSERT(*targetBuf.getElementPtr(1) == 2); DE_TEST_ASSERT(*targetBuf.getElementPtr(2) == 3); DE_TEST_ASSERT(*targetBuf.getElementPtr(3) == 4); } // clear { de::ArrayBuffer<int> buf(4); buf.clear(); DE_TEST_ASSERT(buf.size() == 0); DE_TEST_ASSERT(buf.getPtr() == DE_NULL); } // setStorage { de::ArrayBuffer<int> buf(4); buf.setStorage(12); DE_TEST_ASSERT(buf.size() == 12); DE_TEST_ASSERT(buf.getPtr() != DE_NULL); } // setStorage, too large { de::ArrayBuffer<int> buf(4); *buf.getElementPtr(0) = 1; *buf.getElementPtr(1) = 2; *buf.getElementPtr(2) = 3; *buf.getElementPtr(3) = 4; try { buf.setStorage((size_t)-1); // setStorage succeeded, all ok } catch (std::bad_alloc&) { // alloc failed, check storage not changed DE_TEST_ASSERT(buf.size() == 4); DE_TEST_ASSERT(*buf.getElementPtr(0) == 1); DE_TEST_ASSERT(*buf.getElementPtr(1) == 2); DE_TEST_ASSERT(*buf.getElementPtr(2) == 3); DE_TEST_ASSERT(*buf.getElementPtr(3) == 4); } } // swap { de::ArrayBuffer<int> buf; de::ArrayBuffer<int> source(4); *source.getElementPtr(0) = 1; *source.getElementPtr(1) = 2; *source.getElementPtr(2) = 3; *source.getElementPtr(3) = 4; buf.swap(source); DE_TEST_ASSERT(source.size() == 0); DE_TEST_ASSERT(buf.size() == 4); DE_TEST_ASSERT(*buf.getElementPtr(0) == 1); DE_TEST_ASSERT(*buf.getElementPtr(1) == 2); DE_TEST_ASSERT(*buf.getElementPtr(2) == 3); DE_TEST_ASSERT(*buf.getElementPtr(3) == 4); } // default { de::ArrayBuffer<int> source(4); int dst; *source.getElementPtr(1) = 2; deMemcpy(&dst, (int*)source.getPtr() + 1, sizeof(int)); DE_TEST_ASSERT(dst == 2); } // Aligned { de::ArrayBuffer<int, 64, sizeof(int)> source(4); int dst; *source.getElementPtr(1) = 2; deMemcpy(&dst, (int*)source.getPtr() + 1, sizeof(int)); DE_TEST_ASSERT(dst == 2); } // Strided { de::ArrayBuffer<int, 4, 64> source(4); int dst; *source.getElementPtr(1) = 2; deMemcpy(&dst, (deUint8*)source.getPtr() + 64, sizeof(int)); DE_TEST_ASSERT(dst == 2); } // Aligned, Strided { de::ArrayBuffer<int, 32, 64> source(4); int dst; *source.getElementPtr(1) = 2; deMemcpy(&dst, (deUint8*)source.getPtr() + 64, sizeof(int)); DE_TEST_ASSERT(dst == 2); } }
void deInt32_selfTest (void) { const int NUM_ACCURATE_BITS = 29; deRandom rnd; deUint32 rcp; int exp; int numBits; deRandom_init(&rnd, 0xdeadbeefu-1); /* Test deClz32(). */ DE_TEST_ASSERT(deClz32(0) == 32); DE_TEST_ASSERT(deClz32(1) == 31); DE_TEST_ASSERT(deClz32(0xF1) == 24); DE_TEST_ASSERT(deClz32(0xBC12) == 16); DE_TEST_ASSERT(deClz32(0xABBACD) == 8); DE_TEST_ASSERT(deClz32(0x10000000) == 3); DE_TEST_ASSERT(deClz32(0x20000000) == 2); DE_TEST_ASSERT(deClz32(0x40000000) == 1); DE_TEST_ASSERT(deClz32(0x80000000) == 0); /* Test simple inputs for dePop32(). */ DE_TEST_ASSERT(dePop32(0) == 0); DE_TEST_ASSERT(dePop32(~0) == 32); DE_TEST_ASSERT(dePop32(0xFF) == 8); DE_TEST_ASSERT(dePop32(0xFF00FF) == 16); DE_TEST_ASSERT(dePop32(0x3333333) == 14); DE_TEST_ASSERT(dePop32(0x33333333) == 16); /* dePop32(): Check exp2(N) values and inverses. */ for (numBits = 0; numBits < 32; numBits++) { DE_TEST_ASSERT(dePop32(1<<numBits) == 1); DE_TEST_ASSERT(dePop32(~(1<<numBits)) == 31); } /* Check exp2(N) values. */ for (numBits = 0; numBits < 32; numBits++) { deUint32 val = (1u<<numBits); deRcp32(val, &rcp, &exp); DE_TEST_ASSERT(rcp == (1u<<DE_RCP_FRAC_BITS)); DE_TEST_ASSERT(exp == numBits); } /* Check random values. */ for (numBits = 0; numBits < 32; numBits++) { int NUM_ITERS = deMax32(16, 1 << (numBits/2)); int iter; for (iter = 0; iter < NUM_ITERS; iter++) { const int EPS = 1 << (DE_RCP_FRAC_BITS - NUM_ACCURATE_BITS); deUint32 val = (deRandom_getUint32(&rnd) & ((1u<<numBits)-1)) | (1u<<numBits); deUint32 ref = (deUint32)(((1.0f / (double)val) * (double)(1<<DE_RCP_FRAC_BITS)) * (double)(1u<<numBits)); deRcp32(val, &rcp, &exp); DE_TEST_ASSERT(rcp >= ref-EPS && rcp < ref+EPS); DE_TEST_ASSERT(exp == numBits); } } DE_TEST_ASSERT(deBitMask32(0, 0) == 0); DE_TEST_ASSERT(deBitMask32(8, 0) == 0); DE_TEST_ASSERT(deBitMask32(16, 0) == 0); DE_TEST_ASSERT(deBitMask32(31, 0) == 0); DE_TEST_ASSERT(deBitMask32(32, 0) == 0); DE_TEST_ASSERT(deBitMask32(0, 2) == 3); DE_TEST_ASSERT(deBitMask32(0, 32) == 0xFFFFFFFFu); DE_TEST_ASSERT(deBitMask32(16, 16) == 0xFFFF0000u); DE_TEST_ASSERT(deBitMask32(31, 1) == 0x80000000u); DE_TEST_ASSERT(deBitMask32(8, 4) == 0xF00u); DE_TEST_ASSERT(deUintMaxValue32(1) == 1); DE_TEST_ASSERT(deUintMaxValue32(2) == 3); DE_TEST_ASSERT(deUintMaxValue32(32) == 0xFFFFFFFFu); DE_TEST_ASSERT(deIntMaxValue32(1) == 0); DE_TEST_ASSERT(deIntMaxValue32(2) == 1); DE_TEST_ASSERT(deIntMaxValue32(32) == 0x7FFFFFFF); DE_TEST_ASSERT(deIntMinValue32(1) == -1); DE_TEST_ASSERT(deIntMinValue32(2) == -2); DE_TEST_ASSERT(deIntMinValue32(32) == -0x7FFFFFFF - 1); }