1#![no_std]
12#![feature(core_intrinsics)]
13#![feature(int_roundings)]
14#![feature(thread_local)]
15#![feature(auto_traits)]
16#![feature(negative_impls)]
17#![allow(unexpected_cfgs)]
18#![allow(internal_features)]
19#![feature(rustc_attrs)]
20#![feature(linkage)]
21#![feature(test)]
22#![feature(c_variadic)]
23
24use syscall::KernelConsoleSource;
25pub mod arch;
26
27#[allow(unused_extern_crates)]
28extern crate alloc as rustc_alloc;
29
30pub mod aux;
31pub mod device;
32pub mod klog;
33pub mod kso;
34pub mod meta;
35pub mod object;
36pub mod pager;
37pub mod security;
38pub mod simple_mutex;
39pub mod slot;
40pub mod syscall;
41pub mod thread;
42pub mod trace;
43pub mod upcall;
44
45#[cfg(all(not(target_os = "twizzler"), not(feature = "kernel")))]
46static _NO: () = panic!("cannot compile for non-twizzler OS");
47
48#[inline]
49unsafe fn internal_abort() -> ! {
50 core::intrinsics::abort();
51}
52
53pub fn print_err(err: &str) {
54 syscall::sys_kernel_console_write(
55 KernelConsoleSource::Console,
56 err.as_bytes(),
57 syscall::KernelConsoleWriteFlags::empty(),
58 );
59}
60
61#[allow(dead_code)]
62fn internal_unwrap<T>(t: Option<T>, msg: &str) -> T {
66 if let Some(t) = t {
67 t
68 } else {
69 print_err(msg);
70 unsafe {
71 internal_abort();
72 }
73 }
74}
75
76#[allow(dead_code)]
77fn internal_unwrap_result<T, E>(t: Result<T, E>, msg: &str) -> T {
81 if let Ok(t) = t {
82 t
83 } else {
84 print_err(msg);
85 unsafe {
86 internal_abort();
87 }
88 }
89}
90
91#[cfg(test)]
92extern crate test;
93
94#[cfg(test)]
95mod tester {
96 use core::sync::atomic::AtomicU64;
97
98 use crate::{
99 simple_mutex::Mutex,
100 syscall::{
101 sys_thread_sync, ThreadSync, ThreadSyncFlags, ThreadSyncOp, ThreadSyncReference,
102 ThreadSyncSleep, ThreadSyncWake,
103 },
104 };
105
106 #[bench]
107 fn test_bench(bench: &mut test::Bencher) {
108 bench.iter(|| {
109 for i in 0..10000 {
110 core::hint::black_box(i);
111 }
112 });
113 }
114
115 #[bench]
116 fn bench_yield(bench: &mut test::Bencher) {
117 bench.iter(|| {
118 crate::syscall::sys_thread_yield();
119 });
120 }
121
122 #[bench]
123 fn bench_simple_syscall(bench: &mut test::Bencher) {
124 bench.iter(|| {
125 crate::syscall::sys_thread_self_id();
126 });
127 }
128
129 #[bench]
130 fn bench_thread_sync_sleep_ready(bench: &mut test::Bencher) {
131 let word = AtomicU64::new(0);
132 bench.iter(|| {
133 let r = sys_thread_sync(
134 &mut [ThreadSync::new_sleep(ThreadSyncSleep::new(
135 ThreadSyncReference::Virtual(&word),
136 1,
137 ThreadSyncOp::Equal,
138 ThreadSyncFlags::empty(),
139 ))],
140 None,
141 );
142 let _ = core::hint::black_box(r);
143 });
144 }
145
146 #[bench]
147 fn bench_thread_sync_wake(bench: &mut test::Bencher) {
148 let word = AtomicU64::new(0);
149 bench.iter(|| {
150 let r = sys_thread_sync(
151 &mut [ThreadSync::new_wake(ThreadSyncWake::new(
152 ThreadSyncReference::Virtual(&word),
153 1,
154 ))],
155 None,
156 );
157 let _ = core::hint::black_box(r);
158 });
159 }
160
161 #[bench]
162 fn bench1000_smutex_lock_unlock(bench: &mut test::Bencher) {
163 let lock = Mutex::new(3);
164 bench.iter(|| {
165 for _ in 0..1000 {
166 let mut g = lock.lock();
167 *g += 1;
168 let g = core::hint::black_box(g);
169 drop(g);
170 }
171 });
172 }
173}