-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ref #1
- Loading branch information
Showing
6 changed files
with
150 additions
and
0 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
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 @@ | ||
--32 |
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,44 @@ | ||
// This file is part of libfringe, a low-level green threading library. | ||
// Copyright (c) 2015, Nathan Zadoks <nathan@nathan7.eu> | ||
// See the LICENSE file included in this distribution. | ||
|
||
//! initialise a new context | ||
//! arguments: | ||
//! * eax: stack pointer | ||
//! * ebx: function pointer | ||
//! * ecx: data pointer | ||
//! * edx: stack limit | ||
//! | ||
//! return values: | ||
//! * eax: new stack pointer | ||
|
||
// switch to the fresh stack | ||
xchg %esp, %eax | ||
|
||
// save the data pointer, function pointer, and stack limit, respectively | ||
pushl %ecx | ||
pushl %ebx | ||
pushl %edx | ||
|
||
// save the return address, control flow continues at label 1 | ||
call 1f | ||
// we arrive here once this context is reactivated (see swap.s) | ||
|
||
// restore the stack limit, data pointer, and function pointer, respectively | ||
// TODO: this stack limit location is specific to Linux/FreeBSD. | ||
popl %gs:0x30 | ||
popl %eax | ||
|
||
// initialise the frame pointer | ||
movl $$0, %ebp | ||
|
||
// call the function pointer with the data pointer (top of the stack is the first argument) | ||
call *%eax | ||
|
||
// crash if it ever returns | ||
ud2 | ||
|
||
1: | ||
// save our neatly-setup new stack | ||
xchg %esp, %eax | ||
// back into Rust-land we go |
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,47 @@ | ||
// This file is part of libfringe, a low-level green threading library. | ||
// Copyright (c) 2015, Nathan Zadoks <nathan@nathan7.eu> | ||
// See the LICENSE file included in this distribution. | ||
use core::prelude::*; | ||
|
||
use stack::Stack; | ||
use super::common::{push, rust_trampoline}; | ||
|
||
pub const STACK_ALIGN: usize = 16; | ||
|
||
#[allow(raw_pointer_derive)] | ||
#[derive(Debug)] | ||
pub struct Registers { | ||
esp: *mut usize | ||
} | ||
|
||
impl Registers { | ||
#[inline] | ||
pub unsafe fn new<S, F>(stack: &mut S, f: F) -> Registers where S: Stack, F: FnOnce() { | ||
let sp_limit = stack.limit(); | ||
let mut sp = stack.top() as *mut usize; | ||
let f_ptr = push(&mut sp, f); | ||
|
||
asm!(include_str!("init.s") | ||
: "={eax}"(sp) | ||
: "{eax}" (sp), | ||
"{ebx}" (rust_trampoline::<F>), | ||
"{ecx}" (f_ptr), | ||
"{edx}" (sp_limit) | ||
: | ||
: "volatile"); | ||
|
||
Registers { esp: sp } | ||
} | ||
|
||
#[inline(always)] | ||
pub unsafe fn swap(&mut self) { | ||
asm!(include_str!("swap.s") | ||
: | ||
: "{eax}" (&mut self.esp) | ||
: "eax", "ebx", "ecx", "edx", "esi", "edi", //"ebp", "esp", | ||
"mmx0", "mmx1", "mmx2", "mmx3", "mmx4", "mmx5", "mmx6", "mmx7", | ||
"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", | ||
"cc" | ||
: "volatile"); | ||
} | ||
} |
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,40 @@ | ||
// This file is part of libfringe, a low-level green threading library. | ||
// Copyright (c) 2015, Nathan Zadoks <nathan@nathan7.eu> | ||
// See the LICENSE file included in this distribution. | ||
|
||
//! switch to a new context | ||
//! arguments: | ||
//! * eax: stack pointer pointer | ||
|
||
// save the Rust stack limit and the frame pointer, respectively | ||
// TODO: this stack limit location is specific to Linux/FreeBSD. | ||
pushl %gs:0x30 | ||
pushl %ebp | ||
|
||
// save the return address to the stack, control flow continues at label 1 | ||
call 1f | ||
// we arrive here once this context is reactivated | ||
|
||
// restore the frame pointer and the Rust stack limit, respectively | ||
popl %ebp | ||
// TODO: this stack limit location is specific to Linux/FreeBSD. | ||
popl %gs:0x30 | ||
|
||
// and we merrily go on our way, back into Rust-land | ||
jmp 2f | ||
|
||
1: | ||
// retrieve the new stack pointer | ||
movl (%eax), %ebx | ||
// save the old stack pointer | ||
movl %esp, (%eax) | ||
// switch to the new stack pointer | ||
movl %ebx, %esp | ||
|
||
// jump into the new context (return to the call point) | ||
// doing this instead of a straight `ret` is 8ns slower, | ||
// presumably because the branch predictor tries to be clever about it | ||
popl %eax | ||
jmpl *%eax | ||
|
||
2: |