Compare commits
No commits in common. "d1b5720abd83dbb1f0e771400db0078036cabd01" and "14585c005c459a0194d2a50f9556c45e42c0e9d8" have entirely different histories.
d1b5720abd
...
14585c005c
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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 }
|
|
||||||
}
|
|
||||||
|
|
|
@ -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()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue