use crate::runtime::thread::continuation::{ContinuationPool, PooledContinuation};
use serde::{Deserialize, Serialize};
use std::cell::RefCell;
use std::fmt::Debug;
use std::rc::Rc;
pub(crate) const DEFAULT_INLINE_TASKS: usize = 16;
#[derive(Debug)]
pub(crate) struct Task {
pub(super) id: TaskId,
pub(super) state: TaskState,
pub(super) continuation: Rc<RefCell<PooledContinuation>>,
pub(crate) instructions: usize,
name: Option<String>,
}
impl Task {
fn new<F>(f: F, stack_size: usize, id: TaskId, name: Option<String>) -> Self
where
F: FnOnce() + Send + 'static,
{
let mut continuation = ContinuationPool::acquire(stack_size);
continuation.initialize(Box::new(f));
let continuation = Rc::new(RefCell::new(continuation));
Self {
id,
state: TaskState::Runnable,
continuation,
instructions: 0,
name,
}
}
pub(crate) fn from_closure<F>(
f: F,
stack_size: usize,
id: TaskId,
name: Option<String>,
) -> Self
where
F: FnOnce() + Send + 'static,
{
Self::new(f, stack_size, id, name)
}
pub(crate) fn id(&self) -> TaskId {
self.id
}
pub(crate) fn runnable(&self) -> bool {
self.state == TaskState::Runnable
}
pub(crate) fn is_stuck(&self) -> bool {
self.state == TaskState::Stuck
}
pub(crate) fn finished(&self) -> bool {
self.state == TaskState::Finished
}
pub(crate) fn stuck(&mut self) {
assert!(self.state != TaskState::Finished);
self.state = TaskState::Stuck;
}
pub(crate) fn unstuck(&mut self) {
assert!(self.state == TaskState::Stuck);
self.state = TaskState::Runnable;
}
pub(crate) fn finish(&mut self) {
assert!(self.state != TaskState::Finished);
self.state = TaskState::Finished;
}
pub(crate) fn name(&self) -> Option<String> {
self.name.clone()
}
}
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub(crate) enum TaskState {
Runnable,
Stuck,
Finished,
}
#[derive(PartialEq, Eq, Hash, Clone, Copy, PartialOrd, Ord, Debug, Serialize, Deserialize)]
pub struct TaskId(pub(crate) usize);
impl From<usize> for TaskId {
fn from(id: usize) -> Self {
TaskId(id)
}
}
impl From<TaskId> for usize {
fn from(tid: TaskId) -> usize {
tid.0
}
}