Compare commits

..

No commits in common. "d1b5720abd83dbb1f0e771400db0078036cabd01" and "14585c005c459a0194d2a50f9556c45e42c0e9d8" have entirely different histories.

6 changed files with 75 additions and 175 deletions

View File

@ -1,7 +1,3 @@
use core::cell::UnsafeCell;
use core::ops::Deref;
use core::ops::DerefMut;
use crate::{cap::Capability, syscall, zion::ZError}; use crate::{cap::Capability, syscall, zion::ZError};
pub struct Semaphore { pub struct Semaphore {
@ -21,52 +17,3 @@ impl Semaphore {
syscall::semaphone_signal(&self.cap) syscall::semaphone_signal(&self.cap)
} }
} }
pub struct Mutex<T> {
cap: Capability,
data: UnsafeCell<T>,
}
unsafe impl<T> Sync for Mutex<T> where T: Send {}
pub struct MutexGuard<'a, T> {
mutex: &'a Mutex<T>,
}
unsafe impl<T> Send for MutexGuard<'_, T> where T: Send {}
unsafe impl<T> Sync for MutexGuard<'_, T> where T: Sync {}
impl<T> Deref for MutexGuard<'_, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
unsafe { &*self.mutex.data.get() }
}
}
impl<T> DerefMut for MutexGuard<'_, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { &mut *self.mutex.data.get() }
}
}
impl<T> Mutex<T> {
pub fn new(data: T) -> Mutex<T> {
Mutex {
cap: syscall::mutex_create().unwrap(),
data: UnsafeCell::new(data),
}
}
pub fn lock(&self) -> MutexGuard<T> {
syscall::mutex_lock(&self.cap).unwrap();
MutexGuard { mutex: self }
}
}
impl<T> Drop for MutexGuard<'_, T> {
fn drop(&mut self) {
syscall::mutex_release(&self.mutex.cap).unwrap();
}
}

View File

@ -412,36 +412,6 @@ pub fn reply_port_recv(
Ok((num_bytes, num_caps)) Ok((num_bytes, num_caps))
} }
pub fn mutex_create() -> Result<Capability, ZError> {
let mut mutex_cap: z_cap_t = 0;
syscall(
zion::kZionMutexCreate,
&zion::ZMutexCreateReq {
mutex_cap: &mut mutex_cap,
},
)?;
Ok(Capability::take(mutex_cap))
}
pub fn mutex_lock(mutex_cap: &Capability) -> Result<(), ZError> {
syscall(
zion::kZionMutexLock,
&zion::ZMutexLockReq {
mutex_cap: mutex_cap.raw(),
},
)
}
pub fn mutex_release(mutex_cap: &Capability) -> Result<(), ZError> {
syscall(
zion::kZionMutexRelease,
&zion::ZMutexReleaseReq {
mutex_cap: mutex_cap.raw(),
},
)
}
pub fn semaphore_create() -> Result<Capability, ZError> { pub fn semaphore_create() -> Result<Capability, ZError> {
let mut sem_cap: z_cap_t = 0; let mut sem_cap: z_cap_t = 0;
syscall( syscall(

View File

@ -42,43 +42,3 @@ impl Thread {
syscall::thread_wait(&self.cap) syscall::thread_wait(&self.cap)
} }
} }
pub struct JoinHandle {
cap: Capability,
}
impl JoinHandle {
pub fn join(&self) -> Result<(), zion::ZError> {
syscall::thread_wait(&self.cap)
}
}
#[no_mangle]
extern "C" fn entry_point(func: *mut c_void) -> ! {
unsafe {
Box::from_raw(func as *mut Box<dyn FnOnce()>)();
}
syscall::thread_exit()
}
pub fn spawn<F>(f: F) -> JoinHandle
where
F: FnOnce() + Send + 'static,
{
// This is very tricky.
// If we have been passed a closure that doesn't capture
// anything it will be 0 size and creating a Box of it
// will create a pointer with address 0x1.
// So we create this "main" closure that captures f to get around this.
// Also somehow having the explicit type annotation here is important.
let main: Box<dyn FnOnce()> = Box::new(move || {
f();
});
let raw_main = Box::into_raw(Box::new(main));
let proc_cap = Capability::take_copy(unsafe { crate::init::SELF_PROC_CAP }).unwrap();
let cap = syscall::thread_create(&proc_cap).unwrap();
syscall::thread_start(&cap, entry_point as u64, raw_main as u64, 0).unwrap();
JoinHandle { cap }
}

View File

@ -1,7 +1,12 @@
use core::cell::RefCell;
use alloc::boxed::Box;
use alloc::rc::Rc;
use alloc::string::ToString; use alloc::string::ToString;
use mammoth::cap::Capability; use mammoth::cap::Capability;
use mammoth::port::PortServer; use mammoth::port::PortServer;
use mammoth::thread; use mammoth::thread::Thread;
use mammoth::zion::ZError;
#[repr(u8)] #[repr(u8)]
#[allow(dead_code)] #[allow(dead_code)]
@ -193,34 +198,67 @@ pub trait KeyboardHandler {
fn handle_char(&mut self, c: char); fn handle_char(&mut self, c: char);
} }
pub fn spawn_keyboard_listener<T>(mut handler: T) -> thread::JoinHandle pub struct KeyboardListener {
where listen_port: PortServer,
T: KeyboardHandler + Send + 'static, listen_thread: Option<Box<Thread>>,
{ handler: Rc<RefCell<dyn KeyboardHandler>>,
let listen_port = PortServer::new().unwrap(); }
impl KeyboardListener {
pub fn new(handler: Rc<RefCell<dyn KeyboardHandler>>) -> Result<Box<Self>, ZError> {
let mut listnr = Box::new(Self {
listen_port: PortServer::new()?,
listen_thread: None,
handler,
});
let voyageur_endpoint = yellowstone_yunq::from_init_endpoint() let voyageur_endpoint = yellowstone_yunq::from_init_endpoint()
.get_endpoint(&yellowstone_yunq::GetEndpointRequest { .get_endpoint(&yellowstone_yunq::GetEndpointRequest {
endpoint_name: "voyageurs".to_string(), endpoint_name: "voyageurs".to_string(),
}) })?
.unwrap()
.endpoint; .endpoint;
let mut voyageur_client = crate::VoyageursClient::new(Capability::take(voyageur_endpoint)); let mut voyageur_client = crate::VoyageursClient::new(Capability::take(voyageur_endpoint));
voyageur_client voyageur_client.register_keyboard_listener(&crate::KeyboardListener {
.register_keyboard_listener(&crate::KeyboardListener { port_capability: listnr.listen_port.create_client_cap()?,
port_capability: listen_port.create_client_cap().unwrap(), })?;
})
.unwrap();
let listen_thread = move || loop { let thread_entry = |self_raw| {
let scancode = listen_port.recv_u16().expect("Failed to recieve scancode"); let listener = unsafe {
(self_raw as *mut KeyboardListener)
.as_mut()
.expect("Failed to convert to keyboard listener")
};
listener.listen_loop();
};
listnr.listen_thread = Some(Thread::spawn(
thread_entry,
&*listnr as *const Self as *const core::ffi::c_void,
)?);
Ok(listnr)
}
fn listen_loop(&mut self) {
loop {
let scancode = self
.listen_port
.recv_u16()
.expect("Failed to recieve scancode");
let keycode = Keycode::from_scancode(scancode); let keycode = Keycode::from_scancode(scancode);
let modifiers = Modifiers::from_scancode(scancode); let modifiers = Modifiers::from_scancode(scancode);
handler.handle_char(into_char(keycode, modifiers)) self.handler
}; .as_ref()
.borrow_mut()
thread::spawn(listen_thread) .handle_char(into_char(keycode, modifiers))
}
}
pub fn join(&self) -> Result<(), ZError> {
self.listen_thread.as_ref().unwrap().join()
}
} }

