Skip to main content

ksync_kernel_tests/
kernel.rs

1// Copyright 2026 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#![no_std]
6#![cfg_attr(not(ktest), allow(unused_crate_dependencies))]
7
8#[cfg(ktest)]
9#[unittest::test_suite(name = "rust_ksync")]
10/// Tests for Rust ksync bindings
11mod ksync_tests {
12    use pin_init::{pin_init, stack_pin_init};
13    use unittest::{assert_true, expect_false, expect_ok, expect_true};
14
15    #[unsafe(no_mangle)]
16    pub extern "C" fn ksync_tests_link_helper() {}
17
18    #[ksync::guarded]
19    struct GuardedMutexObj {
20        #[mutex]
21        mu: ksync::KMutex,
22        #[guarded_by(mu)]
23        value: u32,
24    }
25
26    #[ksync::guarded]
27    struct GuardedSpinlockObj {
28        #[mutex]
29        mu: ksync::KMutex<ksync::RawSpinlock>,
30        #[guarded_by(mu)]
31        value: u32,
32    }
33
34    #[ksync::guarded]
35    struct GuardedCriticalMutexObj {
36        #[mutex]
37        mu: ksync::KMutex<ksync::RawCriticalMutex>,
38        #[guarded_by(mu)]
39        value: u32,
40    }
41
42    #[ksync::guarded]
43    struct GuardedBrwLockObj {
44        #[brwlock]
45        lock: ksync::BrwLockPi,
46        #[guarded_by(lock)]
47        value: u32,
48    }
49
50    unsafe extern "C" {
51        fn cpp_verify_mutex_id(
52            lock: *const core::ffi::c_void,
53            expected_id: *const core::ffi::c_void,
54        ) -> bool;
55        fn cpp_verify_critical_mutex_id(
56            lock: *const core::ffi::c_void,
57            expected_id: *const core::ffi::c_void,
58        ) -> bool;
59        fn cpp_verify_spinlock_id(
60            lock: *const core::ffi::c_void,
61            expected_id: *const core::ffi::c_void,
62        ) -> bool;
63        fn cpp_verify_brwlock_id(
64            lock: *const core::ffi::c_void,
65            expected_id: *const core::ffi::c_void,
66        ) -> bool;
67    }
68
69    /// test Rust KMutex ID
70    #[test]
71    fn mutex_id() {
72        stack_pin_init!(let obj = pin_init!(GuardedMutexObj {
73            mu <- ksync::KMutex::init(),
74            value: 0.into(),
75        }));
76        unsafe {
77            assert_true!(cpp_verify_mutex_id(
78                &obj.mu as *const _ as *const core::ffi::c_void,
79                <GuardedMutexObjMuClass as ksync::LockClass>::ID,
80            ));
81        }
82    }
83
84    /// test Rust KCriticalMutex ID
85    #[test]
86    fn critical_mutex_id() {
87        stack_pin_init!(let obj = pin_init!(GuardedCriticalMutexObj {
88            mu <- ksync::KMutex::init(),
89            value: 0.into(),
90        }));
91        unsafe {
92            assert_true!(cpp_verify_critical_mutex_id(
93                &obj.mu as *const _ as *const core::ffi::c_void,
94                <GuardedCriticalMutexObjMuClass as ksync::LockClass>::ID,
95            ));
96        }
97    }
98
99    /// test Rust KSpinlock ID
100    #[test]
101    fn spinlock_id() {
102        stack_pin_init!(let obj = pin_init!(GuardedSpinlockObj {
103            mu <- ksync::KMutex::init(),
104            value: 0.into(),
105        }));
106        unsafe {
107            assert_true!(cpp_verify_spinlock_id(
108                &obj.mu as *const _ as *const core::ffi::c_void,
109                <GuardedSpinlockObjMuClass as ksync::LockClass>::ID,
110            ));
111        }
112    }
113
114    /// test Rust BrwLockPi ID
115    #[test]
116    fn brwlock_id() {
117        stack_pin_init!(let obj = pin_init!(GuardedBrwLockObj {
118            lock <- ksync::BrwLockPi::init(),
119            value: 0.into(),
120        }));
121        unsafe {
122            assert_true!(cpp_verify_brwlock_id(
123                &obj.lock as *const _ as *const core::ffi::c_void,
124                <GuardedBrwLockObjLockClass as ksync::LockClass>::ID,
125            ));
126        }
127    }
128
129    /// test Rust KSpinlock
130    #[test]
131    fn spinlock() {
132        stack_pin_init!(let obj = pin_init!(GuardedSpinlockObj {
133            mu <- ksync::KMutex::init(),
134            value: 100.into(),
135        }));
136
137        {
138            ksync::lock!(let mut guard = obj.lock_mu());
139            expect_true!(*guard.value() == 100);
140            *guard.as_mut().value_mut() = 101;
141        }
142
143        {
144            ksync::lock!(let guard = obj.lock_mu());
145            expect_true!(*guard.value() == 101);
146        }
147    }
148
149    /// test Rust KMutex
150    #[test]
151    fn mutex() {
152        stack_pin_init!(let obj = pin_init!(GuardedMutexObj {
153            mu <- ksync::KMutex::init(),
154            value: 42.into(),
155        }));
156
157        {
158            ksync::lock!(let mut guard = obj.lock_mu());
159            expect_true!(*guard.value() == 42);
160            *guard.as_mut().value_mut() = 43;
161        }
162
163        {
164            ksync::lock!(let guard = obj.lock_mu());
165            expect_true!(*guard.value() == 43);
166        }
167    }
168
169    /// test Rust KEvent
170    #[test]
171    fn event() {
172        stack_pin_init!(let event = ksync::KEvent::init(false));
173        expect_false!(event.wait_deadline(0).is_ok());
174        event.signal();
175        expect_ok!(event.wait_deadline(0));
176        event.unsignal();
177        expect_false!(event.wait_deadline(0).is_ok());
178    }
179
180    /// test Rust BrwLockPi
181    #[test]
182    fn brwlock() {
183        stack_pin_init!(let obj = pin_init!(GuardedBrwLockObj {
184            lock <- ksync::BrwLockPi::init(),
185            value: 10.into(),
186        }));
187
188        {
189            ksync::lock!(let guard = obj.read_lock());
190            expect_true!(*guard.value() == 10);
191        }
192
193        {
194            ksync::lock!(let mut guard = obj.write_lock());
195            expect_true!(*guard.value() == 10);
196            *guard.as_mut().value_mut() = 20;
197        }
198
199        {
200            ksync::lock!(let guard = obj.read_lock());
201            expect_true!(*guard.value() == 20);
202        }
203    }
204}