1#include "sync/tests/test_internal.h"
2
3#include <asm.h>
4#include <sync/raw_spinlock.h>
5
6TEST_GROUP_DEFINE(raw_spinlock);
7
8static void raw_spin_test_body(bool *rejected_out,
9 bool *acquired_out) TSA_NO_ANALYSIS {
10 struct raw_spinlock lock = RAW_SPINLOCK_INIT;
11
12 raw_spin_lock(lock: &lock);
13 *rejected_out = !raw_spin_trylock(lock: &lock);
14 raw_spin_unlock(lock: &lock);
15
16 *acquired_out = raw_spin_trylock(lock: &lock);
17 if (*acquired_out)
18 raw_spin_unlock(lock: &lock);
19}
20
21TEST_DEFINE_UNIT(raw_spinlock, physical_operations) {
22 bool rejected_while_held = false;
23 bool acquired_after_release = false;
24 raw_spin_test_body(rejected_out: &rejected_while_held, acquired_out: &acquired_after_release);
25
26 TEST_ASSERT(rejected_while_held);
27 TEST_ASSERT(acquired_after_release);
28 return TEST_SUCCESS;
29}
30
31TEST_DEFINE_UNIT(raw_spinlock, irq_restore) {
32 struct raw_spinlock lock = RAW_SPINLOCK_INIT;
33 bool entry_irqs_enabled = irqs_enabled();
34
35 bool saved_irqs_enabled = raw_spin_lock_high(lock: &lock);
36 bool disabled_while_held = !irqs_enabled();
37 raw_spin_unlock_irq_restore(lock: &lock, irqs_were_enabled: saved_irqs_enabled);
38 bool restored_entry_state = irqs_enabled() == entry_irqs_enabled;
39
40 irq_disable();
41 bool saved_disabled_state = raw_spin_lock_high(lock: &lock);
42 raw_spin_unlock_irq_restore(lock: &lock, irqs_were_enabled: saved_disabled_state);
43 bool remained_disabled = !irqs_enabled();
44
45 irq_restore(was_enabled: entry_irqs_enabled);
46
47 TEST_ASSERT_EQ(saved_irqs_enabled, entry_irqs_enabled);
48 TEST_ASSERT(disabled_while_held);
49 TEST_ASSERT(restored_entry_state);
50 TEST_ASSERT(!saved_disabled_state);
51 TEST_ASSERT(remained_disabled);
52 return TEST_SUCCESS;
53}
54