Change design of sleeping state

This commit is contained in:
luojia65 2021-04-25 14:32:47 +08:00
parent 4d583f52a2
commit 7bae22b118
12 changed files with 175 additions and 140 deletions

View File

@ -16,6 +16,8 @@ pub trait Scheduler<T: Clone + PartialEq> {
fn next_task(&mut self) -> Option<T>;
/// 获取正在运行的任务,中断发生时,将保存这个任务的上下文
fn current_task(&self) -> Option<T>;
/// 查找一个任务
fn find_first_task_mut(&mut self, p: impl Fn(&T) -> bool) -> Option<&mut T>;
/// 移除一个任务
fn remove_task(&mut self, task: &T);
/// 设置任务的优先级

View File

@ -2,7 +2,7 @@
//!
use super::Scheduler;
use core::mem::MaybeUninit;
use core::{marker::PhantomData, mem::MaybeUninit};
use core::ptr;
/// 先进先出轮转任务调度器
@ -46,6 +46,9 @@ impl<T: Clone + PartialEq, const N: usize> Scheduler<T> for RingFifoScheduler<T,
fn current_task(&self) -> Option<T> {
self.current.clone()
}
fn find_first_task_mut(&mut self, p: impl Fn(&T) -> bool) -> Option<&mut T> {
self.ring.iter_mut().find(|t| p(t))
}
fn remove_task(&mut self, task: &T) {
// 移除相应的线程并且确认恰移除一个线程
drop(task);
@ -107,40 +110,37 @@ impl<T, const N: usize> RingQueue<T, N> {
Some(unsafe { &*self.elem[self.front].as_ptr() })
}
}
// 如果用到这个函数,取消注释
// pub fn iter(&self) -> Iter<'_, T, N> {
// let mut elem = [&self.elem[0]; N];
// for i in 0..self.elem.len() {
// elem[i] = &self.elem[i];
// }
// Iter {
// elem,
// front: self.front,
// tail: self.tail
// }
// }
pub fn iter_mut(&mut self) -> IterMut<'_, T, N> {
IterMut {
ptr: &mut self.elem as *mut [MaybeUninit<T>; N] as *mut [T; N],
front: self.front,
tail: self.tail,
_marker: PhantomData
}
}
}
// pub struct Iter<'a, T: 'a, const N: usize> {
// elem: [&'a MaybeUninit<T>; N],
// front: usize,
// tail: usize
// }
pub struct IterMut<'a, T: 'a, const N: usize> {
ptr: *mut [T; N],
front: usize,
tail: usize,
_marker: PhantomData<&'a mut T>
}
// // TODO: 这里有不确定 Unsafe 代码,需检查正确性
// impl<'a, T, const N: usize> Iterator for Iter<'a, T, N> {
// type Item = &'a T;
// fn next(&mut self) -> Option<Self::Item> {
// if self.tail == self.front {
// // is empty
// None
// } else {
// let value = unsafe { self.elem[self.front].assume_init_ref() };
// self.front = self.front.wrapping_add(1);
// if self.front > N || self.front == 0 {
// self.front = self.front.wrapping_sub(N);
// }
// Some(value)
// }
// }
// }
// TODO: 这里有不确定 Unsafe 代码,需检查正确性
impl<'a, T, const N: usize> Iterator for IterMut<'a, T, N> {
type Item = &'a mut T;
fn next(&mut self) -> Option<Self::Item> {
if self.tail == self.front {
// is empty
None
} else {
let value = unsafe { &mut (*(self.ptr))[self.front] };
self.front = self.front.wrapping_add(1);
if self.front > N || self.front == 0 {
self.front = self.front.wrapping_sub(N);
}
Some(value)
}
}
}

View File

