Serene Runtime 1.0.0-dev
C runtime for the Serene programming language
Loading...
Searching...
No Matches
mutex_tests.h File Reference
#include <stdatomic.h>
#include <stdint.h>
#include "base.h"
#include "serene/rt/fiber.h"
#include "serene/rt/fiber/mutex.h"
Include dependency graph for mutex_tests.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define MUTEX_TESTS(X)
#define MTX_MUTEX_N   8
#define MTX_FIFO_N   3
#define MTX_MT_N   64
#define MTX_MT_ITERS   100

Functions

static srn_fiber_ttest_mtx_state (void)
static void test_mutex_init ()
static srn_fiber_result_t test_mtx_uncontended_entry (srn_context_t *ctx, void *arg)
static void test_mutex_uncontended ()
static srn_fiber_result_t test_mtx_me_entry (srn_context_t *ctx, void *arg)
static void test_mutex_mutual_exclusion ()
static srn_fiber_result_t test_mtx_fifo_waiter_entry (srn_context_t *ctx, void *arg)
static srn_fiber_result_t test_mtx_fifo_holder_entry (srn_context_t *ctx, void *arg)
static void test_mutex_fifo_order ()
static srn_fiber_result_t test_mtx_mt_entry (srn_context_t *ctx, void *arg)
static void test_mutex_mt_contention ()

Variables

static srn_fiber_mutex_t test_mtx
static bool test_mtx_uncontended_ran
static int test_mtx_me_counter
static int test_mtx_fifo_order [MTX_FIFO_N]
static int test_mtx_fifo_n
static long test_mtx_mt_counter

Macro Definition Documentation

◆ MTX_FIFO_N

#define MTX_FIFO_N   3

Definition at line 128 of file mutex_tests.h.

◆ MTX_MT_ITERS

#define MTX_MT_ITERS   100

Definition at line 188 of file mutex_tests.h.

◆ MTX_MT_N

#define MTX_MT_N   64

Definition at line 187 of file mutex_tests.h.

◆ MTX_MUTEX_N

#define MTX_MUTEX_N   8

Definition at line 87 of file mutex_tests.h.

◆ MUTEX_TESTS

#define MUTEX_TESTS ( X)
Value:
X("mutex::init", test_mutex_init), X("mutex::uncontended", test_mutex_uncontended), \
X("mutex::mutual_exclusion", test_mutex_mutual_exclusion), \
X("mutex::fifo_order", test_mutex_fifo_order), \
X("mutex::mt_contention", test_mutex_mt_contention)
static void test_mutex_init()
Definition mutex_tests.h:42
static void test_mutex_mt_contention()
static void test_mutex_uncontended()
Definition mutex_tests.h:62
static void test_mutex_mutual_exclusion()
static void test_mutex_fifo_order()

Definition at line 28 of file mutex_tests.h.

28#define MUTEX_TESTS(X) \
29 X("mutex::init", test_mutex_init), X("mutex::uncontended", test_mutex_uncontended), \
30 X("mutex::mutual_exclusion", test_mutex_mutual_exclusion), \
31 X("mutex::fifo_order", test_mutex_fifo_order), \
32 X("mutex::mt_contention", test_mutex_mt_contention)

Function Documentation

◆ test_mtx_fifo_holder_entry()

srn_fiber_result_t test_mtx_fifo_holder_entry ( srn_context_t * ctx,
void * arg )
static

Definition at line 141 of file mutex_tests.h.

141 {
142 UNUSED(ctx);
143 UNUSED(arg);
145 // One yield is enough: the single worker runs all three waiters (each parking
146 // on lock) before this holder is scheduled again.
149 return nullptr;
150}
void srn_fiber_mutex_unlock(srn_fiber_mutex_t *m)
Release m.
Definition mutex.c:99
void srn_fiber_mutex_lock(srn_fiber_mutex_t *m)
Acquire m.
Definition mutex.c:81
static srn_fiber_mutex_t test_mtx
Definition mutex_tests.h:34
void srn_fiber_yield(void)
Yield cooperatively, re-enqueue the running fiber and run the next ready one.
Definition scheduler.c:1039
#define UNUSED(x)
Definition utils.h:45
Here is the call graph for this function:
Here is the caller graph for this function:

◆ test_mtx_fifo_waiter_entry()

srn_fiber_result_t test_mtx_fifo_waiter_entry ( srn_context_t * ctx,
void * arg )
static

