#include "../kit/shared_mutex.h" #include "../kit/threads.h" #define KIT_TEST_FILE shared_mutex #include "../kit/test.h" enum { SHARED_MUTEX_TEST_SLEEP = 400000000, SHARED_MUTEX_TEST_TICK_COUNT = 200, SHARED_MUTEX_TEST_THREAD_COUNT = 100, }; typedef struct { shared_mutex_t lock; int value; } shared_mutex_test_data_t; static int shared_mutex_test_run_(void *data) { shared_mutex_test_data_t *x = (shared_mutex_test_data_t *) data; for (i64 i = 0; i < SHARED_MUTEX_TEST_TICK_COUNT; i++) { unique_lock(&x->lock); x->value += i; thrd_yield(); x->value -= i + 42; thrd_yield(); x->value += i + 20; thrd_yield(); x->value += 22 - i; unique_unlock(&x->lock); } return 0; } TEST("shared mutex lock") { shared_mutex_test_data_t data; thrd_t pool[SHARED_MUTEX_TEST_THREAD_COUNT]; data.value = 42; shared_mutex_init(&data.lock); for (i64 i = 0; i < SHARED_MUTEX_TEST_THREAD_COUNT; i++) thrd_create(pool + i, shared_mutex_test_run_, &data); for (i64 i = 0; i < SHARED_MUTEX_TEST_THREAD_COUNT; i++) thrd_join(pool[i], NULL); REQUIRE(data.value == 42); } static int shared_mutex_test_lock_(void *data) { shared_mutex_t *m = (shared_mutex_t *) data; unique_lock(m); thrd_sleep( &(struct timespec) { .tv_sec = 0, .tv_nsec = SHARED_MUTEX_TEST_SLEEP, }, NULL); unique_unlock(m); return 0; } TEST("shared mutex try lock") { shared_mutex_t m; shared_mutex_init(&m); thrd_t t; REQUIRE_EQ(thrd_create(&t, shared_mutex_test_lock_, &m), thrd_success); REQUIRE_EQ(thrd_sleep( &(struct timespec) { .tv_sec = 0, .tv_nsec = SHARED_MUTEX_TEST_SLEEP / 2, }, NULL), thrd_success); REQUIRE_EQ(shared_try_lock(&m), 0); REQUIRE_EQ(thrd_join(t, NULL), thrd_success); REQUIRE_EQ(shared_try_lock(&m), 1); shared_unlock(&m); } #undef KIT_TEST_FILE