Launch a thread by calling the low-level syscalls
(p: Box<dyn FnOnce()>)
| 36 | /// Launch a thread by calling the low-level syscalls |
| 37 | /// |
| 38 | fn launch(p: Box<dyn FnOnce()>) -> Result<(), SyscallError> |
| 39 | { |
| 40 | // Note: A Box<dyn FnOnce()> is a fat pointer, |
| 41 | // containing a pointer to heap allocated memory |
| 42 | // along with the function pointer. To convert to |
| 43 | // a thin pointer (memory address) we first need |
| 44 | // to move the fat pointer onto the heap by putting |
| 45 | // into a Box, then get a pointer to that. |
| 46 | let p = Box::into_raw(Box::new(p)); |
| 47 | |
| 48 | // Get thin pointer as memory address |
| 49 | if let Err(sys_err) = syscalls::thread_spawn(thread_start, |
| 50 | p as *mut () as usize) { |
| 51 | // Could not launch thread. Reconstruct Box so that |
| 52 | // the contents can be dropped |
| 53 | let _ = unsafe {Box::from_raw(p)}; |
| 54 | return Err(sys_err); |
| 55 | } |
| 56 | |
| 57 | // This function is called by syscalls::thread_spawn |
| 58 | extern "C" fn thread_start(main: usize) { |
| 59 | // Convert address back to Box containing the Box<dyn FnOnce()> |
| 60 | // fat pointer, then call it. |
| 61 | unsafe {Box::from_raw(main as *mut Box<dyn FnOnce()>)()}; |
| 62 | } |
| 63 | Ok(()) |
| 64 | } |