Definition at line 132 of file mutex_tests.h.

132 {
133 UNUSED(ctx);
134 int id = (int)(intptr_t)arg;
138 return nullptr;
139}
static int test_mtx_fifo_n
static int test_mtx_fifo_order[MTX_FIFO_N]
Here is the call graph for this function:
Here is the caller graph for this function:

◆ test_mtx_me_entry()

srn_fiber_result_t test_mtx_me_entry ( srn_context_t * ctx,
void * arg )
static

Definition at line 90 of file mutex_tests.h.

90 {
91 UNUSED(ctx);
92 UNUSED(arg);
94 int seen = test_mtx_me_counter;
95 // Yield the execution and let other fibers run
97 test_mtx_me_counter = seen + 1;
99 return nullptr;
100}
static int test_mtx_me_counter
Definition mutex_tests.h:88
Here is the call graph for this function:
Here is the caller graph for this function:

◆ test_mtx_mt_entry()

srn_fiber_result_t test_mtx_mt_entry ( srn_context_t * ctx,
void * arg )
static

Definition at line 191 of file mutex_tests.h.

191 {
192 UNUSED(ctx);
193 UNUSED(arg);
194 for (int i = 0; i < MTX_MT_ITERS; i++) {
196 // plain RMW, guarded solely by the lock
199 }
200 return nullptr;
201}
static long test_mtx_mt_counter
#define MTX_MT_ITERS
Here is the call graph for this function:
Here is the caller graph for this function:

◆ test_mtx_state()

srn_fiber_t * test_mtx_state ( void )
inlinestatic

Definition at line 37 of file mutex_tests.h.

37 {
38 return atomic_load_explicit(&test_mtx.state, memory_order_relaxed);
39}
Here is the caller graph for this function:

◆ test_mtx_uncontended_entry()

srn_fiber_result_t test_mtx_uncontended_entry ( srn_context_t * ctx,
void * arg )
static

Definition at line 48 of file mutex_tests.h.

48 {
49 UNUSED(ctx);
50 UNUSED(arg);
52
55 // Re-acquiring a just-released lock must succeed.
59 return nullptr;
60}
static bool test_mtx_uncontended_ran
Definition mutex_tests.h:35
Here is the call graph for this function:
Here is the caller graph for this function:

◆ test_mutex_fifo_order()

void test_mutex_fifo_order ( )
static

Definition at line 152 of file mutex_tests.h.

