a touch more fiddling

This commit is contained in:
koniifer 2024-09-10 00:10:10 +01:00
parent fd155ea26a
commit 3b95371c41
11 changed files with 239 additions and 164 deletions

53
Cargo.lock generated
View file

@ -166,15 +166,6 @@ dependencies = [
"windows-targets", "windows-targets",
] ]
[[package]]
name = "convert_case"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca"
dependencies = [
"unicode-segmentation",
]
[[package]] [[package]]
name = "core-foundation-sys" name = "core-foundation-sys"
version = "0.8.7" version = "0.8.7"
@ -211,7 +202,6 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22"
dependencies = [ dependencies = [
"convert_case",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn",
@ -391,17 +381,17 @@ dependencies = [
[[package]] [[package]]
name = "hbbytecode" name = "hbbytecode"
version = "0.1.0" version = "0.1.0"
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#e8a5027cab7ce008dbb0964fe0522c8fef585979" source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#67b8ffe2f223629850c293858abbb0cc5337a850"
[[package]] [[package]]
name = "hbbytecode" name = "hbbytecode"
version = "0.1.0" version = "0.1.0"
source = "git+https://git.ablecorp.us/ableos/holey-bytes#e8a5027cab7ce008dbb0964fe0522c8fef585979" source = "git+https://git.ablecorp.us/ableos/holey-bytes#67b8ffe2f223629850c293858abbb0cc5337a850"
[[package]] [[package]]
name = "hblang" name = "hblang"
version = "0.1.0" version = "0.1.0"
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#e8a5027cab7ce008dbb0964fe0522c8fef585979" source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#67b8ffe2f223629850c293858abbb0cc5337a850"
dependencies = [ dependencies = [
"hbvm 0.1.0 (git+https://git.ablecorp.us/AbleOS/holey-bytes.git)", "hbvm 0.1.0 (git+https://git.ablecorp.us/AbleOS/holey-bytes.git)",
] ]
@ -409,7 +399,7 @@ dependencies = [
[[package]] [[package]]
name = "hbvm" name = "hbvm"
version = "0.1.0" version = "0.1.0"
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#e8a5027cab7ce008dbb0964fe0522c8fef585979" source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#67b8ffe2f223629850c293858abbb0cc5337a850"
dependencies = [ dependencies = [
"hbbytecode 0.1.0 (git+https://git.ablecorp.us/AbleOS/holey-bytes.git)", "hbbytecode 0.1.0 (git+https://git.ablecorp.us/AbleOS/holey-bytes.git)",
] ]
@ -417,7 +407,7 @@ dependencies = [
[[package]] [[package]]
name = "hbvm" name = "hbvm"
version = "0.1.0" version = "0.1.0"
source = "git+https://git.ablecorp.us/ableos/holey-bytes#e8a5027cab7ce008dbb0964fe0522c8fef585979" source = "git+https://git.ablecorp.us/ableos/holey-bytes#67b8ffe2f223629850c293858abbb0cc5337a850"
dependencies = [ dependencies = [
"hbbytecode 0.1.0 (git+https://git.ablecorp.us/ableos/holey-bytes)", "hbbytecode 0.1.0 (git+https://git.ablecorp.us/ableos/holey-bytes)",
] ]
@ -507,9 +497,9 @@ dependencies = [
[[package]] [[package]]
name = "hyper-util" name = "hyper-util"
version = "0.1.7" version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9" checksum = "da62f120a8a37763efb0cf8fdf264b884c7b8b9ac8660b900c8661030c00e6ba"
dependencies = [ dependencies = [
"bytes", "bytes",
"futures-channel", "futures-channel",
@ -594,16 +584,14 @@ name = "kernel"
version = "0.2.0" version = "0.2.0"
dependencies = [ dependencies = [
"crossbeam-queue", "crossbeam-queue",
"crossbeam-utils",
"derive_more", "derive_more",
"embedded-graphics", "embedded-graphics",
"hashbrown", "hashbrown",
"hbvm 0.1.0 (git+https://git.ablecorp.us/ableos/holey-bytes)", "hbvm 0.1.0 (git+https://git.ablecorp.us/ableos/holey-bytes)",
"kiam",
"limine", "limine",
"log", "log",
"rdrand",
"sbi", "sbi",
"slab",
"spin", "spin",
"uart_16550", "uart_16550",
"versioning", "versioning",
@ -613,12 +601,6 @@ dependencies = [
"xml", "xml",
] ]
[[package]]
name = "kiam"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb0fc32485e41ae5e9dedd1442f36dec998431adc9f321224c2c5d645f38fdcb"
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.5.0" version = "1.5.0"
@ -907,15 +889,6 @@ dependencies = [
"bitflags 1.3.2", "bitflags 1.3.2",
] ]
[[package]]
name = "rdrand"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d92195228612ac8eed47adbc2ed0f04e513a4ccb98175b6f2bd04d963b533655"
dependencies = [
"rand_core",
]
[[package]] [[package]]
name = "regex-syntax" name = "regex-syntax"
version = "0.8.4" version = "0.8.4"
@ -1046,9 +1019,9 @@ checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0"
[[package]] [[package]]
name = "rustls-webpki" name = "rustls-webpki"
version = "0.102.7" version = "0.102.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84678086bd54edf2b415183ed7a94d0efb049f1b646a33e22a36f3794be6ae56" checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9"
dependencies = [ dependencies = [
"ring", "ring",
"rustls-pki-types", "rustls-pki-types",
@ -1389,12 +1362,6 @@ dependencies = [
"tinyvec", "tinyvec",
] ]
[[package]]
name = "unicode-segmentation"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
[[package]] [[package]]
name = "unicode-xid" name = "unicode-xid"
version = "0.2.5" version = "0.2.5"

View file

@ -9,13 +9,11 @@ embedded-graphics = "0.8"
hbvm.git = "https://git.ablecorp.us/ableos/holey-bytes" hbvm.git = "https://git.ablecorp.us/ableos/holey-bytes"
log = "0.4" log = "0.4"
spin = "0.9" spin = "0.9"
uart_16550 = "0.3" uart_16550 = { version = "0.3", features = ["nightly"] }
slab = { version = "0.4", default-features = false }
xml.git = "https://git.ablecorp.us/ableos/ableos_userland" xml.git = "https://git.ablecorp.us/ableos/ableos_userland"
versioning.git = "https://git.ablecorp.us/ableos/ableos_userland" versioning.git = "https://git.ablecorp.us/ableos/ableos_userland"
# able_graphics_library.git = "https://git.ablecorp.us/ableos/ableos_userland" # able_graphics_library.git = "https://git.ablecorp.us/ableos/ableos_userland"
hashbrown = "0.14" hashbrown = { version = "0.14", features = ["nightly"] }
kiam = "0.1"
[dependencies.limine] [dependencies.limine]
version = "0.1" version = "0.1"
@ -24,7 +22,11 @@ version = "0.1"
[dependencies.crossbeam-queue] [dependencies.crossbeam-queue]
version = "0.3" version = "0.3"
default-features = false default-features = false
features = ["alloc"] features = ["alloc", "nightly"]
[dependencies.crossbeam-utils]
version = "0.8"
default-features = false
# [dependencies.clparse] # [dependencies.clparse]
# git = "https://git.ablecorp.us/ableos/ableos_userland" # git = "https://git.ablecorp.us/ableos/ableos_userland"
@ -51,9 +53,6 @@ features = [
x86_64 = "0.15" x86_64 = "0.15"
x2apic = "0.4" x2apic = "0.4"
virtio-drivers = "0.7" virtio-drivers = "0.7"
# rdrand = "*"
rdrand = { version = "0.8", default-features = false }
[target.'cfg(target_arch = "riscv64")'.dependencies] [target.'cfg(target_arch = "riscv64")'.dependencies]
sbi = "0.2.0" sbi = "0.2.0"

View file

@ -1,8 +1,10 @@
use core::num; use core::num;
use alloc::boxed::Box; use {
use spin::{Mutex, Once}; crate::memory::{MemoryManager, PhysicalAddress, VirtualAddress},
use crate::memory::{MemoryManager, PhysicalAddress, VirtualAddress}; alloc::boxed::Box,
spin::{Mutex, Once},
};
use super::PAGE_SIZE; use super::PAGE_SIZE;
@ -28,7 +30,7 @@ impl PageSize {
} }
pub struct PageTable { pub struct PageTable {
entries: [PageEntry; 512] entries: [PageEntry; 512],
} }
impl PageTable { impl PageTable {
@ -72,8 +74,14 @@ impl PageTable {
/// flags MUST include one or more of the following: /// flags MUST include one or more of the following:
/// Read, Write, Execute /// Read, Write, Execute
/// The valid bit automatically gets added /// The valid bit automatically gets added
pub fn map(&mut self, vaddr: VirtualAddress, paddr: PhysicalAddress, flags: PageEntryFlags, page_size: PageSize) { pub fn map(
assert!(flags as usize & 0xe != 0); &mut self,
vaddr: VirtualAddress,
paddr: PhysicalAddress,
flags: PageEntryFlags,
page_size: PageSize,
) {
assert!(flags as usize & 0xE != 0);
let vpn = vaddr.vpns(); let vpn = vaddr.vpns();
let ppn = paddr.ppns(); let ppn = paddr.ppns();
@ -91,7 +99,7 @@ impl PageTable {
} }
let entry = v.addr().as_mut_ptr::<PageEntry>(); let entry = v.addr().as_mut_ptr::<PageEntry>();
v = unsafe { entry.add(vpn[i]).as_mut().unwrap() }; v = unsafe { entry.add(vpn[i]).as_mut().unwrap() };
} }
// When we get here, we should be at VPN[0] and v should be pointing to our entry. // When we get here, we should be at VPN[0] and v should be pointing to our entry.
@ -105,14 +113,24 @@ impl PageTable {
} }
/// Identity maps a page of memory /// Identity maps a page of memory
pub fn identity_map(&mut self, addr: PhysicalAddress, flags: PageEntryFlags, page_size: PageSize) { pub fn identity_map(
&mut self,
addr: PhysicalAddress,
flags: PageEntryFlags,
page_size: PageSize,
) {
// log::debug!("identity mapped {addr}"); // log::debug!("identity mapped {addr}");
self.map(addr.as_addr().into(), addr, flags, page_size); self.map(addr.as_addr().into(), addr, flags, page_size);
} }
/// Identity maps a range of contiguous memory /// Identity maps a range of contiguous memory
/// This assumes that start <= end /// This assumes that start <= end
pub fn identity_map_range(&mut self, start: PhysicalAddress, end: PhysicalAddress, flags: PageEntryFlags) { pub fn identity_map_range(
&mut self,
start: PhysicalAddress,
end: PhysicalAddress,
flags: PageEntryFlags,
) {
log::debug!("start: {start}, end: {end}"); log::debug!("start: {start}, end: {end}");
let mut mem_addr = start.as_addr() & !(PAGE_SIZE - 1); let mut mem_addr = start.as_addr() & !(PAGE_SIZE - 1);
let num_pages = (align_val(end.as_addr(), 12) - mem_addr - 1) / PAGE_SIZE + 1; let num_pages = (align_val(end.as_addr(), 12) - mem_addr - 1) / PAGE_SIZE + 1;
@ -142,7 +160,7 @@ impl PageTable {
} }
let entry = v.addr().as_mut_ptr::<PageEntry>(); let entry = v.addr().as_mut_ptr::<PageEntry>();
v = unsafe { entry.add(vpn[i]).as_mut().unwrap() }; v = unsafe { entry.add(vpn[i]).as_mut().unwrap() };
} }
// If we're here this is an unmapped page // If we're here this is an unmapped page
@ -182,7 +200,7 @@ pub enum PageEntryFlags {
Global = 1 << 5, Global = 1 << 5,
Access = 1 << 6, Access = 1 << 6,
Dirty = 1 << 7, Dirty = 1 << 7,
// for convenience // for convenience
ReadWrite = Self::Read as usize | Self::Write as usize, ReadWrite = Self::Read as usize | Self::Write as usize,
ReadExecute = Self::Read as usize | Self::Execute as usize, ReadExecute = Self::Read as usize | Self::Execute as usize,
@ -228,7 +246,7 @@ impl PageEntry {
} }
fn addr(&self) -> PhysicalAddress { fn addr(&self) -> PhysicalAddress {
((self.entry() as usize & !0x3ff) << 2).into() ((self.entry() as usize & !0x3FF) << 2).into()
} }
fn destroy(&mut self) { fn destroy(&mut self) {

View file

@ -1,4 +1,6 @@
use {crate::bootmodules::BootModule, core::arch::asm, log::warn, rdrand::RdSeed}; use core::arch::x86_64::{_rdrand32_step, _rdrand64_step, _rdseed32_step, _rdseed64_step};
use {crate::bootmodules::BootModule, core::arch::asm, log::warn};
pub mod memory; pub mod memory;
mod cpuid; mod cpuid;
@ -189,62 +191,43 @@ unsafe extern "C" fn start() -> ! {
) )
} }
use crossbeam_utils::Backoff;
/// Spin loop /// Spin loop
pub fn spin_loop() -> ! { pub fn spin_loop() -> ! {
let backoff = Backoff::new();
loop { loop {
x86_64::instructions::hlt(); core::hint::spin_loop();
// x86_64::instructions::hlt();
backoff.spin()
} }
} }
pub fn hardware_random_u64() -> u64 { pub fn hardware_random_u64() -> u64 {
use {log::trace, rdrand::RdRand}; let mut out: u64 = 0;
let gen = RdRand::new(); match unsafe { _rdrand64_step(&mut out) } {
match gen { 1 => out,
Ok(gen) => { _ => {
let ret = gen.try_next_u64().unwrap();
trace!("Random {}", ret);
return ret;
}
Err(_) => {
warn!("RDRand not supported."); warn!("RDRand not supported.");
// Try rdseed // Try rdseed
let gen = RdSeed::new(); match unsafe { _rdseed64_step(&mut out) } {
match gen { 1 => out,
Ok(gen) => { _ => panic!("Neither RDRand or RDSeed are supported"),
let ret = gen.try_next_u64().unwrap();
trace!("Random {}", ret);
return ret;
}
Err(_) => {
panic!("Neither RDRand or RDSeed are supported")
}
} }
} }
} }
} }
pub fn hardware_random_u32() -> u32 { pub fn hardware_random_u32() -> u32 {
use {log::trace, rdrand::RdRand}; let mut out: u32 = 0;
let gen = RdRand::new(); match unsafe { _rdrand32_step(&mut out) } {
match gen { 1 => out,
Ok(gen) => { _ => {
let ret = gen.try_next_u32().unwrap();
trace!("Random {}", ret);
return ret;
}
Err(_) => {
warn!("RDRand not supported."); warn!("RDRand not supported.");
// Try rdseed // Try rdseed
let gen = RdSeed::new(); match unsafe { _rdseed32_step(&mut out) } {
match gen { 1 => out,
Ok(gen) => { _ => panic!("Neither RDRand or RDSeed are supported"),
let ret = gen.try_next_u32().unwrap();
trace!("Random {}", ret);
return ret;
}
Err(_) => {
panic!("Neither RDRand or RDSeed are supported")
}
} }
} }
} }

View file

@ -65,7 +65,7 @@ impl<'p> Drop for ExecThread<'p> {
impl<'p> Future for ExecThread<'p> { impl<'p> Future for ExecThread<'p> {
type Output = Result<(), VmRunError>; type Output = Result<(), VmRunError>;
#[inline(always)]
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
match self.vm.run() { match self.vm.run() {
Err(err) => { Err(err) => {
@ -110,10 +110,12 @@ impl HandlePageFault for PageFaultHandler {
} }
} }
#[inline(always)]
const fn stack_layout() -> Layout { const fn stack_layout() -> Layout {
unsafe { Layout::from_size_align_unchecked(STACK_SIZE, 4096) } unsafe { Layout::from_size_align_unchecked(STACK_SIZE, 4096) }
} }
#[inline(always)]
fn allocate_stack() -> NonNull<u8> { fn allocate_stack() -> NonNull<u8> {
let layout = stack_layout(); let layout = stack_layout();
NonNull::new(unsafe { alloc::alloc::alloc_zeroed(layout) }) NonNull::new(unsafe { alloc::alloc::alloc_zeroed(layout) })

View file

@ -66,7 +66,7 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
fb1.address.as_ptr().unwrap() as *const u8 fb1.address.as_ptr().unwrap() as *const u8
); );
let mut executor = crate::task::Executor::default(); let mut executor = crate::task::Executor::new(256);
let bm_take = boot_modules.len(); let bm_take = boot_modules.len();
unsafe { unsafe {
for module in boot_modules.into_iter().take(bm_take) { for module in boot_modules.into_iter().take(bm_take) {
@ -80,16 +80,17 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
log::info!("Spawning {} with arguments \"{}\"", module.path, cmd); log::info!("Spawning {} with arguments \"{}\"", module.path, cmd);
executor.spawn(async move { executor
let mut thr = ExecThread::new(&module.bytes, Address::new(0)); .spawn(async move {
if cmd_len > 0 { let mut thr = ExecThread::new(&module.bytes, Address::new(0));
thr.set_arguments(cmd.as_bytes().as_ptr() as u64, cmd_len); if cmd_len > 0 {
} thr.set_arguments(cmd.as_bytes().as_ptr() as u64, cmd_len);
}
if let Err(e) = thr.await { if let Err(e) = thr.await {
log::error!("{e:?}"); log::error!("{e:?}");
} }
}); })
.unwrap();
} }
info!("Random number: {}", hardware_random_u64()); info!("Random number: {}", hardware_random_u64());

View file

@ -1,23 +1,23 @@
#![allow(unused)]
use { use {
alloc::{boxed::Box, sync::Arc, task::Wake}, alloc::{boxed::Box, sync::Arc, task::Wake},
core::{ core::{
future::Future, future::Future,
pin::Pin, pin::Pin,
sync::atomic::{AtomicUsize, Ordering},
task::{Context, Poll, Waker}, task::{Context, Poll, Waker},
}, },
crossbeam_queue::SegQueue, crossbeam_queue::SegQueue,
hashbrown::HashMap, crossbeam_utils::CachePadded,
slab::Slab,
spin::Mutex,
}; };
use alloc::vec::Vec;
pub fn yield_now() -> impl Future<Output = ()> { pub fn yield_now() -> impl Future<Output = ()> {
struct YieldNow(bool); struct YieldNow(bool);
impl Future for YieldNow { impl Future for YieldNow {
type Output = (); type Output = ();
#[inline(always)]
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
if self.0 { if self.0 {
Poll::Ready(()) Poll::Ready(())
@ -34,86 +34,168 @@ pub fn yield_now() -> impl Future<Output = ()> {
#[derive(Default)] #[derive(Default)]
pub struct Executor { pub struct Executor {
tasks: Slab<Task>, tasks: Vec<CachePadded<TaskSlot>>,
queue: Arc<SegQueue<TaskId>>, task_queue: Arc<TaskQueue>,
wakers: HashMap<TaskId, Waker>, // Keeping HashMap as it is more performant for lookups. max_tasks: usize,
} }
impl Executor { impl Executor {
pub fn new() -> Self { pub fn new(max_tasks: usize) -> Self {
Self { Self {
tasks: Slab::new(), tasks: (0..max_tasks)
queue: Arc::new(SegQueue::new()), .map(|_| CachePadded::new(TaskSlot::default()))
wakers: HashMap::new(), .collect(),
task_queue: Arc::new(TaskQueue::new(max_tasks)),
max_tasks,
} }
} }
pub fn spawn(&mut self, future: impl Future<Output = ()> + Send + 'static) { pub fn spawn(&mut self, future: impl Future<Output = ()> + Send + 'static) -> Result<(), ()> {
let task_id = TaskId(self.tasks.insert(Task::new(future))); let task_id = self.task_queue.allocate_task_id().ok_or(())?;
self.queue.push(task_id); self.tasks[task_id.0].lock.replace(Task::new(future));
self.task_queue.push(task_id);
Ok(())
} }
pub fn run(&mut self) { pub fn run(&mut self) {
let mut task_batch = Vec::with_capacity(16);
loop { loop {
while let Some(id) = self.queue.pop() { self.task_queue.batch_pop(&mut task_batch);
if let Some(task) = self.tasks.get_mut(id.0) { if task_batch.is_empty() {
let waker = self.wakers.entry(id).or_insert_with(|| { if self.task_queue.is_empty() {
Waker::from(Arc::new(TaskWaker { break;
id,
queue: Arc::clone(&self.queue),
}))
});
let mut cx = Context::from_waker(waker);
if let Poll::Ready(()) = task.poll(&mut cx) {
self.tasks.remove(id.0);
self.wakers.remove(&id);
}
} else { } else {
panic!("Attempted to get task from empty slot: {}", id.0); continue;
} }
} }
if self.tasks.is_empty() { for id in task_batch.drain(..) {
break; let task_slot = &mut self.tasks[id.0];
let mut task_opt = task_slot.lock.take();
if let Some(task) = &mut task_opt {
let waker = task_slot.waker.get_or_insert_with(|| {
Arc::new(TaskWaker::new(id, Arc::clone(&self.task_queue)))
});
let waker = Waker::from(Arc::clone(waker));
let mut cx = Context::from_waker(&waker);
if let Poll::Ready(()) = task.poll(&mut cx) {
task_slot.waker = None;
self.task_queue.free_task_id(id);
} else {
task_slot.lock.replace(task_opt.take().unwrap());
}
}
} }
} }
} }
} }
#[derive(Default)]
struct TaskSlot {
lock: Option<Task>,
waker: Option<Arc<TaskWaker>>,
}
struct Task { struct Task {
future: Pin<Box<dyn Future<Output = ()> + Send>>, future: Pin<Box<dyn Future<Output = ()> + Send>>,
} }
impl Task { impl Task {
#[inline(always)]
pub fn new(future: impl Future<Output = ()> + Send + 'static) -> Self { pub fn new(future: impl Future<Output = ()> + Send + 'static) -> Self {
log::trace!("New task scheduled");
Self { Self {
future: Box::pin(future), future: Box::pin(future),
} }
} }
#[inline(always)]
fn poll(&mut self, cx: &mut Context) -> Poll<()> { fn poll(&mut self, cx: &mut Context) -> Poll<()> {
self.future.as_mut().poll(cx) self.future.as_mut().poll(cx)
} }
} }
#[derive(Hash, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
struct TaskId(usize); struct TaskId(usize);
struct TaskWaker { struct TaskWaker {
id: TaskId, id: TaskId,
queue: Arc<SegQueue<TaskId>>, task_queue: Arc<TaskQueue>,
}
impl TaskWaker {
#[inline(always)]
pub fn new(id: TaskId, task_queue: Arc<TaskQueue>) -> Self {
Self { id, task_queue }
}
} }
impl Wake for TaskWaker { impl Wake for TaskWaker {
#[inline(always)]
fn wake(self: Arc<Self>) { fn wake(self: Arc<Self>) {
log::trace!("Woke Task-{:?}", self.id); self.task_queue.push(self.id);
self.queue.push(self.id);
} }
#[inline(always)]
fn wake_by_ref(self: &Arc<Self>) { fn wake_by_ref(self: &Arc<Self>) {
self.queue.push(self.id); self.task_queue.push(self.id);
}
}
#[derive(Default)]
struct TaskQueue {
queue: SegQueue<TaskId>,
next_task: AtomicUsize,
max_tasks: usize,
free_tasks: SegQueue<TaskId>,
}
impl TaskQueue {
fn new(max_tasks: usize) -> Self {
Self {
queue: SegQueue::new(),
next_task: AtomicUsize::new(0),
max_tasks,
free_tasks: SegQueue::new(),
}
}
fn allocate_task_id(&self) -> Option<TaskId> {
self.free_tasks.pop().or_else(|| {
let id = self.next_task.fetch_add(1, Ordering::Relaxed);
if id < self.max_tasks {
Some(TaskId(id))
} else {
None
}
})
}
#[inline(always)]
fn free_task_id(&self, id: TaskId) {
self.free_tasks.push(id);
}
#[inline(always)]
fn push(&self, id: TaskId) {
self.queue.push(id);
}
#[inline(always)]
fn batch_pop(&self, output: &mut Vec<TaskId>) {
while let Some(id) = self.queue.pop() {
output.push(id);
if output.len() >= output.capacity() {
break;
}
}
}
#[inline(always)]
fn is_empty(&self) -> bool {
self.queue.is_empty()
} }
} }

View file

@ -5,7 +5,18 @@ edition = "2021"
[dependencies] [dependencies]
str-reader = "0.1" str-reader = "0.1"
derive_more = { version = "1", features = ["full"] } derive_more = { version = "1", default-features = false, features = [
"add",
"add_assign",
"constructor",
"display",
"from",
"into",
"mul",
"mul_assign",
"not",
"sum",
] }
error-stack = "0.5" error-stack = "0.5"
fatfs = "0.3" fatfs = "0.3"
toml = "0.8" toml = "0.8"

View file

@ -1,4 +1,4 @@
#![allow(unused)] // #![allow(unused)]
mod dev; mod dev;
@ -195,7 +195,7 @@ TERM_BACKDROP={}
let modules = value.get_mut("modules").unwrap().as_table_mut().unwrap(); let modules = value.get_mut("modules").unwrap().as_table_mut().unwrap();
// let mut real_modules = modules.clone(); // let mut real_modules = modules.clone();
modules.into_iter().for_each(|(key, value)| { modules.into_iter().for_each(|(_, value)| {
if value.is_table() { if value.is_table() {
let path = get_path_without_boot_prefix( let path = get_path_without_boot_prefix(
value.get("path").expect("You must have `path` as a value"), value.get("path").expect("You must have `path` as a value"),
@ -244,7 +244,7 @@ TERM_BACKDROP={}
let bootdir = fs.root_dir().create_dir("efi")?.create_dir("boot")?; let bootdir = fs.root_dir().create_dir("efi")?.create_dir("boot")?;
let mut f = fs.root_dir().create_file("limine.cfg")?; let mut f = fs.root_dir().create_file("limine.cfg")?;
let a = f.write(limine_str.as_bytes())?; let _ = f.write(limine_str.as_bytes())?;
drop(f); drop(f);
io::copy( io::copy(
@ -446,6 +446,7 @@ enum Target {
Aarch64, Aarch64,
} }
#[allow(unused)]
#[derive(Debug, Display)] #[derive(Debug, Display)]
enum Error { enum Error {
#[display("Failed to build the kernel")] #[display("Failed to build the kernel")]
@ -466,6 +467,7 @@ enum Error {
impl Context for Error {} impl Context for Error {}
#[allow(dead_code)]
fn fmt_qemu_err(e: Option<i32>) -> impl Display { fn fmt_qemu_err(e: Option<i32>) -> impl Display {
struct W(Option<i32>); struct W(Option<i32>);
impl Display for W { impl Display for W {

View file

@ -23,7 +23,7 @@ fb_width := 1024
fb_height := 768 fb_height := 768
fb_pixels := fb_width * fb_height fb_pixels := fb_width * fb_height
fb_bytes := fb_pixels << 2 fb_bytes := fb_pixels << 2
copy_pixels := math.min(0x1800, fb_bytes) >> 2 copy_pixels := math.min(0xC000, fb_bytes) >> 2
partitions := fb_pixels / copy_pixels partitions := fb_pixels / copy_pixels
total_pages := 1 + fb_bytes >> 12 total_pages := 1 + fb_bytes >> 12
@ -51,12 +51,22 @@ create_back_buffer := fn(): ^Color {
clear := fn(color: Color): void { clear := fn(color: Color): void {
n := 0 n := 0
loop if n >= copy_pixels break else { loop if n == 512 break else {
*(back_buffer + n) = color *(back_buffer + n) = color
n += 1 n += 1
} }
n = 1 n = 1
loop if n >= partitions break else { loop if n == 8 break else {
*(@as(^[Color; 512], @bitcast(back_buffer)) + n) = *@as(^[Color; 512], @bitcast(back_buffer))
n += 1
}
n = 1
loop if n == copy_pixels >> 12 break else {
*(@as(^[Color; 4096], @bitcast(back_buffer)) + n) = *@as(^[Color; 4096], @bitcast(back_buffer))
n += 1
}
n = 1
loop if n == partitions break else {
*(@as(^[Color; copy_pixels], @bitcast(back_buffer)) + n) = *@as(^[Color; copy_pixels], @bitcast(back_buffer)) *(@as(^[Color; copy_pixels], @bitcast(back_buffer)) + n) = *@as(^[Color; copy_pixels], @bitcast(back_buffer))
n += 1 n += 1
} }
@ -65,7 +75,7 @@ clear := fn(color: Color): void {
sync := fn(): void { sync := fn(): void {
n := 0 n := 0
loop if n >= partitions break else { loop if n == partitions break else {
*(@as(^[Color; copy_pixels], @bitcast(front_buffer)) + n) = *(@as(^[Color; copy_pixels], @bitcast(back_buffer)) + n) *(@as(^[Color; copy_pixels], @bitcast(front_buffer)) + n) = *(@as(^[Color; copy_pixels], @bitcast(back_buffer)) + n)
n += 1 n += 1
} }

View file

@ -1,4 +1,4 @@
.{example} := @use("./examples/lines.hb") .{example} := @use("./examples/amogus.hb")
main := fn(): void { main := fn(): void {
@inline(example) @inline(example)