@ -22,8 +22,8 @@ mod syscall;
use buddy_system_allocator::LockedHeap;
use core::{mem::MaybeUninit, ptr::NonNull};
use crate::task::{
SharedTaskHandle, TaskResult, TaskRepr, SharedScheduler, SHARED_SCHEDULER,
shared_add_task, shared_peek_task, shared_delete_task,
TaskResult, TaskRepr, TaskState, SharedScheduler, SHARED_SCHEDULER,
shared_add_task, shared_peek_task, shared_delete_task, shared_set_task_state,
};
use crate::mm::AddressSpaceId;
@ -60,8 +60,9 @@ pub static SHARED_RAW_TABLE: (
unsafe extern "C" fn() -> PageList, // 初始化函数,执行完之后,内核将函数指针置空
&'static SharedScheduler, // 共享调度器的地址
unsafe extern "C" fn(NonNull<()>, usize, AddressSpaceId, TaskRepr) -> bool, // 添加任务
unsafe extern "C" fn(NonNull<()>, extern "C" fn(&SharedTaskHandle) -> bool) -> TaskResult, // 弹出任务
unsafe extern "C" fn(NonNull<()>, TaskRepr) -> bool,
unsafe extern "C" fn(NonNull<()>, extern "C" fn(AddressSpaceId) -> bool) -> TaskResult, // 弹出任务
unsafe extern "C" fn(NonNull<()>, usize, AddressSpaceId, TaskRepr) -> bool, // 删除任务
unsafe extern "C" fn(NonNull<()>, usize, AddressSpaceId, TaskRepr, TaskState), // 改变任务的状态
) = (
unsafe { &payload_compiled_start },
init_payload_environment,
@ -69,6 +70,7 @@ pub static SHARED_RAW_TABLE: (
shared_add_task,
shared_peek_task,
shared_delete_task,
shared_set_task_state,
);
#[allow(non_upper_case_globals)]

View File

@ -25,22 +25,34 @@ pub enum TaskResult {
pub struct TaskRepr(usize);
/// 共享调度器的类型
pub type SharedScheduler = Mutex<RingFifoScheduler<SharedTaskHandle, 100>>;
pub type SharedScheduler = Mutex<RingFifoScheduler<TaskMeta, 100>>;
/// 全局的共享调度器
/// 放到数据段,内核或用户从这个地址里取得共享调度器
pub static SHARED_SCHEDULER: SharedScheduler = Mutex::new(RingFifoScheduler::new());
/// 共享任务的句柄
/// 共享任务的元数据
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[repr(C)]
pub struct SharedTaskHandle {
pub struct TaskMeta {
/// 运行此任务的硬件线程编号
pub(crate) hart_id: usize,
/// 地址空间的编号
pub(crate) address_space_id: AddressSpaceId,
// 元数据指针,由所在的地址空间解释
task_repr: TaskRepr,
// 任务当前的状态
pub(crate) state: TaskState,
}
// todo: 在调度器中设计,如果任务正在休眠,就跳过
/// 任务当前的状态
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[repr(u8)]
pub enum TaskState {
Ready = 0,
Sleeping = 1,
}
/// 给共享调度器添加任务
@ -63,11 +75,12 @@ pub unsafe extern "C" fn shared_add_task(
hart_id: usize,
address_space_id: AddressSpaceId,
task_repr: TaskRepr,
) -> SharedTaskHandle {
SharedTaskHandle {
) -> TaskMeta {
TaskMeta {
hart_id,
address_space_id,
task_repr,
state: TaskState::Ready, // 默认为就绪状态
}
}
@ -76,7 +89,7 @@ pub unsafe extern "C" fn shared_add_task(
/// 在内核态和用户态都可以调用
pub unsafe extern "C" fn shared_peek_task(
shared_scheduler: NonNull<()>,
should_switch: extern "C" fn(&SharedTaskHandle) -> bool
should_switch: extern "C" fn(AddressSpaceId) -> bool
) -> TaskResult {
// 得到共享调度器的引用
// println!("[Shared peek task] {:p} {:x}", shared_scheduler, should_switch as usize);
@ -84,7 +97,7 @@ pub unsafe extern "C" fn shared_peek_task(
let scheduler = s.as_mut().lock();
if let Some(task) = scheduler.peek_next_task() {
// println!("Pop task {:x?}!", task);
if should_switch(task) {
if should_switch(task.address_space_id) {
// 如果需要跳转到其他地址空间,则不弹出任务,返回需要跳转到的地址空间编号
return TaskResult::ShouldYield(task.address_space_id.into_inner())
}
@ -103,6 +116,8 @@ pub unsafe extern "C" fn shared_peek_task(
/// 删除一个共享调度器中的任务
pub unsafe extern "C" fn shared_delete_task(
shared_scheduler: NonNull<()>,
_hart_id: usize,
_address_space_id: AddressSpaceId,
task_repr: TaskRepr,
) -> bool {
let mut s: NonNull<SharedScheduler> = shared_scheduler.cast();
@ -117,3 +132,27 @@ pub unsafe extern "C" fn shared_delete_task(
}
false
}
/// 设置任务的状态
pub unsafe extern "C" fn shared_set_task_state(
shared_scheduler: NonNull<()>,
hart_id: usize,
address_space_id: AddressSpaceId,
task_repr: TaskRepr,
new_state: TaskState,
) {
let mut s: NonNull<SharedScheduler> = shared_scheduler.cast();
let mut scheduler = s.as_mut().lock();
if let Some(task) = scheduler.find_first_task_mut(|t| task_eq(t, hart_id, address_space_id, task_repr)) {
task.state = new_state;
}
}
fn task_eq(
a: &TaskMeta,
hart_id: usize,
address_space_id: AddressSpaceId,
task_repr: TaskRepr,
) -> bool {
a.hart_id == hart_id && a.address_space_id == address_space_id && a.task_repr == task_repr
}

View File

@ -2,7 +2,7 @@
use alloc::collections::LinkedList;
use alloc::boxed::Box;
use alloc::sync::Arc;
use crate::{task::{Process, SharedTaskHandle}, trap::TrapFrame};
use crate::task::Process;
use crate::memory::{AddressSpaceId, Satp};
/// 写一个指针到上下文指针

View File

@ -118,7 +118,8 @@ pub extern "C" fn rust_main(hart_id: usize) -> ! {
task::run_until_idle(
|| unsafe { shared_payload.peek_task(task::kernel_should_switch) },
|task_repr| unsafe { shared_payload.delete_task(task_repr) },
|task_repr| unsafe { shared_payload.delete_task(hart_id, address_space_id, task_repr) },
|task_repr, new_state| unsafe { shared_payload.set_task_state(hart_id, address_space_id, task_repr, new_state)}
);
// 进入用户态
@ -155,6 +156,8 @@ use core::future::Future;
use core::task::{Context, Poll};
use core::pin::Pin;
use task::TaskState;
impl Future for FibonacciFuture {
type Output = ();

View File

@ -1,4 +1,4 @@
use crate::task::{TaskResult, KernelTask};
use crate::task::{TaskResult, TaskState, KernelTask};
use woke::waker_ref;
use alloc::sync::Arc;
use core::{mem, task::{Poll, Context}};
@ -11,28 +11,24 @@ use core::{mem, task::{Poll, Context}};
pub fn run_until_idle(
peek_task: impl Fn() -> TaskResult,
delete_task: impl Fn(usize) -> bool,
set_task_state: impl Fn(usize, TaskState),
) {
loop {
let task = peek_task();
println!(">>> kernel executor: next task = {:x?}", task);
match task {
TaskResult::Task(task_repr) => {
// 在相同的(内核)地址空间里面
TaskResult::Task(task_repr) => { // 在相同的(内核)地址空间里面
set_task_state(task_repr, TaskState::Sleeping);
let task: Arc<KernelTask> = unsafe { Arc::from_raw(task_repr as *mut _) };
task.mark_sleep();
// make a waker for our task
let waker = waker_ref(&task);
// poll our future and give it a waker
let mut context = Context::from_waker(&*waker);
// println!("Poll begin");
let ret = task.future.lock().as_mut().poll(&mut context);
// println!("Ret = {:?}", ret);
if let Poll::Pending = ret {
set_task_state(task_repr, TaskState::Ready);
mem::forget(task); // 不要释放task的内存它将继续保存在内存中被使用
} else { // 否则释放task的内存
delete_task(task_repr);
// drop(task)
}
} // 隐含一个drop(task)
},
TaskResult::ShouldYield(next_asid) => {
todo!("切换到 next_asid (= {}) 对应的地址空间", next_asid)
@ -41,3 +37,9 @@ pub fn run_until_idle(
}
}
}
impl woke::Woke for KernelTask {
fn wake_by_ref(_task: &Arc<Self>) {
//todo: use set_task_state: impl Fn(usize, TaskState),
}
}

View File

@ -3,8 +3,8 @@ use spin::Mutex;
use core::ops::Range;
use core::future::Future;
use alloc::boxed::Box;
use crate::{hart::KernelHartInfo, memory::VirtualAddress};
use crate::task::{Process, SharedTaskHandle};
use crate::memory::VirtualAddress;
use crate::task::Process;
use core::pin::Pin;
use core::fmt;
use core::sync::atomic::{AtomicUsize, Ordering};
@ -20,7 +20,7 @@ pub struct KernelTask {
/// 任务信息的可变部分
pub inner: Mutex<TaskInner>,
/// 任务的内容
pub future: Mutex<Pin<Box<dyn Future<Output = ()> + 'static + Send + Sync>>> // 用UnsafeCell代替Mutex会好一点
pub future: Mutex<Pin<Box<dyn Future<Output = ()> + 'static + Send + Sync>>>, // 用UnsafeCell代替Mutex会好一点
}
/// 任务的编号
@ -47,10 +47,6 @@ pub struct TaskInner {
///
/// 内核任务复用执行器的栈。用户任务占有一个栈,下一个任务复用此栈。强制中断暂停时,下一个任务使用新分配的栈。
pub stack: Option<Range<VirtualAddress>>,
/// 任务是否正在休眠
pub sleeping: bool,
/// 任务是否已经结束
pub ended: bool,
}
impl KernelTask {
@ -67,8 +63,6 @@ impl KernelTask {
process,
inner: Mutex::new(TaskInner {
stack: None,
sleeping: false,
ended: false,
}),
future: Mutex::new(Box::pin(future)),
})
@ -82,26 +76,6 @@ impl KernelTask {
}
}
impl KernelTask {
fn mark_ready(&self) {
self.inner.lock().sleeping = false;
}
pub(crate) fn is_sleeping(&self) -> bool {
self.inner.lock().sleeping
}
pub(crate) fn mark_sleep(&self) {
self.inner.lock().sleeping = true;
}
}
impl woke::Woke for KernelTask {
fn wake_by_ref(task: &Arc<Self>) {
task.mark_ready();
}
}
impl PartialEq for KernelTask {
fn eq(&self, other: &KernelTask) -> bool {
self.id == other.id
@ -120,11 +94,9 @@ impl fmt::Debug for KernelTask {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let inner = self.inner.lock();
f.debug_struct("KernelTask")
.field("task id", &self.id)
.field("task isd", &self.id)
.field("address space id", &self.process.address_space_id())
.field("stack", &inner.stack)
.field("is_sleeping", &inner.sleeping)
.field("is_ended", &inner.ended)
.finish()
}
}

View File

@ -9,8 +9,8 @@ pub use kernel_task::{KernelTask, TaskId};
pub use process::{Process, ProcessId};
pub use executor::run_until_idle;
pub use shared::{
SharedTaskHandle,
SharedPayload,
TaskState,
kernel_should_switch
};

View File

@ -29,22 +29,17 @@ use core::ptr::NonNull;
use core::mem;
use super::TaskResult;
/// 共享的包含Future在用户空间的地址
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(C)]
pub struct SharedTaskHandle {
/// 运行此任务的硬件线程编号
pub(crate) hart_id: usize,
/// 地址空间的编号
pub(crate) address_space_id: AddressSpaceId,
/// 对每个虚拟空间来说task_ptr是Arc<Task>相应的虚拟地址
/// 比如内核中是内核虚拟地址,用户中是用户的虚拟地址
pub(crate) task_ptr: usize,
/// 任务当前的状态
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[repr(u8)]
pub enum TaskState {
Ready = 0,
Sleeping = 1,
}
pub extern "C" fn kernel_should_switch(handle: &SharedTaskHandle) -> bool {
pub extern "C" fn kernel_should_switch(address_space_id: AddressSpaceId) -> bool {
// 如果当前和下一个任务间地址空间变化了,就说明应当切换上下文
KernelHartInfo::current_address_space_id() != handle.address_space_id
KernelHartInfo::current_address_space_id() != address_space_id
}
/// 共享载荷
@ -52,19 +47,24 @@ pub extern "C" fn kernel_should_switch(handle: &SharedTaskHandle) -> bool {
pub struct SharedPayload {
shared_scheduler: NonNull<()>,
shared_add_task: unsafe extern "C" fn(NonNull<()>, usize, AddressSpaceId, usize) -> bool,
shared_peek_task: unsafe extern "C" fn(NonNull<()>, extern "C" fn(&SharedTaskHandle) -> bool) -> TaskResult,
shared_delete_task: unsafe extern "C" fn(NonNull<()>, usize) -> bool,
shared_peek_task: unsafe extern "C" fn(NonNull<()>, extern "C" fn(AddressSpaceId) -> bool) -> TaskResult,
shared_delete_task: unsafe extern "C" fn(NonNull<()>, usize, AddressSpaceId, usize) -> bool,
shared_set_task_state: unsafe extern "C" fn(NonNull<()>, usize, AddressSpaceId, usize, TaskState),
}
type SharedPayloadAsUsize = [usize; 6]; // 编译时基地址,初始化函数,共享调度器地址,添加函数,弹出函数
unsafe impl Send for SharedPayload {}
unsafe impl Sync for SharedPayload {}
type SharedPayloadAsUsize = [usize; 7]; // 编译时基地址,初始化函数,共享调度器地址,添加函数,弹出函数
type InitFunction = unsafe extern "C" fn() -> PageList;
type SharedPayloadRaw = (
usize, // 编译时基地址,转换后类型占位,不使用
usize, // 初始化函数,执行完之后,内核将函数指针置空
NonNull<()>,
unsafe extern "C" fn(NonNull<()>, usize, AddressSpaceId, usize) -> bool,
unsafe extern "C" fn(NonNull<()>, extern "C" fn(&SharedTaskHandle) -> bool) -> TaskResult,
unsafe extern "C" fn(NonNull<()>, usize) -> bool,
unsafe extern "C" fn(NonNull<()>, usize, AddressSpaceId, usize) -> bool, // 添加任务
unsafe extern "C" fn(NonNull<()>, extern "C" fn(AddressSpaceId) -> bool) -> TaskResult, // 弹出任务
unsafe extern "C" fn(NonNull<()>, usize, AddressSpaceId, usize) -> bool, // 删除任务
unsafe extern "C" fn(NonNull<()>, usize, AddressSpaceId, usize, TaskState), // 改变任务的状态
);
impl SharedPayload {
@ -93,6 +93,7 @@ impl SharedPayload {
shared_add_task: raw_table.3,
shared_peek_task: raw_table.4,
shared_delete_task: raw_table.5,
shared_set_task_state: raw_table.6,
}
}
@ -105,16 +106,22 @@ impl SharedPayload {
}
/// 从共享调度器中得到下一个任务
pub unsafe fn peek_task(&self, should_yield: extern "C" fn(&SharedTaskHandle) -> bool) -> TaskResult {
pub unsafe fn peek_task(&self, should_yield: extern "C" fn(AddressSpaceId) -> bool) -> TaskResult {
let f = self.shared_peek_task;
// println!("Peek = {:x}, p1 = {:p}, p2 = {:x}", f as usize, self.shared_scheduler, should_yield as usize);
f(self.shared_scheduler, should_yield)
}
/// 从共享调度器中删除任务
pub unsafe fn delete_task(&self, task_repr: usize) -> bool {
pub unsafe fn delete_task(&self, hart_id: usize, address_space_id: AddressSpaceId, task_repr: usize) -> bool {
let f = self.shared_delete_task;
f(self.shared_scheduler, task_repr)
f(self.shared_scheduler, hart_id, address_space_id, task_repr)
}
/// 设置一个任务的状态
pub unsafe fn set_task_state(&self, hart_id: usize, address_space_id: AddressSpaceId, task_repr: usize, new_state: TaskState) {
let f = self.shared_set_task_state;
f(self.shared_scheduler, hart_id, address_space_id, task_repr, new_state)
}
}

View File

@ -78,18 +78,20 @@ fn main() -> i32 {
/// 运行一个异步的main函数在用户的entry函数里调用
/// 应该作为标准库的一部分,这里使用一个库函数来模拟有标准库的情况
pub fn execute_async_main(main: impl Future<Output = i32> + Send + Sync + 'static) -> i32 {
let hart_id = 0; // todo!
let shared_payload = unsafe { shared::SharedPayload::new(SHARED_PAYLOAD_BASE) };
let asid = unsafe { shared::AddressSpaceId::from_raw(ADDRESS_SPACE_ID) };
let address_space_id = unsafe { shared::AddressSpaceId::from_raw(ADDRESS_SPACE_ID) };
static mut EXIT_CODE: i32 = 0;
let main_task = task::UserTask::new(async move {
unsafe { EXIT_CODE = main.await };
});
unsafe {
shared_payload.add_task(0/* todo */, asid, main_task.task_repr());
shared_payload.add_task(hart_id, address_space_id, main_task.task_repr());
}
shared::run_until_ready(
|| unsafe { shared_payload.peek_task(shared::user_should_switch) },
|task_repr| unsafe { shared_payload.delete_task(task_repr) }
|task_repr| unsafe { shared_payload.delete_task(hart_id, address_space_id, task_repr) },
|task_repr, new_state| unsafe { shared_payload.set_task_state(hart_id, address_space_id, task_repr, new_state)}
);
unsafe { EXIT_CODE }
}

View File

@ -8,17 +8,6 @@ use alloc::sync::Arc;
use core::{mem, task::{Poll, Context}};
use core::ptr::NonNull;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(C)]
pub struct SharedTaskHandle {
/// 处理核编号
pub(crate) hart_id: usize,
/// 地址空间编号
pub(crate) address_space_id: AddressSpaceId,
/// task_ptr 是 Arc<Task> 的虚拟地址
pub(crate) task_ptr: usize,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[repr(C)]
pub struct AddressSpaceId(u16);
@ -30,26 +19,28 @@ impl AddressSpaceId {
}
}
pub extern "C" fn user_should_switch(_handle: &SharedTaskHandle) -> bool {
false
pub extern "C" fn user_should_switch(_asid: AddressSpaceId) -> bool {
false // todo
}
// 该执行器目前是测试使用,当轮询到一个完成的任务就退出了
pub fn run_until_ready(
peek_task: impl Fn() -> TaskResult,
delete_task: impl Fn(usize) -> bool,
set_task_state: impl Fn(usize, TaskState),
) {
loop {
let task = peek_task();
println!(">>> user executor: next task = {:x?}", task);
match task {
TaskResult::Task(task_repr) => { // 在相同的地址空间里面
set_task_state(task_repr, TaskState::Sleeping);
let task: Arc<UserTask> = unsafe { Arc::from_raw(task_repr as *mut _) };
let waker = waker_ref(&task);
let mut context = Context::from_waker(&*waker);
println!(">>> User executor: task = {:p}", task);
let ret = task.future.lock().as_mut().poll(&mut context);
if let Poll::Pending = ret {
set_task_state(task_repr, TaskState::Ready);
mem::forget(task); // 不要释放task的内存它将继续保存在内存中被使用
} else {
delete_task(task_repr);
@ -66,23 +57,33 @@ pub fn run_until_ready(
}
}
/// 任务当前的状态
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[repr(u8)]
pub enum TaskState {
Ready = 0,
Sleeping = 1,
}
/// 共享载荷
#[repr(C)]
pub struct SharedPayload {
shared_scheduler: NonNull<()>,
shared_add_task: unsafe extern "C" fn(NonNull<()>, usize, AddressSpaceId, usize) -> bool,
shared_peek_task: unsafe extern "C" fn(NonNull<()>, extern "C" fn(&SharedTaskHandle) -> bool) -> TaskResult,
shared_delete_task: unsafe extern "C" fn(NonNull<()>, usize) -> bool,
shared_peek_task: unsafe extern "C" fn(NonNull<()>, extern "C" fn(AddressSpaceId) -> bool) -> TaskResult,
shared_delete_task: unsafe extern "C" fn(NonNull<()>, usize, AddressSpaceId, usize) -> bool,
shared_set_task_state: unsafe extern "C" fn(NonNull<()>, usize, AddressSpaceId, usize, TaskState),
}
type SharedPayloadAsUsize = [usize; 6]; // 编译时基地址,(已清空)初始化函数,共享调度器地址,添加函数,弹出函数
type SharedPayloadAsUsize = [usize; 7]; // 编译时基地址,(已清空)初始化函数,共享调度器地址,添加函数,弹出函数
type SharedPayloadRaw = (
usize, // 编译时基地址,转换后类型占位,不使用
usize, // 初始化函数已清空,不适用
NonNull<()>,
unsafe extern "C" fn(NonNull<()>, usize, AddressSpaceId, usize) -> bool,
unsafe extern "C" fn(NonNull<()>, extern "C" fn(&SharedTaskHandle) -> bool) -> TaskResult,
unsafe extern "C" fn(NonNull<()>, usize) -> bool,
unsafe extern "C" fn(NonNull<()>, usize, AddressSpaceId, usize) -> bool, // 添加任务
unsafe extern "C" fn(NonNull<()>, extern "C" fn(AddressSpaceId) -> bool) -> TaskResult, // 弹出任务
unsafe extern "C" fn(NonNull<()>, usize, AddressSpaceId, usize) -> bool, // 删除任务
unsafe extern "C" fn(NonNull<()>, usize, AddressSpaceId, usize, TaskState), // 改变任务的状态
);
impl SharedPayload {
@ -101,6 +102,7 @@ impl SharedPayload {
shared_add_task: raw_table.3,
shared_peek_task: raw_table.4,
shared_delete_task: raw_table.5,
shared_set_task_state: raw_table.6,
}
}
@ -109,13 +111,17 @@ impl SharedPayload {
f(self.shared_scheduler, hart_id, address_space_id, task_repr)
}
pub unsafe fn peek_task(&self, should_yield: extern "C" fn(&SharedTaskHandle) -> bool) -> TaskResult {
pub unsafe fn peek_task(&self, should_yield: extern "C" fn(AddressSpaceId) -> bool) -> TaskResult {
let f = self.shared_peek_task;
f(self.shared_scheduler, should_yield)
}
pub unsafe fn delete_task(&self, task_repr: usize) -> bool {
pub unsafe fn delete_task(&self, hart_id: usize, address_space_id: AddressSpaceId, task_repr: usize) -> bool {
let f = self.shared_delete_task;
f(self.shared_scheduler, task_repr)
f(self.shared_scheduler, hart_id, address_space_id, task_repr)
}
pub unsafe fn set_task_state(&self, hart_id: usize, address_space_id: AddressSpaceId, task_repr: usize, new_state: TaskState) {
let f = self.shared_set_task_state;
f(self.shared_scheduler, hart_id, address_space_id, task_repr, new_state)
}
}