libfringe/src/context.rs

58 lines
1.6 KiB
Rust
Raw Normal View History

2015-04-16 20:06:57 +08:00
// This file is part of libfringe, a low-level green threading library.
2015-04-16 18:08:44 +08:00
// Copyright (c) 2015, edef <edef@edef.eu>
// See the LICENSE file included in this distribution.
use core::marker::PhantomData;
2015-08-25 12:42:26 +08:00
use void::Void;
use arch::Registers;
2015-04-16 04:26:51 +08:00
use stack;
use debug::StackId;
2014-12-24 13:12:39 +08:00
2015-04-16 22:12:26 +08:00
/// Context is the heart of libfringe.
/// A context represents a saved thread of execution, along with a stack.
/// It can be swapped into and out of with the swap method,
/// and once you're done with it, you can get the stack back through unwrap.
///
/// Every operation is unsafe, because libfringe can't make any guarantees
/// about the state of the context.
#[derive(Debug)]
pub struct Context<'a, Stack: stack::Stack> {
2014-12-23 11:24:40 +08:00
regs: Registers,
_stack_id: StackId,
stack: Stack,
_ref: PhantomData<&'a ()>
2014-12-23 11:24:40 +08:00
}
2015-04-16 19:06:30 +08:00
unsafe impl<'a, Stack> Send for Context<'a, Stack>
where Stack: stack::Stack + Send {}
impl<'a, Stack> Context<'a, Stack> where Stack: stack::Stack {
2015-04-16 22:12:26 +08:00
/// Create a new Context. When it is swapped into,
/// it will call the passed closure.
#[inline]
pub unsafe fn new<F>(mut stack: Stack, f: F) -> Context<'a, Stack>
2015-08-25 12:42:26 +08:00
where F: FnOnce() -> Void + Send + 'a {
let stack_id = StackId::register(&mut stack);
let regs = Registers::new(&mut stack, f);
2014-12-23 11:24:40 +08:00
Context {
regs: regs,
_stack_id: stack_id,
stack: stack,
_ref: PhantomData
2014-12-23 11:24:40 +08:00
}
}
2015-04-16 22:12:26 +08:00
/// Switch to the context, saving the current thread of execution there.
2014-12-23 11:24:40 +08:00
#[inline(always)]
pub unsafe fn swap(&mut self) {
self.regs.swap()
2014-12-23 11:24:40 +08:00
}
2015-04-16 09:54:56 +08:00
2015-04-16 22:12:26 +08:00
/// Unwrap the context, returning the stack it contained.
2015-04-16 18:43:09 +08:00
#[inline]
pub unsafe fn unwrap(self) -> Stack {
2015-04-16 09:54:56 +08:00
self.stack
}
2014-12-23 11:24:40 +08:00
}