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)]
|
||||
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")
|
||||
:
|
||||
: "{eax}" (&mut self.esp)
|
||||
: "{eax}" (out_espp),
|
||||
"{ebx}" (in_espp)
|
||||
: "eax", "ebx", "ecx", "edx", "esi", "edi", //"ebp", "esp",
|
||||
"mmx0", "mmx1", "mmx2", "mmx3", "mmx4", "mmx5", "mmx6", "mmx7",
|
||||
"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
|
||||
//! switch to a new context
|
||||
//! arguments:
|
||||
//! * eax: stack pointer pointer
|
||||
//! * eax: stack pointer out pointer
|
||||
//! * ebx: stack pointer in pointer
|
||||
|
||||
// save the frame pointer
|
||||
pushl %ebp
|
||||
|
@ -21,11 +22,11 @@ jmp 2f
|
|||
|
||||
1:
|
||||
// retrieve the new stack pointer
|
||||
movl (%eax), %ebx
|
||||
movl (%eax), %edx
|
||||
// save the old stack pointer
|
||||
movl %esp, (%eax)
|
||||
movl %esp, (%ebx)
|
||||
// switch to the new stack pointer
|
||||
movl %ebx, %esp
|
||||
movl %edx, %esp
|
||||
|
||||
// jump into the new context (return to the call point)
|
||||
// doing this instead of a straight `ret` is 8ns slower,
|
||||
|
|
|
@ -31,10 +31,13 @@ impl Registers {
|
|||
}
|
||||
|
||||
#[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")
|
||||
:
|
||||
: "{rdi}" (&mut self.rsp)
|
||||
: "{rdi}" (out_rspp),
|
||||
"{rdi}" (in_rspp)
|
||||
: "rax", "rbx", "rcx", "rdx", "rsi", "rdi", //"rbp", "rsp",
|
||||
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
|
||||
"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
|
||||
//! switch to a new context
|
||||
//! arguments:
|
||||
//! * rdi: stack pointer pointer
|
||||
//! * rdi: stack pointer out pointer
|
||||
//! * rsi: stack pointer in pointer
|
||||
|
||||
// make sure we leave the red zone alone
|
||||
sub $$128, %rsp
|
||||
|
@ -27,7 +28,7 @@ jmp 2f
|
|||
|
||||
1:
|
||||
// retrieve the new stack pointer
|
||||
movq (%rdi), %rax
|
||||
movq (%rsi), %rax
|
||||
// save the old stack pointer
|
||||
movq %rsp, (%rdi)
|
||||
// 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.
|
||||
#[inline(always)]
|
||||
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.
|
||||
|
|
Loading…
Reference in New Issue