This repository has been archived by the owner on Dec 9, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #110 from tbu-/pr_thread_basic
Add basic `thread`
- Loading branch information
Showing
36 changed files
with
1,780 additions
and
129 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,7 @@ main() { | |
stderr | ||
system-time | ||
tcp_listen_connect | ||
thread | ||
vec | ||
zero | ||
) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#[cfg(not(any(target_arch = "aarch64", | ||
target_arch = "arm", | ||
target_arch = "powerpc", | ||
target_arch = "x86", | ||
target_arch = "x86_64")))] | ||
fn main() { | ||
} | ||
|
||
#[cfg(any(target_arch = "aarch64", | ||
target_arch = "arm", | ||
target_arch = "powerpc", | ||
target_arch = "x86", | ||
target_arch = "x86_64"))] | ||
fn main() { | ||
use std::io::{self, Write}; | ||
use std::thread; | ||
|
||
thread::spawn(|| { | ||
io::stdout().write_all(b"Hello, world!\n").unwrap(); | ||
}).join().unwrap(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
#[cfg(not(test))] | ||
mod not_test { | ||
// Syscall number is passed in x8, syscall arguments in x0, x1, x2, x3, x4. | ||
// The arguments are | ||
// (flags: c_ulong, // x0 | ||
// child_stack: *mut c_void, // x1 | ||
// ptid: *mut c_int, // x2 | ||
// newtls: c_ulong, // x3 | ||
// ctid: *mut c_int) // x4 | ||
// | ||
// No registers are clobbered, x0 gets the return value. | ||
// | ||
// We do not clobber any registers, so we don't need to save any. | ||
// | ||
// The calling convention passes arguments in registers, from x0 to x6. | ||
// (fn_: extern "C" fn(*mut c_void) -> *mut c_void, // x0 | ||
// child_stack: *mut c_void, // x1 | ||
// flags: c_ulong, // x2 | ||
// arg: *mut c_void, // x3 | ||
// ptid: *mut pid_t, // x4 | ||
// newtls: *mut c_void, // x5 | ||
// ctid: *mut pid_t) // x6 | ||
// | ||
// Both ABIs return the function result in x0. | ||
// | ||
// This means we need the following moves: | ||
// x2 -> x0 // flags | ||
// x1 -> x1 // child_stack | ||
// x4 -> x2 // ptid | ||
// x5 -> x3 // newtls | ||
// x6 -> x4 // ctid | ||
// | ||
// We save `fn_` and `arg` on the child stack. | ||
|
||
global_asm!(" | ||
.globl __steed_clone | ||
__steed_clone: | ||
// Align the child stack. | ||
and x1,x1,#-16 | ||
// Save `fn_` and `arg` on the child stack. | ||
stp x0,x3,[x1,#-16]! | ||
mov x8,#220 // CLONE | ||
mov x0,x2 // flags | ||
// child_stack | ||
mov x2,x4 // ptid | ||
mov x3,x5 // newtls | ||
mov x4,x6 // ctid | ||
svc #0 | ||
cbnz x0,1f | ||
// Restore `fn_` and `arg`. | ||
ldp x1,x0,[sp],#16 | ||
blr x1 | ||
mov x8,#93 // EXIT | ||
// status | ||
svc #0 | ||
1: | ||
ret | ||
"); | ||
} | ||
|
||
pub unsafe fn set_thread_pointer(thread_data: *mut ()) { | ||
let _ = thread_data; // TODO(steed, #127): Set thread-local pointer. | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
#[cfg(not(test))] | ||
mod not_test { | ||
// Syscall number is passed in r7, syscall arguments in r0, r1, r2, r3, r4. | ||
// The arguments are | ||
// (flags: c_ulong, // r0 | ||
// child_stack: *mut c_void, // r1 | ||
// ptid: *mut c_int, // r2 | ||
// newtls: c_ulong, // r3 | ||
// ctid: *mut c_int) // r4 | ||
// | ||
// No registers are clobbered, r0 gets the return value. | ||
// | ||
// Only r0, r1, r2, r3 are caller-saved, so we must restore the value of | ||
// all other registers before returning. | ||
// | ||
// The calling convention passes the first four arguments in r0 to r3 and | ||
// all further arguments on the stack, right to left. Since we push r4 to | ||
// r7 onto the stack in the very beginning, all stack offsets are increased | ||
// by 16. The arguments are | ||
// (fn_: extern "C" fn(*mut c_void) -> *mut c_void, // r0 | ||
// child_stack: *mut c_void, // r1 | ||
// flags: c_ulong, // r2 | ||
// arg: *mut c_void, // r3 | ||
// ptid: *mut pid_t, // [sp,#16] | ||
// newtls: *mut c_void, // [sp,#20] | ||
// ctid: *mut pid_t) // [sp,#24] | ||
// | ||
// Both ABIs return the function result in r0. | ||
// | ||
// This means we need the following moves: | ||
// r2 -> r0 // flags | ||
// r1 -> r1 // child_stack | ||
// [sp,#16] -> r2 // ptid | ||
// [sp,#20] -> r3 // newtls | ||
// [sp,#24] -> r4 // ctid | ||
// | ||
// We save `fn_` in r5, `arg` in r6. | ||
|
||
global_asm!(" | ||
.globl __steed_clone | ||
__steed_clone: | ||
@ Save r4 to r7 | ||
stmfd sp!,{r4,r5,r6,r7} | ||
mov r5,r0 @ fn_ | ||
mov r6,r3 @ arg | ||
mov r7,#120 @ CLONE | ||
mov r0,r2 @ flags | ||
@ child_stack | ||
ldr r2,[sp,#16] @ ptid | ||
ldr r3,[sp,#20] @ newtls | ||
ldr r4,[sp,#24] @ ctid | ||
and r1,r1,#-16 @ Align the stack | ||
@ Do the syscall | ||
svc 0 | ||
@ CLONE returns 0 in the child thread, return if we're the parent. | ||
tst r0,r0 | ||
bne 3f | ||
mov r0,r6 @ arg | ||
@ Do we need to execute `fn_` in thumb mode? | ||
tst r5,#1 | ||
bne 2f | ||
@ pc (Program Counter) is always 2 instructions ahead. | ||
mov lr,pc | ||
mov pc,r5 @ fn_ | ||
@ The function will return here. | ||
__steed_clone_exit: | ||
mov r7,#1 @ EXIT | ||
@ status | ||
svc 0 | ||
2: | ||
@ Again, pc is 2 instructions ahead. | ||
mov lr,pc | ||
bx r5 @ Start thumb mode | ||
b 2b | ||
3: | ||
@ Restore r4 to r7 | ||
ldmfd sp!,{r4,r5,r6,r7} | ||
@ Return from the function. | ||
mov pc,lr | ||
"); | ||
} | ||
|
||
pub unsafe fn set_thread_pointer(thread_data: *mut ()) { | ||
let _ = thread_data; // TODO(steed, #127): Set thread-local pointer. | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
pub unsafe fn set_thread_pointer(thread_data: *mut ()) { | ||
let _ = thread_data; // TODO(steed, #127): Set thread-local pointer. | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
pub unsafe fn set_thread_pointer(thread_data: *mut ()) { | ||
let _ = thread_data; // TODO(steed, #127): Set thread-local pointer. | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#[cfg(target_arch = "aarch64")] #[path = "aarch64.rs"] mod arch; | ||
#[cfg(target_arch = "arm")] #[path = "arm.rs"] mod arch; | ||
#[cfg(target_arch = "mips")] #[path = "mips.rs"] mod arch; | ||
#[cfg(target_arch = "mips64")] #[path = "mips64.rs"] mod arch; | ||
#[cfg(target_arch = "powerpc")] #[path = "powerpc.rs"] mod arch; | ||
#[cfg(target_arch = "powerpc64")] #[path = "powerpc64.rs"] mod arch; | ||
#[cfg(target_arch = "sparc64")] #[path = "sparc64.rs"] mod arch; | ||
#[cfg(target_arch = "x86")] #[path = "x86.rs"] mod arch; | ||
#[cfg(target_arch = "x86_64")] #[path = "x86_64.rs"] mod arch; | ||
|
||
use super::*; | ||
use self::arch::*; | ||
|
||
pub struct Buffer(thread); | ||
|
||
pub unsafe fn init_main_thread(buffer: *mut Buffer) { | ||
let buffer: *mut thread = &mut (*buffer).0; | ||
*buffer = thread { | ||
this: buffer, | ||
thread_id: -1, | ||
}; | ||
set_thread_pointer(buffer as *mut _); | ||
} |
Oops, something went wrong.