From 6d31f4db29228e3e876c9a355ff7f4f2b3603b71 Mon Sep 17 00:00:00 2001 From: Able Date: Wed, 5 Jan 2022 07:10:52 -0600 Subject: [PATCH] fix up wasm-sys and implement experimental futex --- ableos/Cargo.lock | 2 +- ableos/Cargo.toml | 2 +- ableos/notes/mouse.md | 0 ableos/src/driver_traits/mouse.rs | 15 ++- ableos/src/experiments/futex.rs | 66 +++++++++++ ableos/src/experiments/mod.rs | 1 + ableos/src/wasm/mod.rs | 182 +++++++++++++++--------------- 7 files changed, 173 insertions(+), 95 deletions(-) create mode 100644 ableos/notes/mouse.md create mode 100644 ableos/src/experiments/futex.rs diff --git a/ableos/Cargo.lock b/ableos/Cargo.lock index fc5b4e7c..09b268de 100644 --- a/ableos/Cargo.lock +++ b/ableos/Cargo.lock @@ -59,7 +59,7 @@ checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" [[package]] name = "externc-libm" version = "0.1.0" -source = "git+https://github.com/HaruxOS/externc-libm#ad2865a706fd46d829550ed4cdfa4126f2c81e19" +source = "git+ssh://root@git.ablecorp.us:20/able/externc-libm.git#0781df85c094bcd7e5ef7505e9c5cc6317eeda75" dependencies = [ "libm", ] diff --git a/ableos/Cargo.toml b/ableos/Cargo.toml index bbe83662..5ca3e3b5 100644 --- a/ableos/Cargo.toml +++ b/ableos/Cargo.toml @@ -41,7 +41,7 @@ features = ["spin_no_std"] version = "1.0" [dependencies.externc-libm] -git = "https://github.com/HaruxOS/externc-libm" +git = "ssh://root@git.ablecorp.us:20/able/externc-libm.git" [target.'cfg(target_arch = "x86_64")'.dependencies] bootloader = { version = "0.9.8", features = ["map_physical_memory"] } diff --git a/ableos/notes/mouse.md b/ableos/notes/mouse.md new file mode 100644 index 00000000..e69de29b diff --git a/ableos/src/driver_traits/mouse.rs b/ableos/src/driver_traits/mouse.rs index 892a57e7..ec624dcb 100644 --- a/ableos/src/driver_traits/mouse.rs +++ b/ableos/src/driver_traits/mouse.rs @@ -1,6 +1,15 @@ -pub enum PS2MouseButton { - LeftMB, - RightMB, + + +// TODO: Bitmasking +pub enum Mouse { + Button1, + Button2, + Button3, + Button4, + Button5, + X(i8), + Y(i8), + Wheel(i8), } pub trait PS2Mouse { diff --git a/ableos/src/experiments/futex.rs b/ableos/src/experiments/futex.rs new file mode 100644 index 00000000..70412a39 --- /dev/null +++ b/ableos/src/experiments/futex.rs @@ -0,0 +1,66 @@ +use core::time::Duration; + +use alloc::vec::Vec; + +use crate::scheduler::ThreadID; + +// pub struct Duration {} + +pub struct AtomicU32(u32); + +impl AtomicU32 { + //if v != current value + pub fn wait(&self, _v: u32) { + todo!(); + } + + pub fn wait_timeout(&self, _v: u32, _timeout: Duration) -> bool { + todo!(); + } + pub fn wake_single(&self) { + todo!(); + } + pub fn wake_all(&self) { + todo!(); + } +} +/* + +SUPER HANDWAVEY +YOU WILL NEED LOCKING THAT I DIDNT WRITE OUT (you == zuurr#9735) + +// all the red is by design +pub fn futex_wait(atom: &AtomicU32, value: usize, current_thread: ThreadID) { + let address = atomic as *const _ as usize; + let waiters = waiters_for(address); // Hold lock + waiters.add(current_thread); + if self.load() == value { + current_thread.sleep(); + } else { + waiters.remove(current_thread); + } +} + +pub fn futex_wake(atom: &AtomicU32, threads_to_wake: usize) { + let address = atomic as *const _ as usize; + let waiters = waiters_for(address); + for waiting_thread in waiters.into_iter().take(threads_to_wake) { + waiting_thread.wake() + } +} + +*/ + +struct FutexWaitlist { + address: u8, + data: Vec, +} + +impl FutexWaitlist { + pub fn remove(&mut self) { + todo!(); + } + pub fn add(&mut self) { + todo!(); + } +} diff --git a/ableos/src/experiments/mod.rs b/ableos/src/experiments/mod.rs index 6149dba8..194bfc32 100644 --- a/ableos/src/experiments/mod.rs +++ b/ableos/src/experiments/mod.rs @@ -10,5 +10,6 @@ pub mod virtual_memory; pub mod kinfo; pub mod mail; +pub mod futex; pub mod info; pub const BANNER: &str = include_str!("banner.txt"); diff --git a/ableos/src/wasm/mod.rs b/ableos/src/wasm/mod.rs index a0ad353c..96f06f81 100644 --- a/ableos/src/wasm/mod.rs +++ b/ableos/src/wasm/mod.rs @@ -2,114 +2,116 @@ use alloc::string::String; use wasmi::TrapKind; use { - alloc::format, - wasm_sys::SysCall, - wasmi::{ - Error, Externals, FuncInstance, FuncRef, ImportsBuilder, ModuleImportResolver, - ModuleInstance, RuntimeArgs, RuntimeValue, Signature, Trap, ValueType, - }, + alloc::format, + wasm_sys::SysCall, + wasmi::{ + Error, Externals, FuncInstance, FuncRef, ImportsBuilder, ModuleImportResolver, + ModuleInstance, RuntimeArgs, RuntimeValue, Signature, Trap, ValueType, + }, }; mod wasm_sys; struct HostFunctions; impl HostFunctions { - fn check_signature(&self, index: usize, signature: &Signature) -> bool { - let (params, ret_ty): (&[ValueType], Option) = match index.into() { - SysCall::KILL => (&[], None), - SysCall::EMPTY => (&[], None), - _ => return false, - }; - signature.params() == params && signature.return_type() == ret_ty - } + fn check_signature(&self, index: usize, signature: &Signature) -> bool { + let (params, ret_ty): (&[ValueType], Option) = match index.into() { + SysCall::KILL => (&[], None), + SysCall::EMPTY => (&[], None), + _ => return false, + }; + signature.params() == params && signature.return_type() == ret_ty + } } impl Externals for HostFunctions { - fn invoke_index( - &mut self, - index: usize, - args: RuntimeArgs, - ) -> Result, Trap> { - match index.into() { - // Take in one arg discard the rest - SysCall::KILL => { - info!("Program run at runtime called a system call"); - debug!("Runtime arguments: {:?}", args); - Ok(None) - } - // Do nothing - SysCall::EMPTY => Ok(None), - SysCall::EXIT => Ok(None), - SysCall::CONSOLE_RESET => Ok(None), - SysCall::CONSOLE_IN => { - info!("In"); - Ok(None) - } + fn invoke_index( + &mut self, + index: usize, + args: RuntimeArgs, + ) -> Result, Trap> { + match index.into() { + // Take in one arg discard the rest + SysCall::KILL => { + info!("Program run at runtime called a system call"); + debug!("Runtime arguments: {:?}", args); + Ok(None) + } + // Do nothing + SysCall::EMPTY => Ok(None), + SysCall::EXIT => Ok(None), + SysCall::CONSOLE_RESET => Ok(None), + SysCall::CONSOLE_IN => { + info!("In"); + Ok(None) + } - SysCall::CONSOLE_OUT => { - // Eventually change this to 2- ptr and len - if args.len() != 1 { - return Err(Trap::new(TrapKind::UnexpectedSignature)); - } - let arg: u64 = args.nth(0); - let buf = unsafe { String::from_utf8_unchecked(arg.to_le_bytes().to_vec()) }; - println!["{}", buf]; - Ok(None) - } - SysCall::CONSOLE_GET_TITLE => Ok(None), - SysCall::CONSOLE_SET_TITLE => Ok(None), - _ => panic!("Unimplemented function at {}", index), - } - } + SysCall::CONSOLE_OUT => { + // Eventually change this to 2- ptr and len + if args.len() != 1 { + return Err(Trap::new(TrapKind::UnexpectedSignature)); + } + let arg: u64 = args.nth(0); + let buf = unsafe { String::from_utf8_unchecked(arg.to_le_bytes().to_vec()) }; + println!["helllooooooo{}", buf]; + Ok(None) + } + SysCall::CONSOLE_GET_TITLE => Ok(None), + SysCall::CONSOLE_SET_TITLE => Ok(None), + _ => panic!("Unimplemented function at {}", index), + } + } } impl ModuleImportResolver for HostFunctions { - fn resolve_func(&self, field_name: &str, signature: &Signature) -> Result { - let index = match field_name { - "kill" => SysCall::KILL as usize, - "empty" => SysCall::EMPTY as usize, - "exit" => SysCall::EXIT as usize, - _ => { - return Err(Error::Instantiation(format!( - "Export {} not found", - field_name - ))) - } - }; + fn resolve_func(&self, field_name: &str, signature: &Signature) -> Result { + let index = match field_name { + "kill" => SysCall::KILL as usize, + "empty" => SysCall::EMPTY as usize, + "exit" => SysCall::EXIT as usize, + "console_out" => SysCall::CONSOLE_OUT as usize, + _ => { + return Err(Error::Instantiation(format!( + "Export {} not found", + field_name + ))) + } + }; - if !self.check_signature(index, signature) { - return Err(Error::Instantiation(format!( - "Export {} has a bad signature", - field_name - ))); - } + if !self.check_signature(index, signature) { + return Err(Error::Instantiation(format!( + "Export {} has a bad signature", + field_name + ))); + } - Ok(FuncInstance::alloc_host( - Signature::new(&[][..], None), - index, - )) - } + Ok(FuncInstance::alloc_host( + Signature::new(&[][..], None), + index, + )) + } } pub fn evaluate() { - let wasm_binary = include_bytes!("bin/rust.wasm"); + let wasm_binary = include_bytes!("bin/console_out_test.wasm"); - // Load wasm binary and prepare it for instantiation. - let module = wasmi::Module::from_buffer(&wasm_binary).expect("failed to load wasm"); + // Load wasm binary and prepare it for instantiation. + let module = wasmi::Module::from_buffer(&wasm_binary).expect("failed to load wasm"); - let imports = ImportsBuilder::new().with_resolver("env", &HostFunctions); + let imports = ImportsBuilder::new().with_resolver("env", &HostFunctions); - // Instantiate a module with empty imports and - // assert that there is no `start` function. - let instance = ModuleInstance::new(&module, &imports) - .expect("failed to instantiate wasm module") - .assert_no_start(); + // Instantiate a module with empty imports and + // assert that there is no `start` function. + let instance = ModuleInstance::new(&module, &imports) + // .expect("failed to instantiate wasm module") + .unwrap() + .assert_no_start(); - // Finally, invoke the exported function "test" with no parameters - // and empty external function executor. - let result: i32 = instance - .invoke_export("_start", &[], &mut HostFunctions) - .expect("failed to execute export") - .unwrap() - .try_into() - .unwrap(); + // Finally, invoke the exported function "test" with no parameters + // and empty external function executor. + let result: i32 = instance + .invoke_export("_start", &[], &mut HostFunctions) + .expect("failed to execute export") + .unwrap() + .try_into() + .unwrap(); - println!("{:?}", result); + println!("{:?}", result); }