diff --git a/tornado-user/src/lib.rs b/tornado-user/src/lib.rs index 3d523ce..6545349 100644 --- a/tornado-user/src/lib.rs +++ b/tornado-user/src/lib.rs @@ -82,9 +82,9 @@ pub fn execute_async_main(main: impl Future + 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 + Send + Sync + 'stati pub fn spawn(future: impl Future + 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()); } diff --git a/tornado-user/src/shared.rs b/tornado-user/src/shared.rs index 708e70e..104d054 100644 --- a/tornado-user/src/shared.rs +++ b/tornado-user/src/shared.rs @@ -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 = unsafe { Arc::from_raw(task_repr as *mut _) }; + let task: Arc = 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]; // 编译时基地址,(已清空)初始化函数,共享调度器地址,添加函数,弹出函数 diff --git a/tornado-user/src/task.rs b/tornado-user/src/task.rs index ed6ff41..0f8f2b0 100644 --- a/tornado-user/src/task.rs +++ b/tornado-user/src/task.rs @@ -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,46 +56,30 @@ impl UserTask { /// 创建一个用户态任务 pub fn new( future: impl Future + 'static + Send + Sync, - ) -> Arc { + ) -> UserTask { // 得到新的用户任务编号 let id = UserTaskId::generate(); // 打包成用户态任务 - Arc::new( - UserTask { - id, - inner: Mutex::new(UserTaskInner { - sleeping: false, - finished: false, - }), - future: Mutex::new(Box::pin(future)) - } - ) - } - - /// 转换到共享的任务编号 - /// 危险:创建了一个没有边界的生命周期 - - pub unsafe fn task_repr(self: Arc) -> usize { - Arc::into_raw(self) as usize + UserTask { + id, + inner: Mutex::new(UserTaskInner { + sleeping: false, + finished: false, + }), + future: Mutex::new(Box::pin(future)) + } } } -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) { - 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 + 'static + Send + Sync, + shared_scheduler: NonNull<()>, + set_task_state: unsafe extern "C" fn(NonNull<()>, usize, TaskState) +) -> Arc { + 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) -> usize { + Arc::into_raw(self) as usize + } + pub unsafe fn do_wake(self: &Arc) { + 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) { + unsafe { task.do_wake() } + } +} \ No newline at end of file