diff options
Diffstat (limited to 'source/test/unittests')
-rw-r--r-- | source/test/unittests/atomic.test.c | 159 | ||||
-rw-r--r-- | source/test/unittests/condition_variable.test.c | 2 | ||||
-rw-r--r-- | source/test/unittests/mutex.test.c | 34 |
3 files changed, 177 insertions, 18 deletions
diff --git a/source/test/unittests/atomic.test.c b/source/test/unittests/atomic.test.c index 9f1a10b..8f6d22b 100644 --- a/source/test/unittests/atomic.test.c +++ b/source/test/unittests/atomic.test.c @@ -1,4 +1,5 @@ #include "../../kit/atomic.h" +#include "../../kit/threads.h" #define KIT_TEST_FILE atomic #include "../../kit_test/test.h" @@ -24,3 +25,161 @@ TEST("atomic fetch add") { memory_order_relaxed) == 20); REQUIRE(atomic_load_explicit(&value, memory_order_relaxed) == 42); } + +enum { THREAD_COUNT = 20, TICK_COUNT = 10000 }; + +static int test_8_(void *p) { + ATOMIC(int8_t) *x = (ATOMIC(int8_t) *) p; + + for (ptrdiff_t i = 0; i < TICK_COUNT; i++) { + atomic_fetch_add_explicit(x, 20, memory_order_relaxed); + thrd_yield(); + atomic_fetch_add_explicit(x, 22, memory_order_relaxed); + thrd_yield(); + atomic_fetch_add_explicit(x, -42, memory_order_relaxed); + thrd_yield(); + } +} + +TEST("atomic types") { + ATOMIC(int8_t) byte; + ATOMIC(int16_t) i16; + ATOMIC(int32_t) i32; + ATOMIC(int64_t) i64; + + atomic_store_explicit(&byte, 42, memory_order_relaxed); + atomic_store_explicit(&i16, 4242, memory_order_relaxed); + atomic_store_explicit(&i32, 42424242, memory_order_relaxed); + atomic_store_explicit(&i64, 4242424242424242ll, + memory_order_relaxed); + + atomic_fetch_add_explicit(&byte, -20, memory_order_relaxed); + atomic_fetch_add_explicit(&i16, -2020, memory_order_relaxed); + atomic_fetch_add_explicit(&i32, -20202020, memory_order_relaxed); + atomic_fetch_add_explicit(&i64, -2020202020202020ll, + memory_order_relaxed); + + REQUIRE(atomic_exchange_explicit(&byte, 0, memory_order_relaxed) == + 22); + REQUIRE(atomic_exchange_explicit(&i16, 0, memory_order_relaxed) == + 2222); + REQUIRE(atomic_exchange_explicit(&i32, 0, memory_order_relaxed) == + 22222222); + REQUIRE(atomic_exchange_explicit(&i64, 0, memory_order_relaxed) == + 2222222222222222ll); + + REQUIRE(atomic_load_explicit(&byte, memory_order_relaxed) == 0); + REQUIRE(atomic_load_explicit(&i16, memory_order_relaxed) == 0); + REQUIRE(atomic_load_explicit(&i32, memory_order_relaxed) == 0); + REQUIRE(atomic_load_explicit(&i64, memory_order_relaxed) == 0ll); +} + +TEST("atomic byte concurrency") { + ATOMIC(int8_t) foo; + ATOMIC(int8_t) bar; + + atomic_store_explicit(&foo, 42, memory_order_relaxed); + atomic_store_explicit(&bar, 43, memory_order_relaxed); + + thrd_t threads[THREAD_COUNT]; + for (ptrdiff_t i = 0; i < THREAD_COUNT; i++) + thrd_create(threads + i, test_8_, (i % 2) ? &foo : &bar); + for (ptrdiff_t i = 0; i < THREAD_COUNT; i++) + thrd_join(threads[i], NULL); + + REQUIRE(atomic_load_explicit(&foo, memory_order_relaxed) == 42); + REQUIRE(atomic_load_explicit(&bar, memory_order_relaxed) == 43); +} + +static int test_16_(void *p) { + ATOMIC(int16_t) *x = (ATOMIC(int16_t) *) p; + + for (ptrdiff_t i = 0; i < TICK_COUNT; i++) { + atomic_fetch_add_explicit(x, 2020, memory_order_relaxed); + thrd_yield(); + atomic_fetch_add_explicit(x, 2222, memory_order_relaxed); + thrd_yield(); + atomic_fetch_add_explicit(x, -4242, memory_order_relaxed); + thrd_yield(); + } +} + +TEST("atomic int16 concurrency") { + ATOMIC(int16_t) foo; + ATOMIC(int16_t) bar; + + atomic_store_explicit(&foo, 42, memory_order_relaxed); + atomic_store_explicit(&bar, 43, memory_order_relaxed); + + thrd_t threads[THREAD_COUNT]; + for (ptrdiff_t i = 0; i < THREAD_COUNT; i++) + thrd_create(threads + i, test_16_, (i % 2) ? &foo : &bar); + for (ptrdiff_t i = 0; i < THREAD_COUNT; i++) + thrd_join(threads[i], NULL); + + REQUIRE(atomic_load_explicit(&foo, memory_order_relaxed) == 42); + REQUIRE(atomic_load_explicit(&bar, memory_order_relaxed) == 43); +} + +static int test_32_(void *p) { + ATOMIC(int32_t) *x = (ATOMIC(int32_t) *) p; + + for (ptrdiff_t i = 0; i < TICK_COUNT; i++) { + atomic_fetch_add_explicit(x, 202020, memory_order_relaxed); + thrd_yield(); + atomic_fetch_add_explicit(x, 222222, memory_order_relaxed); + thrd_yield(); + atomic_fetch_add_explicit(x, -424242, memory_order_relaxed); + thrd_yield(); + } +} + +TEST("atomic int32 concurrency") { + ATOMIC(int32_t) foo; + ATOMIC(int32_t) bar; + + atomic_store_explicit(&foo, 42, memory_order_relaxed); + atomic_store_explicit(&bar, 43, memory_order_relaxed); + + thrd_t threads[THREAD_COUNT]; + for (ptrdiff_t i = 0; i < THREAD_COUNT; i++) + thrd_create(threads + i, test_32_, (i % 2) ? &foo : &bar); + for (ptrdiff_t i = 0; i < THREAD_COUNT; i++) + thrd_join(threads[i], NULL); + + REQUIRE(atomic_load_explicit(&foo, memory_order_relaxed) == 42); + REQUIRE(atomic_load_explicit(&bar, memory_order_relaxed) == 43); +} + +static int test_64_(void *p) { + ATOMIC(int64_t) *x = (ATOMIC(int64_t) *) p; + + for (ptrdiff_t i = 0; i < TICK_COUNT; i++) { + atomic_fetch_add_explicit(x, 20202020202020ll, + memory_order_relaxed); + thrd_yield(); + atomic_fetch_add_explicit(x, 22222222222222ll, + memory_order_relaxed); + thrd_yield(); + atomic_fetch_add_explicit(x, -42424242424242ll, + memory_order_relaxed); + thrd_yield(); + } +} + +TEST("atomic int64 concurrency") { + ATOMIC(int64_t) foo; + ATOMIC(int64_t) bar; + + atomic_store_explicit(&foo, 42, memory_order_relaxed); + atomic_store_explicit(&bar, 43, memory_order_relaxed); + + thrd_t threads[THREAD_COUNT]; + for (ptrdiff_t i = 0; i < THREAD_COUNT; i++) + thrd_create(threads + i, test_64_, (i % 2) ? &foo : &bar); + for (ptrdiff_t i = 0; i < THREAD_COUNT; i++) + thrd_join(threads[i], NULL); + + REQUIRE(atomic_load_explicit(&foo, memory_order_relaxed) == 42); + REQUIRE(atomic_load_explicit(&bar, memory_order_relaxed) == 43); +} diff --git a/source/test/unittests/condition_variable.test.c b/source/test/unittests/condition_variable.test.c index 93389e9..c855b0c 100644 --- a/source/test/unittests/condition_variable.test.c +++ b/source/test/unittests/condition_variable.test.c @@ -1,4 +1,4 @@ -#include "../../kit/threads.h" +#include "../../kit/condition_variable.h" #define KIT_TEST_FILE condition_variable #include "../../kit_test/test.h" diff --git a/source/test/unittests/mutex.test.c b/source/test/unittests/mutex.test.c index d7b209b..7cce6db 100644 --- a/source/test/unittests/mutex.test.c +++ b/source/test/unittests/mutex.test.c @@ -1,9 +1,9 @@ -#include "../../kit/threads.h" +#include "../../kit/mutex.h" #define KIT_TEST_FILE mutex #include "../../kit_test/test.h" -enum { THREAD_COUNT = 200 }; +enum { SLEEP = 200000000, TICK_COUNT = 200, THREAD_COUNT = 100 }; typedef struct { mtx_t lock; @@ -12,7 +12,7 @@ typedef struct { static int test_run(void *data) { test_data_t *x = (test_data_t *) data; - for (int i = 0; i < 1000; i++) { + for (int i = 0; i < TICK_COUNT; i++) { mtx_lock(&x->lock); x->value += i; @@ -28,18 +28,6 @@ static int test_run(void *data) { return 0; } -int test_lock_for_2_sec(void *data) { - mtx_t *m = (mtx_t *) data; - mtx_lock(m); - - struct timespec sec = { .tv_sec = 2, .tv_nsec = 0 }; - thrd_sleep(&sec, NULL); - - mtx_unlock(m); - - return 0; -} - TEST("mutex lock") { test_data_t data; thrd_t pool[THREAD_COUNT]; @@ -55,14 +43,26 @@ TEST("mutex lock") { REQUIRE(data.value == 42); } +static int test_lock(void *data) { + mtx_t *m = (mtx_t *) data; + mtx_lock(m); + + struct timespec sec = { .tv_sec = 0, .tv_nsec = SLEEP }; + thrd_sleep(&sec, NULL); + + mtx_unlock(m); + + return 0; +} + TEST("mutex try lock") { mtx_t m; REQUIRE(mtx_init(&m, mtx_plain) == thrd_success); thrd_t t; - REQUIRE(thrd_create(&t, test_lock_for_2_sec, &m) == thrd_success); + REQUIRE(thrd_create(&t, test_lock, &m) == thrd_success); - struct timespec sec = { .tv_sec = 1, .tv_nsec = 0 }; + struct timespec sec = { .tv_sec = 0, .tv_nsec = SLEEP / 2 }; REQUIRE(thrd_sleep(&sec, NULL) == thrd_success); REQUIRE(mtx_trylock(&m) == thrd_busy); |