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 use std::ffi::{CStr, CString};
15 
16 use libc::{c_char, c_void};
17 
18 use super::*;
19 
20 type FfrtHook = extern "C" fn(*mut c_void);
21 
22 type FfrtExecHook = extern "C" fn(*mut c_void) -> FfrtRet;
23 
24 type RawTaskCtx = *mut c_void;
25 
26 /// Return value.
27 #[repr(C)]
28 pub enum FfrtRet {
29     /// Asynchronous task result pending.
30     FfrtCoroutinePending,
31     /// Asynchronous task result is ready.
32     FfrtCoroutineReady,
33 }
34 
35 impl Default for FfrtTaskAttr {
default() -> Self36     fn default() -> Self {
37         Self::new()
38     }
39 }
40 
41 impl FfrtTaskAttr {
42     /// Creates a default task attribute.
new() -> Self43     pub fn new() -> Self {
44         Self { storage: [0; 128] }
45     }
46 
47     /// Initializes the task attribute
init(&mut self)48     pub fn init(&mut self) {
49         let attr = self as *mut FfrtTaskAttr;
50         unsafe {
51             ffrt_task_attr_init(attr);
52         }
53     }
54 
55     /// Sets the name for the task attribute.
set_name(&mut self, name: &str) -> &mut Self56     pub fn set_name(&mut self, name: &str) -> &mut Self {
57         let attr_ptr = self as *mut FfrtTaskAttr;
58         let c_name = CString::new(name).expect("FfrtTaskAttr::set_name failed");
59         unsafe {
60             ffrt_task_attr_set_name(attr_ptr, c_name.as_ptr());
61         }
62         self
63     }
64 
65     /// Gets the name from the task attribtue.
get_name(&self) -> String66     pub fn get_name(&self) -> String {
67         let attr_ptr = self as *const FfrtTaskAttr;
68         unsafe {
69             let c_name = ffrt_task_attr_get_name(attr_ptr);
70             CStr::from_ptr(c_name)
71                 .to_str()
72                 .expect("FfrtTaskAttr::get_name failed")
73                 .to_string()
74         }
75     }
76 
77     /// Sets qos level for the task attribute.
set_qos(&mut self, qos: Qos) -> &mut Self78     pub fn set_qos(&mut self, qos: Qos) -> &mut Self {
79         unsafe {
80             let ptr = self as *mut FfrtTaskAttr;
81             ffrt_task_attr_set_qos(ptr, qos);
82         }
83         self
84     }
85 
86     /// Gets the qos level from the task attribute.
get_qos(&self) -> Qos87     pub fn get_qos(&self) -> Qos {
88         unsafe { ffrt_task_attr_get_qos(self as _) }
89     }
90 }
91 
92 impl Drop for FfrtTaskAttr {
drop(&mut self)93     fn drop(&mut self) {
94         unsafe {
95             ffrt_task_attr_destroy(self as _);
96         }
97     }
98 }
99 
100 #[link(name = "ffrt")]
101 // task.h
102 extern "C" {
103     #![allow(unused)]
104 
ffrt_task_attr_init(attr: *mut FfrtTaskAttr)105     fn ffrt_task_attr_init(attr: *mut FfrtTaskAttr);
ffrt_task_attr_set_name(attr: *mut FfrtTaskAttr, name: *const c_char)106     fn ffrt_task_attr_set_name(attr: *mut FfrtTaskAttr, name: *const c_char);
ffrt_task_attr_get_name(attr: *const FfrtTaskAttr) -> *const c_char107     fn ffrt_task_attr_get_name(attr: *const FfrtTaskAttr) -> *const c_char;
ffrt_task_attr_destroy(attr: *mut FfrtTaskAttr)108     fn ffrt_task_attr_destroy(attr: *mut FfrtTaskAttr);
ffrt_task_attr_set_qos(attr: *mut FfrtTaskAttr, qos: Qos)109     fn ffrt_task_attr_set_qos(attr: *mut FfrtTaskAttr, qos: Qos);
ffrt_task_attr_get_qos(attr: *const FfrtTaskAttr) -> Qos110     fn ffrt_task_attr_get_qos(attr: *const FfrtTaskAttr) -> Qos;
111 
112     // submit
ffrt_alloc_auto_free_function_storage_base() -> *const c_void113     fn ffrt_alloc_auto_free_function_storage_base() -> *const c_void;
114 
115     /// Submits a task.
ffrt_submit_coroutine( data: *mut c_void, fp: FfrtExecHook, destroy_fp: FfrtHook, in_deps: *const FfrtDeps, out_deps: *const FfrtDeps, attr: *const FfrtTaskAttr, )116     pub fn ffrt_submit_coroutine(
117         // void* callable
118         data: *mut c_void,
119         // ffrt_function_tdd exec
120         fp: FfrtExecHook,
121         // ffrt_function_t destroy
122         destroy_fp: FfrtHook,
123         // const ffrt_deps_t* out_deps,
124         in_deps: *const FfrtDeps,
125         // const ffrt_deps_t* out_deps,
126         out_deps: *const FfrtDeps,
127         // const ffrt_task_attr_t* att
128         attr: *const FfrtTaskAttr,
129     );
130 
131     /// Gets the current task context.
ffrt_get_current_task() -> RawTaskCtx132     pub fn ffrt_get_current_task() -> RawTaskCtx;
133 
134     /// Wakes the task
ffrt_wake_coroutine(task: RawTaskCtx)135     pub fn ffrt_wake_coroutine(task: RawTaskCtx);
136 }
137