From d777b8f4ab1dec131248c87a5dded8a66912dc37 Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Sun, 26 Jan 2025 00:05:55 -0800 Subject: [PATCH] Move yunq to new thread spawn and remove old one. --- rust/lib/mammoth/src/thread.rs | 38 -------------------------- rust/lib/yunq/src/server.rs | 9 ++++++ rust/sys/denali/src/ahci/controller.rs | 4 +-- rust/sys/yellowstone/src/main.rs | 23 +++++++++------- rust/sys/yellowstone/src/server.rs | 18 ++++++------ rust/usr/testbed/src/main.rs | 6 ---- yunq/rust/src/codegen.rs | 11 -------- 7 files changed, 33 insertions(+), 76 deletions(-) diff --git a/rust/lib/mammoth/src/thread.rs b/rust/lib/mammoth/src/thread.rs index 8f74b59..99032be 100644 --- a/rust/lib/mammoth/src/thread.rs +++ b/rust/lib/mammoth/src/thread.rs @@ -5,44 +5,6 @@ use crate::zion; use alloc::boxed::Box; use core::ffi::c_void; -pub type ThreadEntry = fn(*const c_void) -> (); - -#[no_mangle] -extern "C" fn internal_entry_point(thread_ptr: *const Thread, arg1: *const c_void) -> ! { - let thread: &Thread = unsafe { thread_ptr.as_ref().expect("Failed to unwrap thread ref") }; - - (thread.entry)(arg1); - - syscall::thread_exit() -} -// TODO: Add a Drop implementation that kills this thread and drops its capability. -pub struct Thread { - cap: Capability, - // This field only exists to ensure that the entry reference will outlive the thread object - // itself. - entry: ThreadEntry, -} - -impl Thread { - pub fn spawn(entry: ThreadEntry, arg1: *const c_void) -> Result, zion::ZError> { - let proc_cap = Capability::take_copy(unsafe { crate::init::SELF_PROC_CAP })?; - let cap = syscall::thread_create(&proc_cap)?; - let thread = Box::new(Self { cap, entry }); - syscall::thread_start( - &thread.cap, - internal_entry_point as u64, - thread.as_ref() as *const Thread as u64, - arg1 as u64, - )?; - - Ok(thread) - } - - pub fn join(&self) -> Result<(), zion::ZError> { - syscall::thread_wait(&self.cap) - } -} - pub struct JoinHandle { cap: Capability, } diff --git a/rust/lib/yunq/src/server.rs b/rust/lib/yunq/src/server.rs index 49d7276..dcfd03c 100644 --- a/rust/lib/yunq/src/server.rs +++ b/rust/lib/yunq/src/server.rs @@ -2,6 +2,8 @@ use crate::buffer::ByteBuffer; use alloc::vec::Vec; use mammoth::cap::Capability; use mammoth::syscall; +use mammoth::thread; +use mammoth::thread::JoinHandle; use mammoth::zion::z_cap_t; use mammoth::zion::ZError; @@ -50,3 +52,10 @@ pub trait YunqServer { cap_buffer: &mut Vec, ) -> Result; } + +pub fn spawn_server_thread(mut server: T) -> JoinHandle +where + T: YunqServer + Send + 'static, +{ + thread::spawn(move || server.server_loop()) +} diff --git a/rust/sys/denali/src/ahci/controller.rs b/rust/sys/denali/src/ahci/controller.rs index a5ac3ca..a9c998d 100644 --- a/rust/sys/denali/src/ahci/controller.rs +++ b/rust/sys/denali/src/ahci/controller.rs @@ -1,10 +1,8 @@ -use alloc::boxed::Box; use alloc::sync::Arc; -use core::ffi::c_void; use mammoth::sync::Mutex; use mammoth::thread; -use mammoth::{mem::MemoryRegion, thread::Thread, zion::ZError}; +use mammoth::{mem::MemoryRegion, zion::ZError}; use crate::ahci::command::FisType; use crate::ahci::port::{ diff --git a/rust/sys/yellowstone/src/main.rs b/rust/sys/yellowstone/src/main.rs index 18e386f..dbe8c2e 100644 --- a/rust/sys/yellowstone/src/main.rs +++ b/rust/sys/yellowstone/src/main.rs @@ -3,16 +3,16 @@ extern crate alloc; -use alloc::{string::ToString, vec::Vec}; +use alloc::{string::ToString, sync::Arc, vec::Vec}; use mammoth::{ cap::Capability, define_entry, elf, init::{BOOT_FRAMEBUFFER_INFO_VMMO, BOOT_PCI_VMMO}, mem::MemoryRegion, - zion::{z_cap_t, z_err_t, ZError}, + zion::{kZionPerm_All, z_cap_t, z_err_t, ZError}, }; use yellowstone_yunq::YellowstoneServer; -use yunq::server::YunqServer; +use yunq::server::{spawn_server_thread, YunqServer}; mod gpt; mod pci; @@ -40,20 +40,19 @@ extern "C" fn main() -> z_err_t { .expect("Failed to create PCI region"); let fb_region = MemoryRegion::from_cap(Capability::take(unsafe { BOOT_FRAMEBUFFER_INFO_VMMO })) .expect("Failed to create Framebuffer region"); - let context = alloc::rc::Rc::new( + let context = Arc::new( server::YellowstoneServerContext::new(pci_region, fb_region) .expect("Failed to create yellowstone context"), ); let handler = server::YellowstoneServerImpl::new(context.clone()); let server = YellowstoneServer::new(handler).expect("Couldn't create yellowstone server"); - let server_thread = server.run_server().expect("Failed to run server"); + let client_cap = server.create_client_cap().unwrap(); + let server_thread = spawn_server_thread(server); spawn_from_vmmo( unsafe { mammoth::init::BOOT_DENALI_VMMO }, - server - .create_client_cap() - .expect("Failed to create client cap for denali"), + client_cap.duplicate(kZionPerm_All).unwrap(), ) .expect("Failed to spawn denali"); @@ -62,7 +61,7 @@ extern "C" fn main() -> z_err_t { spawn_from_vmmo( unsafe { mammoth::init::BOOT_VICTORIA_FALLS_VMMO }, - server.create_client_cap().unwrap(), + client_cap.duplicate(kZionPerm_All).unwrap(), ) .expect("Failed to spawn victoriafalls"); @@ -87,7 +86,11 @@ extern "C" fn main() -> z_err_t { let path = "/bin/".to_string() + bin_name; let bin_file = victoriafalls::file::File::open(&path).unwrap(); - spawn_from_mem_region(bin_file.memory(), server.create_client_cap().unwrap()).unwrap(); + spawn_from_mem_region( + bin_file.memory(), + client_cap.duplicate(kZionPerm_All).unwrap(), + ) + .unwrap(); } server_thread.join().expect("Failed to join thread"); diff --git a/rust/sys/yellowstone/src/server.rs b/rust/sys/yellowstone/src/server.rs index 5a8ce9c..7daea1f 100644 --- a/rust/sys/yellowstone/src/server.rs +++ b/rust/sys/yellowstone/src/server.rs @@ -1,7 +1,9 @@ use core::cell::RefCell; use alloc::rc::Rc; +use alloc::sync::Arc; use alloc::{collections::BTreeMap, string::String}; +use mammoth::sync::Mutex; use mammoth::{cap::Capability, mem::MemoryRegion, zion::ZError}; use victoriafalls::VFSClient; use yellowstone_yunq::{ @@ -15,7 +17,7 @@ pub struct YellowstoneServerContext { registration_semaphore: mammoth::sync::Semaphore, pci_reader: PciReader, framebuffer_info_region: MemoryRegion, - service_map: RefCell>, + service_map: Mutex>, } impl YellowstoneServerContext { @@ -52,13 +54,13 @@ impl YellowstoneServerContext { registration_semaphore: mammoth::sync::Semaphore::new()?, pci_reader: PciReader::new(pci_region), framebuffer_info_region: fb_region, - service_map: BTreeMap::new().into(), + service_map: Mutex::new(BTreeMap::new()), }) } pub fn wait(&self, service: &str) -> Result<(), ZError> { loop { - match self.service_map.borrow().get(service) { + match self.service_map.lock().get(service) { Some(_) => return Ok(()), None => {} } @@ -68,11 +70,11 @@ impl YellowstoneServerContext { } pub struct YellowstoneServerImpl { - context: Rc, + context: Arc, } impl YellowstoneServerImpl { - pub fn new(context: Rc) -> Self { + pub fn new(context: Arc) -> Self { Self { context } } } @@ -87,7 +89,7 @@ impl YellowstoneServerHandler for YellowstoneServerImpl { self.context .service_map - .borrow_mut() + .lock() .insert(req.endpoint_name, Capability::take(req.endpoint_capability)); self.context.registration_semaphore.signal()?; @@ -95,7 +97,7 @@ impl YellowstoneServerHandler for YellowstoneServerImpl { } fn get_endpoint(&mut self, req: GetEndpointRequest) -> Result { - match self.context.service_map.borrow().get(&req.endpoint_name) { + match self.context.service_map.lock().get(&req.endpoint_name) { Some(cap) => Ok(Endpoint { endpoint: cap.duplicate(Capability::PERMS_ALL)?.release(), }), @@ -122,7 +124,7 @@ impl YellowstoneServerHandler for YellowstoneServerImpl { } fn get_denali(&mut self) -> Result { - match self.context.service_map.borrow().get("denali") { + match self.context.service_map.lock().get("denali") { Some(ep_cap) => crate::gpt::read_gpt(denali::DenaliClient::new( ep_cap.duplicate(Capability::PERMS_ALL).unwrap(), )) diff --git a/rust/usr/testbed/src/main.rs b/rust/usr/testbed/src/main.rs index 91a1913..c782312 100644 --- a/rust/usr/testbed/src/main.rs +++ b/rust/usr/testbed/src/main.rs @@ -37,12 +37,6 @@ pub extern "C" fn main() -> z_err_t { let b = Box::new(1); debug!("Addrs: {:p} {:p}", a, b); - let e: thread::ThreadEntry = |_| { - debug!("Testing 1 2 3"); - }; - let t = thread::Thread::spawn(e, core::ptr::null()).expect("Failed to spawn thread"); - t.join().expect("Failed to wait."); - let x = Box::new(|| 1); debug!("Addr: {:p}", x); debug!("Addr: {:p}", &x); diff --git a/yunq/rust/src/codegen.rs b/yunq/rust/src/codegen.rs index 53560a6..01bf96b 100644 --- a/yunq/rust/src/codegen.rs +++ b/yunq/rust/src/codegen.rs @@ -369,17 +369,6 @@ fn generate_server(interface: &Interface) -> TokenStream { handler, }) } - - pub fn run_server(&self) -> Result, ZError> { - let thread_entry = |server_ptr: *const c_void| { - let server = unsafe { (server_ptr as *mut #server_name).as_mut().expect("Failed to convert to server") }; - server.server_loop(); - }; - thread::Thread::spawn( - thread_entry, - self as *const Self as *const core::ffi::c_void, - ) - } } impl yunq::server::YunqServer for #server_name {