Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // libuser syscalls:
- /// Creates a thread in the current process.
- pub fn create_thread(ip: fn() -> !, arg: usize, sp: *const u8, _priority: u32, _processor_id: u32) -> Result<Thread, KernelError> {
- unsafe {
- let (out_handle, ..) = syscall(nr::CreateThread, ip as usize, arg, sp as _, _priority as _, _processor_id as _, 0)?;
- Ok(Thread(Handle::new(out_handle as _)))
- }
- }
- // Function I'm writing:
- fn test_threads() -> Terminal {
- fn thread_b(c: usize) -> ! {
- for _ in 0..10 {
- println!("{}", c);
- libuser::syscalls::sleep_thread(0);
- }
- }
- libuser::syscalls::exit_thread()
- }
- #[naked]
- fn function_wrapper() {
- unsafe {
- asm!("
- push eax
- call $0
- " :: "i"(thread_b) :: "intel");
- }
- }
- const THREAD_STACK_SIZE: usize = 0x2000;
- let terminal = Arc::new(Mutex::new(terminal));
- let stack = Box::new([0u8; THREAD_STACK_SIZE]);
- let sp = (Box::into_raw(stack) as *const u8).wrapping_offset(THREAD_STACK_SIZE as isize);
- let ip : fn() -> ! = unsafe {
- // Safety: This is changing the return type from () to !. It's safe. It
- // sucks though. This is, yet again, an instance of "naked functions are
- // fucking horrible".
- core::mem::transmute(function_wrapper) // THE BUG IS HERE
- };
- let thread_handle = libuser::syscalls::create_thread(ip, Arc::into_raw(terminal.clone()) as usize, sp, 0, 0)
- .expect("svcCreateThread returned an error");
- thread_handle.start()
- .expect("svcStartThread returned an error");
- // Wait for thread_b to terminate.
- loop {
- if let Ok(terminal) = Arc::try_unwrap(terminal) {
- break terminal.into_inner()
- }
- libuser::syscalls::sleep_thread(0);
- }
- }
Add Comment
Please, Sign In to add comment