View File

@ -8,8 +8,11 @@ mod framebuffer;
mod psf; mod psf;
mod terminal; mod terminal;
use core::cell::RefCell;
use alloc::rc::Rc;
use mammoth::{debug, define_entry, zion::z_err_t}; use mammoth::{debug, define_entry, zion::z_err_t};
use voyageurs::listener; use voyageurs::listener::KeyboardListener;
define_entry!(); define_entry!();
@ -36,9 +39,9 @@ extern "C" fn main() -> z_err_t {
let psf = psf::Psf::new("/default8x16.psfu").expect("Failed to open font file."); let psf = psf::Psf::new("/default8x16.psfu").expect("Failed to open font file.");
let console = console::Console::new(framebuffer, psf); let console = console::Console::new(framebuffer, psf);
let terminal = terminal::Terminal::new(console); let terminal = Rc::new(RefCell::new(terminal::Terminal::new(console)));
let kb_listener = listener::spawn_keyboard_listener(terminal); let kb_listener = KeyboardListener::new(terminal).expect("Failed to create keyboard listener");
kb_listener kb_listener
.join() .join()

View File

@ -3,7 +3,6 @@
extern crate alloc; extern crate alloc;
use alloc::boxed::Box;
use alloc::string::ToString; use alloc::string::ToString;
use mammoth::debug; use mammoth::debug;
use mammoth::define_entry; use mammoth::define_entry;
@ -13,10 +12,6 @@ use yellowstone_yunq::GetEndpointRequest;
define_entry!(); define_entry!();
pub fn testthread() {
debug!("Testing 1, 8 ,9");
}
#[no_mangle] #[no_mangle]
pub extern "C" fn main() -> z_err_t { pub extern "C" fn main() -> z_err_t {
debug!("Testing!"); debug!("Testing!");
@ -33,24 +28,11 @@ pub extern "C" fn main() -> z_err_t {
debug!("Got endpoint w/ cap: {:#x}", endpoint.endpoint); debug!("Got endpoint w/ cap: {:#x}", endpoint.endpoint);
let a = Box::new(1);
let b = Box::new(1);
debug!("Addrs: {:p} {:p}", a, b);
let e: thread::ThreadEntry = |_| { let e: thread::ThreadEntry = |_| {
debug!("Testing 1 2 3"); debug!("Testing 1 2 3");
}; };
let t = thread::Thread::spawn(e, core::ptr::null()).expect("Failed to spawn thread"); 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);
let t = thread::spawn(testthread);
t.join().expect("Failed to wait.");
let t = thread::spawn(|| debug!("Testing 4, 5, 6"));
t.join().expect("Failed to wait."); t.join().expect("Failed to wait.");
0 0