forked from AbleOS/ableos
a touch more fiddling
This commit is contained in:
parent
fd155ea26a
commit
3b95371c41
53
Cargo.lock
generated
53
Cargo.lock
generated
|
@ -166,15 +166,6 @@ dependencies = [
|
|||
"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]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.7"
|
||||
|
@ -211,7 +202,6 @@ version = "1.0.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22"
|
||||
dependencies = [
|
||||
"convert_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
|
@ -391,17 +381,17 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "hbbytecode"
|
||||
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]]
|
||||
name = "hbbytecode"
|
||||
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]]
|
||||
name = "hblang"
|
||||
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 = [
|
||||
"hbvm 0.1.0 (git+https://git.ablecorp.us/AbleOS/holey-bytes.git)",
|
||||
]
|
||||
|
@ -409,7 +399,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "hbvm"
|
||||
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 = [
|
||||
"hbbytecode 0.1.0 (git+https://git.ablecorp.us/AbleOS/holey-bytes.git)",
|
||||
]
|
||||
|
@ -417,7 +407,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "hbvm"
|
||||
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 = [
|
||||
"hbbytecode 0.1.0 (git+https://git.ablecorp.us/ableos/holey-bytes)",
|
||||
]
|
||||
|
@ -507,9 +497,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "hyper-util"
|
||||
version = "0.1.7"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9"
|
||||
checksum = "da62f120a8a37763efb0cf8fdf264b884c7b8b9ac8660b900c8661030c00e6ba"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
|
@ -594,16 +584,14 @@ name = "kernel"
|
|||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"crossbeam-queue",
|
||||
"crossbeam-utils",
|
||||
"derive_more",
|
||||
"embedded-graphics",
|
||||
"hashbrown",
|
||||
"hbvm 0.1.0 (git+https://git.ablecorp.us/ableos/holey-bytes)",
|
||||
"kiam",
|
||||
"limine",
|
||||
"log",
|
||||
"rdrand",
|
||||
"sbi",
|
||||
"slab",
|
||||
"spin",
|
||||
"uart_16550",
|
||||
"versioning",
|
||||
|
@ -613,12 +601,6 @@ dependencies = [
|
|||
"xml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kiam"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb0fc32485e41ae5e9dedd1442f36dec998431adc9f321224c2c5d645f38fdcb"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.5.0"
|
||||
|
@ -907,15 +889,6 @@ dependencies = [
|
|||
"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]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.4"
|
||||
|
@ -1046,9 +1019,9 @@ checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0"
|
|||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
version = "0.102.7"
|
||||
version = "0.102.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84678086bd54edf2b415183ed7a94d0efb049f1b646a33e22a36f3794be6ae56"
|
||||
checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
|
@ -1389,12 +1362,6 @@ dependencies = [
|
|||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.5"
|
||||
|
|
|
@ -9,13 +9,11 @@ embedded-graphics = "0.8"
|
|||
hbvm.git = "https://git.ablecorp.us/ableos/holey-bytes"
|
||||
log = "0.4"
|
||||
spin = "0.9"
|
||||
uart_16550 = "0.3"
|
||||
slab = { version = "0.4", default-features = false }
|
||||
uart_16550 = { version = "0.3", features = ["nightly"] }
|
||||
xml.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"
|
||||
hashbrown = "0.14"
|
||||
kiam = "0.1"
|
||||
hashbrown = { version = "0.14", features = ["nightly"] }
|
||||
|
||||
[dependencies.limine]
|
||||
version = "0.1"
|
||||
|
@ -24,7 +22,11 @@ version = "0.1"
|
|||
[dependencies.crossbeam-queue]
|
||||
version = "0.3"
|
||||
default-features = false
|
||||
features = ["alloc"]
|
||||
features = ["alloc", "nightly"]
|
||||
|
||||
[dependencies.crossbeam-utils]
|
||||
version = "0.8"
|
||||
default-features = false
|
||||
|
||||
# [dependencies.clparse]
|
||||
# git = "https://git.ablecorp.us/ableos/ableos_userland"
|
||||
|
@ -51,9 +53,6 @@ features = [
|
|||
x86_64 = "0.15"
|
||||
x2apic = "0.4"
|
||||
virtio-drivers = "0.7"
|
||||
# rdrand = "*"
|
||||
rdrand = { version = "0.8", default-features = false }
|
||||
|
||||
|
||||
[target.'cfg(target_arch = "riscv64")'.dependencies]
|
||||
sbi = "0.2.0"
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
use core::num;
|
||||
|
||||
use alloc::boxed::Box;
|
||||
use spin::{Mutex, Once};
|
||||
use crate::memory::{MemoryManager, PhysicalAddress, VirtualAddress};
|
||||
use {
|
||||
crate::memory::{MemoryManager, PhysicalAddress, VirtualAddress},
|
||||
alloc::boxed::Box,
|
||||
spin::{Mutex, Once},
|
||||
};
|
||||
|
||||
use super::PAGE_SIZE;
|
||||
|
||||
|
@ -28,7 +30,7 @@ impl PageSize {
|
|||
}
|
||||
|
||||
pub struct PageTable {
|
||||
entries: [PageEntry; 512]
|
||||
entries: [PageEntry; 512],
|
||||
}
|
||||
|
||||
impl PageTable {
|
||||
|
@ -72,8 +74,14 @@ impl PageTable {
|
|||
/// flags MUST include one or more of the following:
|
||||
/// Read, Write, Execute
|
||||
/// The valid bit automatically gets added
|
||||
pub fn map(&mut self, vaddr: VirtualAddress, paddr: PhysicalAddress, flags: PageEntryFlags, page_size: PageSize) {
|
||||
assert!(flags as usize & 0xe != 0);
|
||||
pub fn map(
|
||||
&mut self,
|
||||
vaddr: VirtualAddress,
|
||||
paddr: PhysicalAddress,
|
||||
flags: PageEntryFlags,
|
||||
page_size: PageSize,
|
||||
) {
|
||||
assert!(flags as usize & 0xE != 0);
|
||||
|
||||
let vpn = vaddr.vpns();
|
||||
let ppn = paddr.ppns();
|
||||
|
@ -91,7 +99,7 @@ impl PageTable {
|
|||
}
|
||||
|
||||
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.
|
||||
|
@ -105,14 +113,24 @@ impl PageTable {
|
|||
}
|
||||
|
||||
/// 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}");
|
||||
self.map(addr.as_addr().into(), addr, flags, page_size);
|
||||
}
|
||||
|
||||
/// Identity maps a range of contiguous memory
|
||||
/// 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}");
|
||||
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;
|
||||
|
@ -142,7 +160,7 @@ impl PageTable {
|
|||
}
|
||||
|
||||
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
|
||||
|
@ -182,7 +200,7 @@ pub enum PageEntryFlags {
|
|||
Global = 1 << 5,
|
||||
Access = 1 << 6,
|
||||
Dirty = 1 << 7,
|
||||
|
||||
|
||||
// for convenience
|
||||
ReadWrite = Self::Read as usize | Self::Write as usize,
|
||||
ReadExecute = Self::Read as usize | Self::Execute as usize,
|
||||
|
@ -228,7 +246,7 @@ impl PageEntry {
|
|||
}
|
||||
|
||||
fn addr(&self) -> PhysicalAddress {
|
||||
((self.entry() as usize & !0x3ff) << 2).into()
|
||||
((self.entry() as usize & !0x3FF) << 2).into()
|
||||
}
|
||||
|
||||
fn destroy(&mut self) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
mod cpuid;
|
||||
|
@ -189,62 +191,43 @@ unsafe extern "C" fn start() -> ! {
|
|||
)
|
||||
}
|
||||
|
||||
use crossbeam_utils::Backoff;
|
||||
|
||||
/// Spin loop
|
||||
pub fn spin_loop() -> ! {
|
||||
let backoff = Backoff::new();
|
||||
loop {
|
||||
x86_64::instructions::hlt();
|
||||
core::hint::spin_loop();
|
||||
// x86_64::instructions::hlt();
|
||||
backoff.spin()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hardware_random_u64() -> u64 {
|
||||
use {log::trace, rdrand::RdRand};
|
||||
let gen = RdRand::new();
|
||||
match gen {
|
||||
Ok(gen) => {
|
||||
let ret = gen.try_next_u64().unwrap();
|
||||
trace!("Random {}", ret);
|
||||
return ret;
|
||||
}
|
||||
Err(_) => {
|
||||
let mut out: u64 = 0;
|
||||
match unsafe { _rdrand64_step(&mut out) } {
|
||||
1 => out,
|
||||
_ => {
|
||||
warn!("RDRand not supported.");
|
||||
// Try rdseed
|
||||
let gen = RdSeed::new();
|
||||
match gen {
|
||||
Ok(gen) => {
|
||||
let ret = gen.try_next_u64().unwrap();
|
||||
trace!("Random {}", ret);
|
||||
return ret;
|
||||
}
|
||||
Err(_) => {
|
||||
panic!("Neither RDRand or RDSeed are supported")
|
||||
}
|
||||
match unsafe { _rdseed64_step(&mut out) } {
|
||||
1 => out,
|
||||
_ => panic!("Neither RDRand or RDSeed are supported"),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hardware_random_u32() -> u32 {
|
||||
use {log::trace, rdrand::RdRand};
|
||||
let gen = RdRand::new();
|
||||
match gen {
|
||||
Ok(gen) => {
|
||||
let ret = gen.try_next_u32().unwrap();
|
||||
trace!("Random {}", ret);
|
||||
return ret;
|
||||
}
|
||||
Err(_) => {
|
||||
let mut out: u32 = 0;
|
||||
match unsafe { _rdrand32_step(&mut out) } {
|
||||
1 => out,
|
||||
_ => {
|
||||
warn!("RDRand not supported.");
|
||||
// Try rdseed
|
||||
let gen = RdSeed::new();
|
||||
match gen {
|
||||
Ok(gen) => {
|
||||
let ret = gen.try_next_u32().unwrap();
|
||||
trace!("Random {}", ret);
|
||||
return ret;
|
||||
}
|
||||
Err(_) => {
|
||||
panic!("Neither RDRand or RDSeed are supported")
|
||||
}
|
||||
match unsafe { _rdseed32_step(&mut out) } {
|
||||
1 => out,
|
||||
_ => panic!("Neither RDRand or RDSeed are supported"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ impl<'p> Drop for ExecThread<'p> {
|
|||
|
||||
impl<'p> Future for ExecThread<'p> {
|
||||
type Output = Result<(), VmRunError>;
|
||||
|
||||
#[inline(always)]
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
match self.vm.run() {
|
||||
Err(err) => {
|
||||
|
@ -110,10 +110,12 @@ impl HandlePageFault for PageFaultHandler {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
const fn stack_layout() -> Layout {
|
||||
unsafe { Layout::from_size_align_unchecked(STACK_SIZE, 4096) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn allocate_stack() -> NonNull<u8> {
|
||||
let layout = stack_layout();
|
||||
NonNull::new(unsafe { alloc::alloc::alloc_zeroed(layout) })
|
||||
|
|
|
@ -66,7 +66,7 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
|
|||
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();
|
||||
unsafe {
|
||||
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);
|
||||
|
||||
executor.spawn(async move {
|
||||
let mut thr = ExecThread::new(&module.bytes, Address::new(0));
|
||||
if cmd_len > 0 {
|
||||
thr.set_arguments(cmd.as_bytes().as_ptr() as u64, cmd_len);
|
||||
}
|
||||
|
||||
if let Err(e) = thr.await {
|
||||
log::error!("{e:?}");
|
||||
}
|
||||
});
|
||||
executor
|
||||
.spawn(async move {
|
||||
let mut thr = ExecThread::new(&module.bytes, Address::new(0));
|
||||
if cmd_len > 0 {
|
||||
thr.set_arguments(cmd.as_bytes().as_ptr() as u64, cmd_len);
|
||||
}
|
||||
if let Err(e) = thr.await {
|
||||
log::error!("{e:?}");
|
||||
}
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
info!("Random number: {}", hardware_random_u64());
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
#![allow(unused)]
|
||||
|
||||
use {
|
||||
alloc::{boxed::Box, sync::Arc, task::Wake},
|
||||
core::{
|
||||
future::Future,
|
||||
pin::Pin,
|
||||
sync::atomic::{AtomicUsize, Ordering},
|
||||
task::{Context, Poll, Waker},
|
||||
},
|
||||
crossbeam_queue::SegQueue,
|
||||
hashbrown::HashMap,
|
||||
slab::Slab,
|
||||
spin::Mutex,
|
||||
crossbeam_utils::CachePadded,
|
||||
};
|
||||
|
||||
use alloc::vec::Vec;
|
||||
|
||||
pub fn yield_now() -> impl Future<Output = ()> {
|
||||
struct YieldNow(bool);
|
||||
impl Future for YieldNow {
|
||||
type Output = ();
|
||||
|
||||
#[inline(always)]
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
if self.0 {
|
||||
Poll::Ready(())
|
||||
|
@ -34,86 +34,168 @@ pub fn yield_now() -> impl Future<Output = ()> {
|
|||
|
||||
#[derive(Default)]
|
||||
pub struct Executor {
|
||||
tasks: Slab<Task>,
|
||||
queue: Arc<SegQueue<TaskId>>,
|
||||
wakers: HashMap<TaskId, Waker>, // Keeping HashMap as it is more performant for lookups.
|
||||
tasks: Vec<CachePadded<TaskSlot>>,
|
||||
task_queue: Arc<TaskQueue>,
|
||||
max_tasks: usize,
|
||||
}
|
||||
|
||||
impl Executor {
|
||||
pub fn new() -> Self {
|
||||
pub fn new(max_tasks: usize) -> Self {
|
||||
Self {
|
||||
tasks: Slab::new(),
|
||||
queue: Arc::new(SegQueue::new()),
|
||||
wakers: HashMap::new(),
|
||||
tasks: (0..max_tasks)
|
||||
.map(|_| CachePadded::new(TaskSlot::default()))
|
||||
.collect(),
|
||||
task_queue: Arc::new(TaskQueue::new(max_tasks)),
|
||||
max_tasks,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn spawn(&mut self, future: impl Future<Output = ()> + Send + 'static) {
|
||||
let task_id = TaskId(self.tasks.insert(Task::new(future)));
|
||||
self.queue.push(task_id);
|
||||
pub fn spawn(&mut self, future: impl Future<Output = ()> + Send + 'static) -> Result<(), ()> {
|
||||
let task_id = self.task_queue.allocate_task_id().ok_or(())?;
|
||||
self.tasks[task_id.0].lock.replace(Task::new(future));
|
||||
self.task_queue.push(task_id);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run(&mut self) {
|
||||
let mut task_batch = Vec::with_capacity(16);
|
||||
|
||||
loop {
|
||||
while let Some(id) = self.queue.pop() {
|
||||
if let Some(task) = self.tasks.get_mut(id.0) {
|
||||
let waker = self.wakers.entry(id).or_insert_with(|| {
|
||||
Waker::from(Arc::new(TaskWaker {
|
||||
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);
|
||||
}
|
||||
self.task_queue.batch_pop(&mut task_batch);
|
||||
if task_batch.is_empty() {
|
||||
if self.task_queue.is_empty() {
|
||||
break;
|
||||
} else {
|
||||
panic!("Attempted to get task from empty slot: {}", id.0);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if self.tasks.is_empty() {
|
||||
break;
|
||||
for id in task_batch.drain(..) {
|
||||
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 {
|
||||
future: Pin<Box<dyn Future<Output = ()> + Send>>,
|
||||
}
|
||||
|
||||
impl Task {
|
||||
#[inline(always)]
|
||||
pub fn new(future: impl Future<Output = ()> + Send + 'static) -> Self {
|
||||
log::trace!("New task scheduled");
|
||||
Self {
|
||||
future: Box::pin(future),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn poll(&mut self, cx: &mut Context) -> Poll<()> {
|
||||
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 TaskWaker {
|
||||
id: TaskId,
|
||||
queue: Arc<SegQueue<TaskId>>,
|
||||
id: 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 {
|
||||
#[inline(always)]
|
||||
fn wake(self: Arc<Self>) {
|
||||
log::trace!("Woke Task-{:?}", self.id);
|
||||
self.queue.push(self.id);
|
||||
self.task_queue.push(self.id);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,18 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
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"
|
||||
fatfs = "0.3"
|
||||
toml = "0.8"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#![allow(unused)]
|
||||
// #![allow(unused)]
|
||||
|
||||
mod dev;
|
||||
|
||||
|
@ -195,7 +195,7 @@ TERM_BACKDROP={}
|
|||
let modules = value.get_mut("modules").unwrap().as_table_mut().unwrap();
|
||||
// let mut real_modules = modules.clone();
|
||||
|
||||
modules.into_iter().for_each(|(key, value)| {
|
||||
modules.into_iter().for_each(|(_, value)| {
|
||||
if value.is_table() {
|
||||
let path = get_path_without_boot_prefix(
|
||||
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 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);
|
||||
|
||||
io::copy(
|
||||
|
@ -446,6 +446,7 @@ enum Target {
|
|||
Aarch64,
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
#[derive(Debug, Display)]
|
||||
enum Error {
|
||||
#[display("Failed to build the kernel")]
|
||||
|
@ -466,6 +467,7 @@ enum Error {
|
|||
|
||||
impl Context for Error {}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn fmt_qemu_err(e: Option<i32>) -> impl Display {
|
||||
struct W(Option<i32>);
|
||||
impl Display for W {
|
||||
|
|
|
@ -23,7 +23,7 @@ fb_width := 1024
|
|||
fb_height := 768
|
||||
fb_pixels := fb_width * fb_height
|
||||
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
|
||||
total_pages := 1 + fb_bytes >> 12
|
||||
|
||||
|
@ -51,12 +51,22 @@ create_back_buffer := fn(): ^Color {
|
|||
|
||||
clear := fn(color: Color): void {
|
||||
n := 0
|
||||
loop if n >= copy_pixels break else {
|
||||
loop if n == 512 break else {
|
||||
*(back_buffer + n) = color
|
||||
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))
|
||||
n += 1
|
||||
}
|
||||
|
@ -65,7 +75,7 @@ clear := fn(color: Color): void {
|
|||
|
||||
sync := fn(): void {
|
||||
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)
|
||||
n += 1
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.{example} := @use("./examples/lines.hb")
|
||||
.{example} := @use("./examples/amogus.hb")
|
||||
|
||||
main := fn(): void {
|
||||
@inline(example)
|
||||
|
|
Loading…
Reference in a new issue