1 // Copyright (c) 2023 Huawei Device Co., Ltd. 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 //! Asynchronous tasks that wraps the future and get scheduled by the runtime. 15 16 pub mod builder; 17 pub mod join_handle; 18 mod join_set; 19 mod raw; 20 pub(crate) mod state; 21 mod task_handle; 22 mod waker; 23 pub(crate) mod yield_now; 24 use std::future::Future; 25 use std::mem; 26 use std::ptr::NonNull; 27 use std::sync::Weak; 28 29 pub use builder::TaskBuilder; 30 pub use join_handle::JoinHandle; 31 pub use join_set::JoinSet; 32 pub use yield_now::yield_now; 33 34 use crate::executor::Schedule; 35 use crate::task::raw::{Header, RawTask, TaskMngInfo}; 36 37 pub(crate) enum VirtualTableType { 38 Ylong, 39 #[cfg(feature = "ffrt")] 40 Ffrt, 41 } 42 43 #[cfg(not(feature = "ffrt"))] 44 #[derive(Clone, Copy, PartialEq, Eq, Debug)] 45 /// Qos levels. 46 pub enum Qos { 47 /// Inherits parent's qos level 48 Inherent = -1, 49 /// Lowest qos 50 Background, 51 /// Utility qos 52 Utility, 53 /// Default qos 54 Default, 55 /// User initialiated qos 56 UserInitiated, 57 /// Deadline qos 58 DeadlineRequest, 59 /// Highest qos 60 UserInteractive, 61 } 62 63 #[cfg(feature = "ffrt")] 64 pub use ylong_ffrt::Qos; 65 66 #[repr(transparent)] 67 #[derive(Clone)] 68 pub(crate) struct Task(pub(crate) RawTask); 69 70 unsafe impl Send for Task {} 71 unsafe impl Sync for Task {} 72 73 impl Task { run(self)74 pub(crate) fn run(self) { 75 self.0.run(); 76 mem::forget(self); 77 } 78 #[cfg(not(feature = "ffrt"))] shutdown(self)79 pub(crate) fn shutdown(self) { 80 self.0.shutdown(); 81 } 82 } 83 84 impl Task { from_raw(ptr: NonNull<Header>) -> Task85 pub(crate) unsafe fn from_raw(ptr: NonNull<Header>) -> Task { 86 Task(RawTask::form_raw(ptr)) 87 } 88 create_task<T, S>( builder: &TaskBuilder, scheduler: Weak<S>, task: T, virtual_table_type: VirtualTableType, ) -> (Task, JoinHandle<T::Output>) where T: Future + Send + 'static, T::Output: Send + 'static, S: Schedule,89 pub(crate) fn create_task<T, S>( 90 builder: &TaskBuilder, 91 scheduler: Weak<S>, 92 task: T, 93 virtual_table_type: VirtualTableType, 94 ) -> (Task, JoinHandle<T::Output>) 95 where 96 T: Future + Send + 'static, 97 T::Output: Send + 'static, 98 S: Schedule, 99 { 100 let raw = Task::create_raw_task::<T, S>(builder, scheduler, task, virtual_table_type); 101 102 let join = JoinHandle::new(raw); 103 (Task(raw), join) 104 } 105 create_raw_task<T, S>( builder: &TaskBuilder, scheduler: Weak<S>, task: T, virtual_table_type: VirtualTableType, ) -> RawTask where T: Future, S: Schedule,106 pub(crate) fn create_raw_task<T, S>( 107 builder: &TaskBuilder, 108 scheduler: Weak<S>, 109 task: T, 110 virtual_table_type: VirtualTableType, 111 ) -> RawTask 112 where 113 T: Future, 114 S: Schedule, 115 { 116 let ptr = Box::into_raw(TaskMngInfo::<T, S>::new( 117 builder, 118 scheduler, 119 task, 120 virtual_table_type, 121 )); 122 let non_ptr = NonNull::new(ptr as *mut Header); 123 let ptr = if let Some(ptr) = non_ptr { 124 ptr 125 } else { 126 panic!("task mem is null because not enough memory is available"); 127 }; 128 RawTask { ptr } 129 } 130 } 131 132 impl Drop for Task { drop(&mut self)133 fn drop(&mut self) { 134 self.0.drop_ref() 135 } 136 } 137