1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
use crate::task::Task; use alloc::sync::Arc; use core::{ mem::{self, ManuallyDrop}, task::{RawWaker, RawWakerVTable, Waker}, }; struct FakeWaker { waker: FakeRawWaker, } struct FakeRawWaker { data: *const (), _vtable: &'static RawWakerVTable, } pub(crate) fn get_task(waker: &Waker) -> Arc<Task> { let waker: &FakeWaker = unsafe { mem::transmute(waker) }; if waker.waker._vtable != waker_vtable() { panic!("not waker from ksched"); } else if waker.waker.data.is_null() { panic!("task has been taken"); } let arc_task = unsafe { Arc::from_raw(waker.waker.data as *const Task) }; let task_ref = ManuallyDrop::new(arc_task); (*task_ref).clone() } pub(crate) fn waker(task: Arc<Task>) -> Waker { let ptr = Arc::into_raw(task) as *const (); unsafe { Waker::from_raw(RawWaker::new(ptr, waker_vtable())) } } fn waker_vtable() -> &'static RawWakerVTable { &RawWakerVTable::new( clone_arc_raw, wake_arc_raw, wake_by_ref_arc_raw, drop_arc_raw, ) } unsafe fn clone_arc_raw(_data: *const ()) -> RawWaker { unimplemented!(); } unsafe fn wake_arc_raw(_data: *const ()) { unimplemented!(); } unsafe fn wake_by_ref_arc_raw(_data: *const ()) { unimplemented!(); } unsafe fn drop_arc_raw(data: *const ()) { drop(Arc::from_raw(data as *const Task)) }