summaryrefslogtreecommitdiff
path: root/source/tests
diff options
context:
space:
mode:
Diffstat (limited to 'source/tests')
-rw-r--r--source/tests/_exe.c1
-rw-r--r--source/tests/shared_mutex.test.c93
2 files changed, 94 insertions, 0 deletions
diff --git a/source/tests/_exe.c b/source/tests/_exe.c
index 5509ab3..acbe5c2 100644
--- a/source/tests/_exe.c
+++ b/source/tests/_exe.c
@@ -15,6 +15,7 @@
#include "astar.test.c"
#include "move_back.test.c"
#include "mutex.test.c"
+#include "shared_mutex.test.c"
#include "secure_random.test.c"
#include "sha256.test.c"
#include "string_ref.test.c"
diff --git a/source/tests/shared_mutex.test.c b/source/tests/shared_mutex.test.c
new file mode 100644
index 0000000..9ee999b
--- /dev/null
+++ b/source/tests/shared_mutex.test.c
@@ -0,0 +1,93 @@
+#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