1#include <sync/rwlock.h>
2#include <test/fleet.h>
3#include <test/sync.h>
4
5#include "sch/tests/test_internal.h"
6
7TEST_GROUP_DEFINE(wroost);
8
9struct wroost_fixture {
10 struct rwlock lock;
11 struct test_latch reader_started;
12};
13
14static bool basic_reader(struct test_fleet *f, struct test_conc_worker *w) {
15 struct wroost_fixture *fix = w->arg;
16
17 rw_read_lock(&fix->lock);
18 test_latch_set(l: &fix->reader_started);
19
20 struct thread *writer = test_fleet_worker_thread(f, role: "writer");
21 TEST_WORKER_POLL_GOTO(
22 f, writer && writer->wroost_data.writer_state == WROOST_WRITER_BUMP,
23 2000, out);
24
25 scheduler_yield();
26
27 enum thread_prio_class prio = thread_get_current()->perceived_prio_class;
28 TEST_WORKER_CHECK_EQ_GOTO(f, prio, THREAD_PRIO_CLASS_REALTIME, out);
29
30 rw_unlock(&fix->lock);
31 return true;
32
33out:
34 rw_unlock(&fix->lock);
35 return false;
36}
37
38static bool basic_writer(struct test_fleet *f, struct test_conc_worker *w) {
39 struct wroost_fixture *fix = w->arg;
40
41 TEST_WORKER_CHECK(f, test_latch_wait_timeout(&fix->reader_started, 2000));
42
43 rw_write_lock(&fix->lock);
44 rw_unlock(&fix->lock);
45 return true;
46}
47
48TEST_DEFINE_UNIT(wroost, basic_boost, .min_cores = 2) {
49 struct test_fleet *fleet = test_fleet_init(ctx);
50
51 struct wroost_fixture *fix = test_new(fix);
52
53 rwlock_init(&fix->lock, THREAD_PRIO_CLASS_REALTIME);
54 test_latch_init(l: &fix->reader_started);
55
56 test_fleet_spawn(fleet, "reader", basic_reader, .core_id = 0, .arg = fix);
57
58 test_fleet_spawn(fleet, "writer", basic_writer, .core_id = 1,
59 .prio_class = THREAD_PRIO_CLASS_REALTIME, .arg = fix);
60
61 test_fleet_start_all(f: fleet);
62 return test_fleet_join(f: fleet);
63}
64
65TEST_DEFINE_UNIT(wroost, propagate_boost, .min_cores = 3) {
66 return TEST_SUCCESS;
67}
68