Spawn a new thread with a given entry point # Returns Ok(thread_id) or Err(error_code)
(
func: extern "C" fn(usize) -> (),
param: usize
)
| 176 | /// Ok(thread_id) or Err(error_code) |
| 177 | /// |
| 178 | pub fn thread_spawn( |
| 179 | func: extern "C" fn(usize) -> (), |
| 180 | param: usize |
| 181 | ) -> Result<u64, SyscallError> { |
| 182 | |
| 183 | let tid: u64; |
| 184 | let errcode: u64; |
| 185 | unsafe { |
| 186 | asm!("syscall", |
| 187 | // rax = 0 indicates no error |
| 188 | "cmp rax, 0", |
| 189 | "jnz 2f", |
| 190 | // rdi = 0 for new thread |
| 191 | "cmp rdi, 0", |
| 192 | "jnz 2f", |
| 193 | // New thread |
| 194 | "mov rdi, r9", // Function argument |
| 195 | "call r8", |
| 196 | "mov rax, 1", // exit_current_thread syscall |
| 197 | "syscall", |
| 198 | // New thread never leaves this asm block |
| 199 | "2:", |
| 200 | in("rax") SYSCALL_FORK_THREAD, |
| 201 | in("r8") func, |
| 202 | in("r9") param, |
| 203 | lateout("rax") errcode, |
| 204 | lateout("rdi") tid, |
| 205 | out("rcx") _, |
| 206 | out("r11") _); |
| 207 | } |
| 208 | if errcode != 0 { |
| 209 | return Err(SyscallError(errcode)); |
| 210 | } |
| 211 | Ok(tid) |
| 212 | } |
| 213 | |
| 214 | /// Exit the current thread. Never returns. |
| 215 | pub fn thread_exit() -> ! { |