forked from M-Labs/libfringe
add Context::swap2, to allow distinct save/restore contexts
Fix #5 Context::swap is now implemented in terms of Context::swap2, and it might make sense to remove Context::swap entirely at some point.
This commit is contained in:
parent
2b23083455
commit
709dad1c4a
|
@ -32,10 +32,13 @@ impl Registers {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub unsafe fn swap(&mut self) {
|
pub unsafe fn swap2(out_regs: *mut Registers, in_regs: *const Registers) {
|
||||||
|
let out_espp = &mut (*out_regs).esp;
|
||||||
|
let in_espp = &(*in_regs).esp;
|
||||||
asm!(include_str!("swap.s")
|
asm!(include_str!("swap.s")
|
||||||
:
|
:
|
||||||
: "{eax}" (&mut self.esp)
|
: "{eax}" (out_espp),
|
||||||
|
"{ebx}" (in_espp)
|
||||||
: "eax", "ebx", "ecx", "edx", "esi", "edi", //"ebp", "esp",
|
: "eax", "ebx", "ecx", "edx", "esi", "edi", //"ebp", "esp",
|
||||||
"mmx0", "mmx1", "mmx2", "mmx3", "mmx4", "mmx5", "mmx6", "mmx7",
|
"mmx0", "mmx1", "mmx2", "mmx3", "mmx4", "mmx5", "mmx6", "mmx7",
|
||||||
"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
|
"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
|
|
||||||
//! switch to a new context
|
//! switch to a new context
|
||||||
//! arguments:
|
//! arguments:
|
||||||
//! * eax: stack pointer pointer
|
//! * eax: stack pointer out pointer
|
||||||
|
//! * ebx: stack pointer in pointer
|
||||||
|
|
||||||
// save the frame pointer
|
// save the frame pointer
|
||||||
pushl %ebp
|
pushl %ebp
|
||||||
|
@ -21,11 +22,11 @@ jmp 2f
|
||||||
|
|
||||||
1:
|
1:
|
||||||
// retrieve the new stack pointer
|
// retrieve the new stack pointer
|
||||||
movl (%eax), %ebx
|
movl (%eax), %edx
|
||||||
// save the old stack pointer
|
// save the old stack pointer
|
||||||
movl %esp, (%eax)
|
movl %esp, (%ebx)
|
||||||
// switch to the new stack pointer
|
// switch to the new stack pointer
|
||||||
movl %ebx, %esp
|
movl %edx, %esp
|
||||||
|
|
||||||
// jump into the new context (return to the call point)
|
// jump into the new context (return to the call point)
|
||||||
// doing this instead of a straight `ret` is 8ns slower,
|
// doing this instead of a straight `ret` is 8ns slower,
|
||||||
|
|
|
@ -31,10 +31,13 @@ impl Registers {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub unsafe fn swap(&mut self) {
|
pub unsafe fn swap2(out_regs: *mut Registers, in_regs: *const Registers) {
|
||||||
|
let out_rspp = &mut (*out_regs).rsp;
|
||||||
|
let in_rspp = &(*in_regs).rsp;
|
||||||
asm!(include_str!("swap.s")
|
asm!(include_str!("swap.s")
|
||||||
:
|
:
|
||||||
: "{rdi}" (&mut self.rsp)
|
: "{rdi}" (out_rspp),
|
||||||
|
"{rdi}" (in_rspp)
|
||||||
: "rax", "rbx", "rcx", "rdx", "rsi", "rdi", //"rbp", "rsp",
|
: "rax", "rbx", "rcx", "rdx", "rsi", "rdi", //"rbp", "rsp",
|
||||||
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
|
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
|
||||||
"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
|
"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
|
|
||||||
//! switch to a new context
|
//! switch to a new context
|
||||||
//! arguments:
|
//! arguments:
|
||||||
//! * rdi: stack pointer pointer
|
//! * rdi: stack pointer out pointer
|
||||||
|
//! * rsi: stack pointer in pointer
|
||||||
|
|
||||||
// make sure we leave the red zone alone
|
// make sure we leave the red zone alone
|
||||||
sub $$128, %rsp
|
sub $$128, %rsp
|
||||||
|
@ -27,7 +28,7 @@ jmp 2f
|
||||||
|
|
||||||
1:
|
1:
|
||||||
// retrieve the new stack pointer
|
// retrieve the new stack pointer
|
||||||
movq (%rdi), %rax
|
movq (%rsi), %rax
|
||||||
// save the old stack pointer
|
// save the old stack pointer
|
||||||
movq %rsp, (%rdi)
|
movq %rsp, (%rdi)
|
||||||
// switch to the new stack pointer
|
// switch to the new stack pointer
|
||||||
|
|
|
@ -46,7 +46,13 @@ impl<'a, Stack> Context<'a, Stack> where Stack: stack::Stack {
|
||||||
/// Switch to the context, saving the current thread of execution there.
|
/// Switch to the context, saving the current thread of execution there.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub unsafe fn swap(&mut self) {
|
pub unsafe fn swap(&mut self) {
|
||||||
self.regs.swap()
|
Context::swap2(self, self)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Switch to in_ctx, saving the current thread of execution to out_ctx.
|
||||||
|
#[inline(always)]
|
||||||
|
pub unsafe fn swap2(out_ctx: *mut Context<'a, Stack>, in_ctx: *const Context<'a, Stack>) {
|
||||||
|
Registers::swap2(&mut (*out_ctx).regs, &(*in_ctx).regs)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Unwrap the context, returning the stack it contained.
|
/// Unwrap the context, returning the stack it contained.
|
||||||
|
|
Loading…
Reference in New Issue