refactor: unsafe only in adapter + libkos; forbid(unsafe_code) everywhere else; libkos Window (volatile, bounds-checked MMIO/DMA/shared mem), entry!, thread::spawn; MapRegion returns pages; kernel const-built (with_cores/install_platform); newtype addrs
This commit is contained in:
@@ -3,44 +3,43 @@
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
#![forbid(unsafe_code)]
|
||||
|
||||
extern crate libkos;
|
||||
|
||||
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||
use libkos::syscall;
|
||||
use types::address::{EntryPoint, StackPointer, VirtualAddress};
|
||||
use types::bounded::{CapSlot, PageCount};
|
||||
use types::address::VirtualAddress;
|
||||
use types::bounded::CapSlot;
|
||||
use types::mapping::PagePerms;
|
||||
|
||||
/// Counter page layout (words): 0 next free counter index, 1..=THREADS counters.
|
||||
const COUNTERS_VA: usize = 0x0100_0000;
|
||||
const COUNTERS_VA: VirtualAddress = VirtualAddress::from_raw(0x0100_0000);
|
||||
const THREADS: usize = 4;
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
extern "C" fn main() {
|
||||
fn main() {
|
||||
let page = CapSlot::const_new(0);
|
||||
if syscall::map_region(page, VirtualAddress::from_raw(COUNTERS_VA), PagePerms::ReadWrite).is_err() {
|
||||
let Ok(window) = libkos::window::map(page, COUNTERS_VA, PagePerms::ReadWrite) else {
|
||||
libkos::println!("smptest: cannot map the counter page");
|
||||
syscall::exit();
|
||||
}
|
||||
};
|
||||
let words = window.atomics(0, 1 + THREADS);
|
||||
for _ in 1..THREADS {
|
||||
let Some(stack) = PageCount::new(1).and_then(syscall::request_pages) else {
|
||||
if !libkos::thread::spawn(words, spin) {
|
||||
break;
|
||||
};
|
||||
let top = StackPointer::from_raw(stack.raw() + 4096);
|
||||
syscall::spawn_thread(EntryPoint::from_raw(spin as *const () as usize), top, 0);
|
||||
}
|
||||
}
|
||||
spin();
|
||||
spin(words);
|
||||
}
|
||||
|
||||
extern "C" fn spin() -> ! {
|
||||
// SAFETY: COUNTERS_VA maps the counter page; every access is atomic.
|
||||
let word = |i: usize| unsafe { &*((COUNTERS_VA + i * 8) as *const AtomicUsize) };
|
||||
let mine = 1 + word(0).fetch_add(1, Ordering::Relaxed) % THREADS;
|
||||
libkos::entry!(main);
|
||||
|
||||
fn spin(word: &'static [AtomicUsize]) -> ! {
|
||||
let mine = 1 + word[0].fetch_add(1, Ordering::Relaxed) % THREADS;
|
||||
loop {
|
||||
// Yield so a spinner sharing init's hart cannot starve it.
|
||||
for _ in 0..1024 {
|
||||
word(mine).fetch_add(1, Ordering::Relaxed);
|
||||
word[mine].fetch_add(1, Ordering::Relaxed);
|
||||
}
|
||||
syscall::yield_now();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user