add do wake in user
This commit is contained in:
parent
cb1fe70c8f
commit
ebc43ad0b3
|
@ -82,9 +82,9 @@ pub fn execute_async_main(main: impl Future<Output = i32> + Send + Sync + 'stati
|
|||
let shared_payload = unsafe { shared::SharedPayload::new(SHARED_PAYLOAD_BASE) };
|
||||
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 {
|
||||
let main_task = task::new_user(async move {
|
||||
unsafe { EXIT_CODE = main.await };
|
||||
});
|
||||
}, shared_payload.shared_scheduler, shared_payload.shared_set_task_state);
|
||||
unsafe {
|
||||
shared_payload.add_task(hart_id, address_space_id, main_task.task_repr());
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ pub fn execute_async_main(main: impl Future<Output = i32> + Send + Sync + 'stati
|
|||
pub fn spawn(future: impl Future<Output = ()> + Send + Sync + 'static) {
|
||||
let shared_payload = unsafe { shared::SharedPayload::new(SHARED_PAYLOAD_BASE) };
|
||||
let asid = unsafe { shared::AddressSpaceId::from_raw(ADDRESS_SPACE_ID) };
|
||||
let task = task::UserTask::new(future);
|
||||
let task = task::new_user(future, shared_payload.shared_scheduler, shared_payload.shared_set_task_state);
|
||||
unsafe {
|
||||
shared_payload.add_task(0/* todo */, asid, task.task_repr());
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use crate::do_yield;
|
||||
use crate::println;
|
||||
use crate::task::UserTaskRepr;
|
||||
|
||||
//! 尝试在用户态给共享调度器添加任务
|
||||
use super::task::{TaskResult, UserTask};
|
||||
use super::task::TaskResult;
|
||||
use woke::waker_ref;
|
||||
use alloc::sync::Arc;
|
||||
use core::{mem, task::{Poll, Context}};
|
||||
|
@ -34,10 +35,10 @@ pub fn run_until_ready(
|
|||
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 task: Arc<UserTaskRepr> = unsafe { Arc::from_raw(task_repr as *mut _) };
|
||||
let waker = waker_ref(&task);
|
||||
let mut context = Context::from_waker(&*waker);
|
||||
let ret = task.future.lock().as_mut().poll(&mut context);
|
||||
let ret = task.task().future.lock().as_mut().poll(&mut context);
|
||||
if let Poll::Pending = ret {
|
||||
mem::forget(task); // 不要释放task的内存,它将继续保存在内存中被使用
|
||||
} else {
|
||||
|
@ -67,11 +68,11 @@ pub enum TaskState {
|
|||
/// 共享载荷
|
||||
#[repr(C)]
|
||||
pub struct SharedPayload {
|
||||
shared_scheduler: NonNull<()>,
|
||||
pub(crate)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(AddressSpaceId) -> bool) -> TaskResult,
|
||||
shared_delete_task: unsafe extern "C" fn(NonNull<()>, usize) -> bool,
|
||||
shared_set_task_state: unsafe extern "C" fn(NonNull<()>, usize, TaskState),
|
||||
pub(crate)shared_set_task_state: unsafe extern "C" fn(NonNull<()>, usize, TaskState),
|
||||
}
|
||||
|
||||
type SharedPayloadAsUsize = [usize; 7]; // 编译时基地址,(已清空)初始化函数,共享调度器地址,添加函数,弹出函数
|
||||
|
|
|
@ -13,9 +13,10 @@ use core::pin::Pin;
|
|||
use alloc::boxed::Box;
|
||||
use core::future::Future;
|
||||
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
use core::ptr::NonNull;
|
||||
use core::fmt;
|
||||
use super::shared::TaskState;
|
||||
/// 临时的用户态任务实现
|
||||
|
||||
pub struct UserTask {
|
||||
/// 任务的编号
|
||||
pub id: UserTaskId,
|
||||
|
@ -26,6 +27,7 @@ pub struct UserTask {
|
|||
}
|
||||
|
||||
/// 任务信息的可变部分
|
||||
#[derive(Debug)]
|
||||
pub struct UserTaskInner {
|
||||
/// 任务是否在休眠
|
||||
pub sleeping: bool,
|
||||
|
@ -54,11 +56,10 @@ impl UserTask {
|
|||
/// 创建一个用户态任务
|
||||
pub fn new(
|
||||
future: impl Future<Output = ()> + 'static + Send + Sync,
|
||||
) -> Arc<UserTask> {
|
||||
) -> UserTask {
|
||||
// 得到新的用户任务编号
|
||||
let id = UserTaskId::generate();
|
||||
// 打包成用户态任务
|
||||
Arc::new(
|
||||
UserTask {
|
||||
id,
|
||||
inner: Mutex::new(UserTaskInner {
|
||||
|
@ -67,33 +68,18 @@ impl UserTask {
|
|||
}),
|
||||
future: Mutex::new(Box::pin(future))
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/// 转换到共享的任务编号
|
||||
/// 危险:创建了一个没有边界的生命周期
|
||||
|
||||
pub unsafe fn task_repr(self: Arc<Self>) -> usize {
|
||||
Arc::into_raw(self) as usize
|
||||
}
|
||||
}
|
||||
|
||||
impl UserTask {
|
||||
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 UserTask {
|
||||
fn wake_by_ref(task: &Arc<Self>) {
|
||||
task.mark_ready();
|
||||
impl fmt::Debug for UserTask {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let inner = self.inner.lock();
|
||||
f.debug_struct("UserTask")
|
||||
.field("task_id", &self.id)
|
||||
.field("is sleeping", &inner.sleeping)
|
||||
.field("is finished", &inner.finished)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,3 +95,48 @@ pub enum TaskResult {
|
|||
/// 队列已空,所有任务已经结束
|
||||
Finished,
|
||||
}
|
||||
|
||||
// 创建一个新的用户任务,打包它的环境
|
||||
pub fn new_user(
|
||||
future: impl Future<Output = ()> + 'static + Send + Sync,
|
||||
shared_scheduler: NonNull<()>,
|
||||
set_task_state: unsafe extern "C" fn(NonNull<()>, usize, TaskState)
|
||||
) -> Arc<UserTaskRepr> {
|
||||
Arc::new(
|
||||
UserTaskRepr(
|
||||
UserTask::new(future),
|
||||
shared_scheduler.as_ptr() as usize,
|
||||
set_task_state
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct UserTaskRepr (
|
||||
UserTask, usize,
|
||||
unsafe extern "C" fn(NonNull<()>, usize, TaskState)
|
||||
);
|
||||
|
||||
impl UserTaskRepr {
|
||||
/// 转换到共享的任务编号
|
||||
///
|
||||
/// note(unsafe): 创建了一个没有边界的生命周期
|
||||
pub unsafe fn task_repr(self: Arc<Self>) -> usize {
|
||||
Arc::into_raw(self) as usize
|
||||
}
|
||||
pub unsafe fn do_wake(self: &Arc<Self>) {
|
||||
let shared_scheduler = NonNull::new(self.1 as *mut()).unwrap();
|
||||
let task_repr = Arc::as_ptr(self) as usize;
|
||||
(self.2)(shared_scheduler, task_repr, TaskState::Ready)
|
||||
}
|
||||
#[inline] pub fn task(&self) -> &UserTask {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl woke::Woke for UserTaskRepr {
|
||||
fn wake_by_ref(task: &Arc<Self>) {
|
||||
unsafe { task.do_wake() }
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue