1 /*-------------------------------------------------------------------------
2 * drawElements Thread Library
3 * ---------------------------
5 * Copyright 2014 The Android Open Source Project
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
21 * \brief Thread library tests.
22 *//*--------------------------------------------------------------------*/
24 #include "deThreadTest.h"
27 #include "deSemaphore.h"
31 #include "deThreadLocal.h"
32 #include "deSingleton.h"
33 #include "deMemPool.h"
34 #include "dePoolArray.h"
36 static void threadTestThr1 (void* arg)
38 deInt32 val = *((deInt32*)arg);
39 DE_TEST_ASSERT(val == 123);
42 static void threadTestThr2 (void* arg)
48 typedef struct ThreadData3_s
53 static void threadTestThr3 (void* arg)
55 ThreadData3* data = (ThreadData3*)arg;
58 for (ndx = 0; ndx < (int)DE_LENGTH_OF_ARRAY(data->bytes); ndx++)
59 DE_TEST_ASSERT(data->bytes[ndx] == 0);
61 for (ndx = 0; ndx < (int)DE_LENGTH_OF_ARRAY(data->bytes); ndx++)
62 data->bytes[ndx] = 0xff;
65 static void threadTestThr4 (void* arg)
67 deThreadLocal tls = *(deThreadLocal*)arg;
68 deThreadLocal_set(tls, DE_NULL);
71 #if defined(DE_THREAD_LOCAL)
73 static DE_THREAD_LOCAL int tls_testVar = 123;
75 static void tlsTestThr (void* arg)
78 DE_TEST_ASSERT(tls_testVar == 123);
80 DE_TEST_ASSERT(tls_testVar == 104);
85 void deThread_selfTest (void)
87 /* Test sleep & yield. */
96 deThread thread = deThread_create(threadTestThr1, &val, DE_NULL);
97 DE_TEST_ASSERT(thread);
99 ret = deThread_join(thread);
102 deThread_destroy(thread);
107 deThread thread = deThread_create(threadTestThr2, DE_NULL, DE_NULL);
109 DE_TEST_ASSERT(thread);
111 ret = deThread_join(thread);
114 deThread_destroy(thread);
124 deMemset(&data, 0, sizeof(ThreadData3));
126 thread = deThread_create(threadTestThr3, &data, DE_NULL);
127 DE_TEST_ASSERT(thread);
129 ret = deThread_join(thread);
132 for (ndx = 0; ndx < (int)DE_LENGTH_OF_ARRAY(data.bytes); ndx++)
133 DE_TEST_ASSERT(data.bytes[ndx] == 0xff);
135 deThread_destroy(thread);
143 tls = deThreadLocal_create();
146 deThreadLocal_set(tls, (void*)(deUintptr)0xff);
148 thread = deThread_create(threadTestThr4, &tls, DE_NULL);
149 deThread_join(thread);
150 deThread_destroy(thread);
152 DE_TEST_ASSERT((deUintptr)deThreadLocal_get(tls) == 0xff);
153 deThreadLocal_destroy(tls);
156 #if defined(DE_THREAD_LOCAL)
160 DE_TEST_ASSERT(tls_testVar == 123);
162 DE_TEST_ASSERT(tls_testVar == 1);
164 thread = deThread_create(tlsTestThr, DE_NULL, DE_NULL);
165 deThread_join(thread);
166 deThread_destroy(thread);
168 DE_TEST_ASSERT(tls_testVar == 1);
174 static void mutexTestThr1 (void* arg)
176 deMutex mutex = *((deMutex*)arg);
179 deMutex_unlock(mutex);
182 typedef struct MutexData2_s
190 static void mutexTestThr2 (void* arg)
192 MutexData2* data = (MutexData2*)arg;
193 deInt32 numIncremented = 0;
197 deInt32 localCounter;
198 deMutex_lock(data->mutex);
200 if (data->counter >= data->maxVal)
202 deMutex_unlock(data->mutex);
206 localCounter = data->counter;
209 DE_TEST_ASSERT(localCounter == data->counter);
211 data->counter = localCounter;
213 deMutex_unlock(data->mutex);
218 deMutex_lock(data->mutex);
219 data->counter2 += numIncremented;
220 deMutex_unlock(data->mutex);
223 void mutexTestThr3 (void* arg)
225 deMutex mutex = *((deMutex*)arg);
228 ret = deMutex_tryLock(mutex);
229 DE_TEST_ASSERT(!ret);
232 void deMutex_selfTest (void)
234 /* Default mutex from single thread. */
236 deMutex mutex = deMutex_create(DE_NULL);
238 DE_TEST_ASSERT(mutex);
241 deMutex_unlock(mutex);
243 /* Should succeed. */
244 ret = deMutex_tryLock(mutex);
246 deMutex_unlock(mutex);
248 deMutex_destroy(mutex);
251 /* Recursive mutex. */
253 deMutexAttributes attrs;
258 deMemset(&attrs, 0, sizeof(attrs));
260 attrs.flags = DE_MUTEX_RECURSIVE;
262 mutex = deMutex_create(&attrs);
263 DE_TEST_ASSERT(mutex);
265 for (ndx = 0; ndx < numLocks; ndx++)
268 for (ndx = 0; ndx < numLocks; ndx++)
269 deMutex_unlock(mutex);
271 deMutex_destroy(mutex);
274 /* Mutex and threads. */
279 mutex = deMutex_create(DE_NULL);
280 DE_TEST_ASSERT(mutex);
284 thread = deThread_create(mutexTestThr1, &mutex, DE_NULL);
285 DE_TEST_ASSERT(thread);
288 deMutex_unlock(mutex);
291 deMutex_unlock(mutex);
293 deThread_join(thread);
295 deThread_destroy(thread);
296 deMutex_destroy(mutex);
299 /* A bit more complex mutex test. */
305 data.mutex = deMutex_create(DE_NULL);
306 DE_TEST_ASSERT(data.mutex);
312 deMutex_lock(data.mutex);
314 for (ndx = 0; ndx < (int)DE_LENGTH_OF_ARRAY(threads); ndx++)
316 threads[ndx] = deThread_create(mutexTestThr2, &data, DE_NULL);
317 DE_TEST_ASSERT(threads[ndx]);
320 deMutex_unlock(data.mutex);
322 for (ndx = 0; ndx < (int)DE_LENGTH_OF_ARRAY(threads); ndx++)
324 deBool ret = deThread_join(threads[ndx]);
326 deThread_destroy(threads[ndx]);
329 DE_TEST_ASSERT(data.counter == data.counter2);
330 DE_TEST_ASSERT(data.maxVal == data.counter);
332 deMutex_destroy(data.mutex);
335 /* tryLock() deadlock test. */
338 deMutex mutex = deMutex_create(DE_NULL);
340 DE_TEST_ASSERT(mutex);
344 thread = deThread_create(mutexTestThr3, &mutex, DE_NULL);
345 DE_TEST_ASSERT(mutex);
347 ret = deThread_join(thread);
350 deMutex_unlock(mutex);
351 deMutex_destroy(mutex);
352 deThread_destroy(thread);
356 typedef struct TestBuffer_s
362 deUint32 producerHash;
363 deUint32 consumerHash;
366 void producerThread (void* arg)
368 TestBuffer* buffer = (TestBuffer*)arg;
371 int numToProduce = 10000;
374 deRandom_init(&random, 123);
376 for (ndx = 0; ndx <= numToProduce; ndx++)
380 if (ndx == numToProduce)
386 val = deRandom_getUint32(&random);
387 val = val ? val : 1u;
390 deSemaphore_decrement(buffer->empty);
392 buffer->buffer[writePos] = val;
393 writePos = (writePos + 1) % DE_LENGTH_OF_ARRAY(buffer->buffer);
395 deSemaphore_increment(buffer->fill);
397 buffer->producerHash ^= val;
401 void consumerThread (void* arg)
403 TestBuffer* buffer = (TestBuffer*)arg;
410 deSemaphore_decrement(buffer->fill);
412 val = buffer->buffer[readPos];
413 readPos = (readPos + 1) % DE_LENGTH_OF_ARRAY(buffer->buffer);
415 deSemaphore_increment(buffer->empty);
417 buffer->consumerHash ^= val;
424 void deSemaphore_selfTest (void)
428 deSemaphore semaphore = deSemaphore_create(1, DE_NULL);
429 DE_TEST_ASSERT(semaphore);
431 deSemaphore_increment(semaphore);
432 deSemaphore_decrement(semaphore);
433 deSemaphore_decrement(semaphore);
435 deSemaphore_destroy(semaphore);
438 /* Producer-consumer test. */
440 TestBuffer testBuffer;
445 deMemset(&testBuffer, 0, sizeof(testBuffer));
447 testBuffer.empty = deSemaphore_create(DE_LENGTH_OF_ARRAY(testBuffer.buffer), DE_NULL);
448 testBuffer.fill = deSemaphore_create(0, DE_NULL);
450 DE_TEST_ASSERT(testBuffer.empty && testBuffer.fill);
452 consumer = deThread_create(consumerThread, &testBuffer, DE_NULL);
453 producer = deThread_create(producerThread, &testBuffer, DE_NULL);
455 DE_TEST_ASSERT(consumer && producer);
457 ret = deThread_join(consumer) &&
458 deThread_join(producer);
461 deThread_destroy(producer);
462 deThread_destroy(consumer);
464 deSemaphore_destroy(testBuffer.empty);
465 deSemaphore_destroy(testBuffer.fill);
466 DE_TEST_ASSERT(testBuffer.producerHash == testBuffer.consumerHash);
470 void deAtomic_selfTest (void)
472 /* Single-threaded tests. */
474 volatile deInt32 a = 11;
475 DE_TEST_ASSERT(deAtomicIncrementInt32(&a) == 12);
476 DE_TEST_ASSERT(a == 12);
477 DE_TEST_ASSERT(deAtomicIncrementInt32(&a) == 13);
478 DE_TEST_ASSERT(a == 13);
481 DE_TEST_ASSERT(deAtomicIncrementInt32(&a) == -1);
482 DE_TEST_ASSERT(a == -1);
483 DE_TEST_ASSERT(deAtomicIncrementInt32(&a) == 0);
484 DE_TEST_ASSERT(a == 0);
487 DE_TEST_ASSERT(deAtomicDecrementInt32(&a) == 10);
488 DE_TEST_ASSERT(a == 10);
489 DE_TEST_ASSERT(deAtomicDecrementInt32(&a) == 9);
490 DE_TEST_ASSERT(a == 9);
493 DE_TEST_ASSERT(deAtomicDecrementInt32(&a) == -1);
494 DE_TEST_ASSERT(a == -1);
495 DE_TEST_ASSERT(deAtomicDecrementInt32(&a) == -2);
496 DE_TEST_ASSERT(a == -2);
499 DE_TEST_ASSERT(deAtomicIncrementInt32(&a) == (int)0x80000000);
500 DE_TEST_ASSERT(a == (int)0x80000000);
501 DE_TEST_ASSERT(deAtomicDecrementInt32(&a) == (int)0x7fffffff);
502 DE_TEST_ASSERT(a == 0x7fffffff);
506 volatile deUint32 a = 11;
507 DE_TEST_ASSERT(deAtomicIncrementUint32(&a) == 12);
508 DE_TEST_ASSERT(a == 12);
509 DE_TEST_ASSERT(deAtomicIncrementUint32(&a) == 13);
510 DE_TEST_ASSERT(a == 13);
513 DE_TEST_ASSERT(deAtomicIncrementUint32(&a) == 0x80000000);
514 DE_TEST_ASSERT(a == 0x80000000);
515 DE_TEST_ASSERT(deAtomicDecrementUint32(&a) == 0x7fffffff);
516 DE_TEST_ASSERT(a == 0x7fffffff);
519 DE_TEST_ASSERT(deAtomicIncrementUint32(&a) == 0xffffffff);
520 DE_TEST_ASSERT(a == 0xffffffff);
521 DE_TEST_ASSERT(deAtomicDecrementUint32(&a) == 0xfffffffe);
522 DE_TEST_ASSERT(a == 0xfffffffe);
529 DE_TEST_ASSERT(deAtomicCompareExchange32(&p, 0, 1) == 0);
530 DE_TEST_ASSERT(p == 1);
532 DE_TEST_ASSERT(deAtomicCompareExchange32(&p, 0, 2) == 1);
533 DE_TEST_ASSERT(p == 1);
536 DE_TEST_ASSERT(deAtomicCompareExchange32(&p, 6, 8) == 7);
537 DE_TEST_ASSERT(p == 7);
539 DE_TEST_ASSERT(deAtomicCompareExchange32(&p, 7, 8) == 7);
540 DE_TEST_ASSERT(p == 8);
543 #if (DE_PTR_SIZE == 8)
545 volatile deInt64 a = 11;
546 DE_TEST_ASSERT(deAtomicIncrementInt64(&a) == 12);
547 DE_TEST_ASSERT(a == 12);
548 DE_TEST_ASSERT(deAtomicIncrementInt64(&a) == 13);
549 DE_TEST_ASSERT(a == 13);
552 DE_TEST_ASSERT(deAtomicIncrementInt64(&a) == -1);
553 DE_TEST_ASSERT(a == -1);
554 DE_TEST_ASSERT(deAtomicIncrementInt64(&a) == 0);
555 DE_TEST_ASSERT(a == 0);
558 DE_TEST_ASSERT(deAtomicDecrementInt64(&a) == 10);
559 DE_TEST_ASSERT(a == 10);
560 DE_TEST_ASSERT(deAtomicDecrementInt64(&a) == 9);
561 DE_TEST_ASSERT(a == 9);
564 DE_TEST_ASSERT(deAtomicDecrementInt64(&a) == -1);
565 DE_TEST_ASSERT(a == -1);
566 DE_TEST_ASSERT(deAtomicDecrementInt64(&a) == -2);
567 DE_TEST_ASSERT(a == -2);
569 a = (deInt64)((1ull << 63) - 1ull);
570 DE_TEST_ASSERT(deAtomicIncrementInt64(&a) == (deInt64)(1ull << 63));
571 DE_TEST_ASSERT(a == (deInt64)(1ull << 63));
572 DE_TEST_ASSERT(deAtomicDecrementInt64(&a) == (deInt64)((1ull << 63) - 1));
573 DE_TEST_ASSERT(a == (deInt64)((1ull << 63) - 1));
575 #endif /* (DE_PTR_SIZE == 8) */
577 /* \todo [2012-10-26 pyry] Implement multi-threaded tests. */
580 /* Singleton self-test. */
582 DE_DECLARE_POOL_ARRAY(deThreadArray, deThread);
584 static volatile deSingletonState s_testSingleton = DE_SINGLETON_STATE_NOT_INITIALIZED;
585 static volatile int s_testSingletonInitCount = 0;
586 static deBool s_testSingletonInitialized = DE_FALSE;
587 static volatile deBool s_singletonInitLock = DE_FALSE;
589 static void waitForSingletonInitLock (void)
593 deMemoryReadWriteFence();
595 if (s_singletonInitLock)
600 static void initTestSingleton (void* arg)
602 int initTimeMs = *(const int*)arg;
605 deSleep((deUint32)initTimeMs);
607 deAtomicIncrement32(&s_testSingletonInitCount);
608 s_testSingletonInitialized = DE_TRUE;
611 static void singletonTestThread (void* arg)
613 waitForSingletonInitLock();
615 deInitSingleton(&s_testSingleton, initTestSingleton, arg);
616 DE_TEST_ASSERT(s_testSingletonInitialized);
619 static void resetTestState (void)
621 s_testSingleton = DE_SINGLETON_STATE_NOT_INITIALIZED;
622 s_testSingletonInitCount = 0;
623 s_testSingletonInitialized = DE_FALSE;
624 s_singletonInitLock = DE_FALSE;
627 static void runSingletonThreadedTest (int numThreads, int initTimeMs)
629 deMemPool* tmpPool = deMemPool_createRoot(DE_NULL, 0);
630 deThreadArray* threads = tmpPool ? deThreadArray_create(tmpPool) : DE_NULL;
635 for (threadNdx = 0; threadNdx < numThreads; threadNdx++)
637 deThread thread = deThread_create(singletonTestThread, &initTimeMs, DE_NULL);
638 DE_TEST_ASSERT(thread);
639 DE_TEST_ASSERT(deThreadArray_pushBack(threads, thread));
642 /* All threads created - let them do initialization. */
643 deMemoryReadWriteFence();
644 s_singletonInitLock = DE_TRUE;
645 deMemoryReadWriteFence();
647 for (threadNdx = 0; threadNdx < numThreads; threadNdx++)
649 deThread thread = deThreadArray_get(threads, threadNdx);
650 DE_TEST_ASSERT(deThread_join(thread));
651 deThread_destroy(thread);
654 /* Verify results. */
655 DE_TEST_ASSERT(s_testSingletonInitialized);
656 DE_TEST_ASSERT(s_testSingletonInitCount == 1);
658 deMemPool_destroy(tmpPool);
661 void deSingleton_selfTest (void)
670 /* #threads time #repeat */
681 for (caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); caseNdx++)
683 int numThreads = cases[caseNdx].numThreads;
684 int initTimeMs = cases[caseNdx].initTimeMs;
685 int repeatCount = cases[caseNdx].repeatCount;
688 for (subCaseNdx = 0; subCaseNdx < repeatCount; subCaseNdx++)
689 runSingletonThreadedTest(numThreads, initTimeMs);