152 {
153 MAKE_ENGINE(mm, engine);
154 MAKE_CONTEXT(engine, ctx);
155 srn_scheduler_t *sched = engine->scheduler;
156 ASSERT_NOT_NULL(sched);
157
159 test_mtx_fifo_n = 0;
160
161 // Holder first so it owns the lock before any waiter runs, then the waiters
162 // in the order whose service order we assert.
163 (void)srn_fiber_spawn(ctx, test_mtx_fifo_holder_entry, nullptr);
164 for (int i = 0; i < MTX_FIFO_N; i++) {
165 (void)srn_fiber_spawn(ctx, test_mtx_fifo_waiter_entry, (void *)(intptr_t)(i + 1));
166 }
167 srn_sched_run(sched, 1);
168
170 for (int i = 0; i < MTX_FIFO_N; i++) {
171 TEST_CHECK(test_mtx_fifo_order[i] == i + 1);
172 TEST_MSG(
174 );
175 }
176 TEST_CHECK(test_mtx_state() == nullptr);
177
178 RELEASE_CONTEXT(ctx);
179 SHUTDOWN_ENGINE(mm, engine);
180}
#define TEST_CHECK(cond)
Definition acutest.h:95
#define TEST_MSG(...)
Definition acutest.h:223
#define RELEASE_CONTEXT(x)
Definition base.h:48
#define ASSERT_NOT_NULL(x)
Definition base.h:30
#define SHUTDOWN_ENGINE(mm, engine)
Definition base.h:40
#define MAKE_ENGINE(mm, engine)
Definition base.h:34
#define MAKE_CONTEXT(engine, x)
Definition base.h:44
srn_fiber_t * srn_fiber_spawn(srn_context_t *ctx, srn_fiber_entry_t entry, void *arg)
Make and schedule a fiber with every default, the engine's scheduler, the configured stack size,...
Definition fiber.c:250
void srn_fiber_mutex_init(srn_fiber_mutex_t *m)
Initialise m to the unlocked state.
Definition mutex.c:76
static srn_fiber_result_t test_mtx_fifo_waiter_entry(srn_context_t *ctx, void *arg)
#define MTX_FIFO_N
static srn_fiber_result_t test_mtx_fifo_holder_entry(srn_context_t *ctx, void *arg)
static srn_fiber_t * test_mtx_state(void)
Definition mutex_tests.h:37
void srn_sched_run(srn_scheduler_t *sched, size_t nworkers)
Run the scheduler with nworkers os threads draining it, returning once the pool goes quiescent (every...
Definition scheduler.c:875
Here is the call graph for this function:

◆ test_mutex_init()

void test_mutex_init ( )
static

Definition at line 42 of file mutex_tests.h.

42 {
44 TEST_CHECK(test_mtx_state() == nullptr);
45 TEST_CHECK(test_mtx.waiters_head == nullptr);
46}
Here is the call graph for this function:

◆ test_mutex_mt_contention()

void test_mutex_mt_contention ( )
static

Definition at line 203 of file mutex_tests.h.

203 {
204 MAKE_ENGINE(mm, engine);
205 MAKE_CONTEXT(engine, ctx);
206 srn_scheduler_t *sched = engine->scheduler;
207 ASSERT_NOT_NULL(sched);
208
211
212 for (int i = 0; i < MTX_MT_N; i++) {
213 (void)srn_fiber_spawn(ctx, test_mtx_mt_entry, nullptr);
214 }
215 srn_sched_run(sched, 4);
216
218 TEST_CHECK(test_mtx_state() == nullptr);
219
220 RELEASE_CONTEXT(ctx);
221 SHUTDOWN_ENGINE(mm, engine);
222}
static srn_fiber_result_t test_mtx_mt_entry(srn_context_t *ctx, void *arg)
#define MTX_MT_N
Here is the call graph for this function:

◆ test_mutex_mutual_exclusion()

void test_mutex_mutual_exclusion ( )
static

Definition at line 102 of file mutex_tests.h.

102 {
103 MAKE_ENGINE(mm, engine);
104 MAKE_CONTEXT(engine, ctx);
105 srn_scheduler_t *sched = engine->scheduler;
106 ASSERT_NOT_NULL(sched);
107
110
111 for (int i = 0; i < MTX_MUTEX_N; i++) {
113 }
114 srn_sched_run(sched, 4);
115
116 // No update was lost despite each holder yielding in the middle of the criticalsection.
118 TEST_CHECK(test_mtx_state() == nullptr);
119
120 RELEASE_CONTEXT(ctx);
121 SHUTDOWN_ENGINE(mm, engine);
122}
static srn_fiber_result_t test_mtx_me_entry(srn_context_t *ctx, void *arg)
Definition mutex_tests.h:90
#define MTX_MUTEX_N
Definition mutex_tests.h:87
Here is the call graph for this function:

◆ test_mutex_uncontended()

void test_mutex_uncontended ( )
static

Definition at line 62 of file mutex_tests.h.

62 {
63 MAKE_ENGINE(mm, engine);
64 MAKE_CONTEXT(engine, ctx);
65 srn_scheduler_t *sched = engine->scheduler;
66 ASSERT_NOT_NULL(sched);
67
69
71 srn_sched_run(sched, 1);
72
74 // The lock is released once the fiber is done.
75 TEST_CHECK(test_mtx_state() == nullptr);
76
77 RELEASE_CONTEXT(ctx);
78 SHUTDOWN_ENGINE(mm, engine);
79}
static srn_fiber_result_t test_mtx_uncontended_entry(srn_context_t *ctx, void *arg)
Definition mutex_tests.h:48
Here is the call graph for this function:

Variable Documentation

◆ test_mtx

srn_fiber_mutex_t test_mtx
static

Definition at line 34 of file mutex_tests.h.

◆ test_mtx_fifo_n

int test_mtx_fifo_n
static

Definition at line 130 of file mutex_tests.h.

◆ test_mtx_fifo_order

int test_mtx_fifo_order[MTX_FIFO_N]
static

Definition at line 129 of file mutex_tests.h.

◆ test_mtx_me_counter

int test_mtx_me_counter
static

Definition at line 88 of file mutex_tests.h.

◆ test_mtx_mt_counter

long test_mtx_mt_counter
static

Definition at line 189 of file mutex_tests.h.

◆ test_mtx_uncontended_ran

bool test_mtx_uncontended_ran
static

Definition at line 35 of file mutex_tests.h.