use crate::execution_kernel::ExecutionTaskState;
use crate::guest_call::{ExecutionTaskId, SharedGuestCallStack};
pub(crate) const THREAD_NOT_FOUND_ERR: i16 = -618;
pub(crate) const THREAD_PROTOCOL_ERR: i16 = -619;
pub(crate) struct ThreadManager<'a> {
execution: &'a SharedGuestCallStack,
}
impl<'a> ThreadManager<'a> {
pub(crate) fn new(execution: &'a SharedGuestCallStack) -> Self {
Self { execution }
}
pub(crate) fn current_thread(&self) -> u32 {
self.execution.current_task().thread_id()
}
pub(crate) fn resolve_thread(&self, thread: u32) -> u32 {
if thread <= 1 {
self.current_thread()
} else {
thread
}
}
pub(crate) fn state(&self, thread: u32) -> Result<u16, i16> {
self.execution
.scheduling_state(ExecutionTaskId::from_thread_id(self.resolve_thread(thread)))
.map(|state| match state {
ExecutionTaskState::Ready => 0,
ExecutionTaskState::Stopped => 1,
ExecutionTaskState::Running => 2,
})
.ok_or(THREAD_NOT_FOUND_ERR)
}
pub(crate) fn begin_critical(&self) -> i16 {
self.execution.begin_critical();
0
}
pub(crate) fn end_critical(&self) -> i16 {
if self.execution.end_critical() {
0
} else {
THREAD_PROTOCOL_ERR
}
}
}