| 1 | #include "sync/tests/test_internal.h" |
|---|---|
| 2 | #include <sync/mutex_simple.h> |
| 3 | |
| 4 | TEST_GROUP_DEFINE(mutex_simple); |
| 5 | |
| 6 | struct simple_contention { |
| 7 | struct mutex_simple mutex; |
| 8 | size_t count; |
| 9 | }; |
| 10 | |
| 11 | static void simple_contender(void *arg) { |
| 12 | struct simple_contention *c = arg; |
| 13 | for (size_t i = 0; i < 32; i++) { |
| 14 | mutex_simple_lock(&c->mutex); |
| 15 | c->count++; |
| 16 | scheduler_yield(); /* force other thread through wait path */ |
| 17 | mutex_simple_unlock(&c->mutex); |
| 18 | } |
| 19 | } |
| 20 | |
| 21 | TEST_DEFINE_UNIT(mutex_simple, object_wait_handoff) { |
| 22 | struct simple_contention c = {0}; |
| 23 | mutex_simple_init(&c.mutex); |
| 24 | struct thread *a = |
| 25 | thread_spawn("simple_a", simple_contender, .arg = &c, .joinable = true); |
| 26 | struct thread *b = |
| 27 | thread_spawn("simple_b", simple_contender, .arg = &c, .joinable = true); |
| 28 | TEST_ASSERT_NONNULL(a); |
| 29 | TEST_ASSERT_NONNULL(b); |
| 30 | thread_join(t: a); |
| 31 | thread_join(t: b); |
| 32 | TEST_ASSERT_EQ(c.count, 64); |
| 33 | TEST_ASSERT(list_head_empty(&c.mutex.waiters.waiters)); |
| 34 | return TEST_SUCCESS; |
| 35 | } |
| 36 |