1484543d1Sopenharmony_ci## FFRT 用户编程指南
2484543d1Sopenharmony_ci
3484543d1Sopenharmony_ci> Function Flow编程模型是一种基于任务和数据驱动的并发编程模型,允许开发者通过任务及其依赖关系描述的方式进行应用开发。FFRT(Function Flow运行时)是支持Function Flow编程模型的软件运行时库,用于调度执行开发者基于Function Flow编程模型开发的应用。通过Function Flow编程模型和FFRT,开发者可专注于应用功能开发,由FFRT在运行时根据任务依赖状态和可用执行资源自动并发调度和执行任务。
4484543d1Sopenharmony_ci>
5484543d1Sopenharmony_ci> 本文用于指导开发者基于Function Flow编程模型和FFRT实现并行编程。
6484543d1Sopenharmony_ci
7484543d1Sopenharmony_ci<hr/>
8484543d1Sopenharmony_ci# 版本
9484543d1Sopenharmony_ci
10484543d1Sopenharmony_ci| 版本 | 编辑                                                         | 主要变更                                                     | 日期       |
11484543d1Sopenharmony_ci| ---- | ------------------------------------------------------------ | ------------------------------------------------------------ | ---------- |
12484543d1Sopenharmony_ci| V0.1 | linjiashu <br />zhangguowei <br />huangyouzhong  | 发布以下API:<br />1. task 管理,包括:submit,wait,task_attr, task_handle/submit_h<br />2. 同步原语,包括:mutex,shared_mutex, condition_variable<br />3. Deadline 调度<br />4. 杂项:sleep,yield<br /> | 2022/09/26 |
13484543d1Sopenharmony_ci| V0.1.1 | shengxia  | 部分描述更新 | 2023/08/24 |
14484543d1Sopenharmony_ci| V0.1.2 | wanghuachen  | 新增串行队列相关接口以及说明,增加规范以避免double free问题 | 2023/10/07 |
15484543d1Sopenharmony_ci| V0.1.3 | shengxia  | 优化串行队列内容描述 | 2024/01/12 |
16484543d1Sopenharmony_ci
17484543d1Sopenharmony_ci<br/>
18484543d1Sopenharmony_ci
19484543d1Sopenharmony_ci<hr/>
20484543d1Sopenharmony_ci# 缩写
21484543d1Sopenharmony_ci
22484543d1Sopenharmony_ci| 缩略语        | 英文全名                        | 中文解释                                                     |
23484543d1Sopenharmony_ci| ------------- | ------------------------------- | ------------------------------------------------------------ |
24484543d1Sopenharmony_ci| FFRT          | Function Flow Run Time          | 软件实现Function Flow运行时用于任务调度和执行                |
25484543d1Sopenharmony_ci| Function Flow | Function Flow Programming Model | Function Flow编程模型                                        |
26484543d1Sopenharmony_ci| Pure Function | Pure Function                   | 纯函数,注意本文中定义的纯函数指的是通过表达相互间数据依赖即可由调度系统保证正确执行的任务。 |
27484543d1Sopenharmony_ci
28484543d1Sopenharmony_ci
29484543d1Sopenharmony_ci<br/>
30484543d1Sopenharmony_ci<hr/>
31484543d1Sopenharmony_ci# 编程模型
32484543d1Sopenharmony_ci## 两种编程模型
33484543d1Sopenharmony_ci
34484543d1Sopenharmony_ci|                | 线程编程模型                                                 | FFRT任务编程模型                                             |
35484543d1Sopenharmony_ci| -------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
36484543d1Sopenharmony_ci| 并行度挖掘方式 | 程序员通过创建多线程并把任务分配到每个线程中执行来挖掘运行时的并行度 | 程序员(编译器工具或语言特性配合)静态编程时将应用分解成任务及其数据依赖关系,运行时调度器分配任务到工作线程执行 |
37484543d1Sopenharmony_ci| 谁负责线程创建 | 程序员负责创建线程,线程编程模型无法约束线程的创建,滥用可能造成系统中大量线程 | FFRT运行时负责工作线程池的创建和管理由调度器负责,程序员无法直接创建线程 |
38484543d1Sopenharmony_ci| 负载均衡       | 程序员静态编程时将任务映射到线程,映射不合理或任务执行时间不确定造成线程负载不均 | FFRT运行时根据线程执行状态调度就绪任务到空闲线程执行,减轻了线程负载不均问题 |
39484543d1Sopenharmony_ci| 调度开销       | 线程调度由内核态调度器完成,调度开销大                       | FFRT运行时在用户态以协程方式调度执行,相比内核线程调度机制更为轻量,减小调度的开销,并可通过硬化调度卸载进一步减小调度开销 |
40484543d1Sopenharmony_ci| 依赖表达       | 线程创建时即处于可执行状态,执行时与其他线程同步操作,增加线程切换 | FFRT运行时根据任务创建时显式表达的输入依赖和输出依赖关系判断任务可执行状态,当输入依赖不满足时,任务不被调度执行 |
41484543d1Sopenharmony_ci
42484543d1Sopenharmony_ci
43484543d1Sopenharmony_ci
44484543d1Sopenharmony_ci## Function Flow 任务编程模型
45484543d1Sopenharmony_ci
46484543d1Sopenharmony_ciFunction Flow编程模型允许开发者通过任务及其依赖关系描述的方式进行应用开发,其主要特性包括`Task-Based` 和 `Data-Driven` 。
47484543d1Sopenharmony_ci
48484543d1Sopenharmony_ci### Task-Based 特性
49484543d1Sopenharmony_ci
50484543d1Sopenharmony_ci`Task-Based` 指在Function Flow编程模型中开发者以任务方式来组织应用程序表达,运行时以任务粒度执行调度。
51484543d1Sopenharmony_ci
52484543d1Sopenharmony_ci任务定义为一种面向开发者的编程线索和面向运行时的执行对象,通常包含一组指令序列及其操作的数据上下文环境。
53484543d1Sopenharmony_ci
54484543d1Sopenharmony_ciFunction Flow编程模型中的任务包含以下主要特征:
55484543d1Sopenharmony_ci
56484543d1Sopenharmony_ci- 任务之间可指定依赖关系,依赖关系通过`Data-Driven`方式表达。
57484543d1Sopenharmony_ci- 任务可支持嵌套,即任务在执行过程中可生成新的任务下发给运行时,形成父子任务关系。
58484543d1Sopenharmony_ci- 多任务支持互同步操作,例如等待,锁,条件变量等。
59484543d1Sopenharmony_ci
60484543d1Sopenharmony_ci> 注意
61484543d1Sopenharmony_ci>
62484543d1Sopenharmony_ci> 任务颗粒度影响应用执行性能,颗粒度过小增加调度开销,颗粒度过大降低并行度。Function Flow编程模型中任务的目标颗粒度最小为100us量级,开发者应注意合理控制任务颗粒度。
63484543d1Sopenharmony_ci
64484543d1Sopenharmony_ci### Data-Driven 特性
65484543d1Sopenharmony_ci
66484543d1Sopenharmony_ci`Data-Driven`指任务之间的依赖关系通过数据依赖表达。
67484543d1Sopenharmony_ci
68484543d1Sopenharmony_ci任务执行过程中对其关联的数据对象进行读写操作。在Function Flow编程模型中,数据对象表达抽象为数据签名,每个数据签名唯一对应一个数据对象。
69484543d1Sopenharmony_ci
70484543d1Sopenharmony_ci数据依赖抽象为任务所操作的数据对象的数据签名列表,包括输入数据依赖`in_deps`和输出数据依赖`out_deps`。数据对象的签名出现在一个任务的`in_deps`中时,该任务称为数据对象的消费者任务,消费者任务执行不改变其输入数据对象的内容;数据对象的签名出现在任务的`out_deps`中时,该任务称为数据对象的生产者任务,生产者任务执行改变其输出数据对象的内容,从而生成该数据对象的一个新的版本。
71484543d1Sopenharmony_ci
72484543d1Sopenharmony_ci一个数据对象可能存在多个版本,每个版本对应一个生产者任务和零个,一个或多个消费者任务,根据生产者任务和消费者任务的下发顺序定义数据对象的多个版本的顺序以及每个版本所对应的生产者和消费者任务。
73484543d1Sopenharmony_ci
74484543d1Sopenharmony_ci数据依赖解除的任务进入就绪状态允许被调度执行,依赖解除状态指任务所有输入数据对象版本的生产者任务执行完成,且所有输出数据对象版本的所有消费者任务执行完成的状态。
75484543d1Sopenharmony_ci
76484543d1Sopenharmony_ci通过上述`Data-Driven`的数据依赖表达,FFRT在运行时可动态构建任务之间的基于生产者/消费者的数据依赖关系并遵循任务数据依赖状态执行调度,包括:
77484543d1Sopenharmony_ci
78484543d1Sopenharmony_ci- Producer-Consumer 依赖
79484543d1Sopenharmony_ci
80484543d1Sopenharmony_ci  一个数据对象版本的生产者任务和该数据对象版本的消费者任务之间形成的依赖关系,也称为Read-after-Write依赖。
81484543d1Sopenharmony_ci
82484543d1Sopenharmony_ci- Consumer-Producer 依赖
83484543d1Sopenharmony_ci
84484543d1Sopenharmony_ci  一个数据对象版本的消费者任务和该数据对象的下一个版本的生产者任务之间形成的依赖关系,也称为Write-after-Read依赖。
85484543d1Sopenharmony_ci
86484543d1Sopenharmony_ci- Producer-Producer 依赖
87484543d1Sopenharmony_ci
88484543d1Sopenharmony_ci  一个数据对象版本的生产者任务和该数据对象的下一个版本的生产者任务之间形成的依赖关系,也称为Write-after-Write依赖。
89484543d1Sopenharmony_ci
90484543d1Sopenharmony_ci
91484543d1Sopenharmony_ci例如,如果有这么一些任务,与数据A的关系表述为:
92484543d1Sopenharmony_ci```{.cpp}
93484543d1Sopenharmony_citask1(OUT A);
94484543d1Sopenharmony_citask2(IN A);
95484543d1Sopenharmony_citask3(IN A);
96484543d1Sopenharmony_citask4(OUT A);
97484543d1Sopenharmony_citask5(OUT A);
98484543d1Sopenharmony_ci```
99484543d1Sopenharmony_ci
100484543d1Sopenharmony_ci<img src="images/image-20220926150341102.png" style="zoom:60%" />
101484543d1Sopenharmony_ci
102484543d1Sopenharmony_ci> 为表述方便,本文中的数据流图均以圆圈表示 Task,方块表示数据。
103484543d1Sopenharmony_ci
104484543d1Sopenharmony_ci可以得出以下结论:
105484543d1Sopenharmony_ci- task1 与task2/task3 构成Producer-Consumer 依赖,即:task2/task3 需要等到task1 写完A之后才能读A
106484543d1Sopenharmony_ci- task2/task3 与task4 构成Consumer-Producer 依赖,即:task4 需要等到task2/task3 读完A之后才能写A
107484543d1Sopenharmony_ci- task4 与task5 构成Producer-Producer 依赖,即:task5 需要等到task4 写完A之后才能写A
108484543d1Sopenharmony_ci
109484543d1Sopenharmony_ci
110484543d1Sopenharmony_ci
111484543d1Sopenharmony_ci# C++ API
112484543d1Sopenharmony_ci
113484543d1Sopenharmony_ci> C++ API采用接近C++11的命名风格,以`ffrt`命名空间替代`std`命名空间
114484543d1Sopenharmony_ci> 需编译使用-std=c++17
115484543d1Sopenharmony_ci
116484543d1Sopenharmony_ci## 任务管理
117484543d1Sopenharmony_ci### submit
118484543d1Sopenharmony_ci<hr/>
119484543d1Sopenharmony_ci* 向调度器提交一个task
120484543d1Sopenharmony_ci* 该接口是异步的,即该接口不等到task完成即可返回,因此,通常与[wait](#wait) 配合使用
121484543d1Sopenharmony_ci
122484543d1Sopenharmony_ci* 建议FFRT任务上下文使用ffrt::mutex替代std::mutex
123484543d1Sopenharmony_ci  * API上,二者仅在命令空间上有差异,可平滑替换(ffrt::mutex可在非ffrt task中调用,效果与普通的锁一致)
124484543d1Sopenharmony_ci  * ffrt::mutex相对std::mutex开销更小,且不会阻塞FFRT的worker线程(提交到FFRT的任务中大量使用std::mutex有FFRT worker线程被耗尽而死锁的风险)
125484543d1Sopenharmony_ci
126484543d1Sopenharmony_ci#### 声明
127484543d1Sopenharmony_ci
128484543d1Sopenharmony_ci```{.cpp}
129484543d1Sopenharmony_cinamespace ffrt {
130484543d1Sopenharmony_civoid submit(std::function<void()>&& func, const std::vector<const void*>& in_deps = {}, const std::vector<const void*>& out_deps = {}, const task_attr& attr = {});
131484543d1Sopenharmony_civoid submit(const std::function<void()>& func, const std::vector<const void*>& in_deps = {}, const std::vector<const void*>& out_deps = {}, const task_attr& attr = {});
132484543d1Sopenharmony_ci}
133484543d1Sopenharmony_ci```
134484543d1Sopenharmony_ci
135484543d1Sopenharmony_ci#### 参数
136484543d1Sopenharmony_ci
137484543d1Sopenharmony_ci`func`
138484543d1Sopenharmony_ci
139484543d1Sopenharmony_ci* 可被std::function 接收的一切CPU 可执行体,可以为C++ 定义的Lambda 函数闭包,函数指针,甚至是函数对象
140484543d1Sopenharmony_ci
141484543d1Sopenharmony_ci`in_deps`
142484543d1Sopenharmony_ci
143484543d1Sopenharmony_ci* 该参数是可选的
144484543d1Sopenharmony_ci* 该参数用于描述该任务的输入依赖,FFRT 通过数据的虚拟地址作为数据的Signature 来建立依赖
145484543d1Sopenharmony_ci
146484543d1Sopenharmony_ci`out_deps`
147484543d1Sopenharmony_ci
148484543d1Sopenharmony_ci* 该参数是可选的
149484543d1Sopenharmony_ci* 该参数用于描述该任务的输出依赖
150484543d1Sopenharmony_ci* `注意`:该依赖值本质上是一个数值,ffrt没办法区分该值是合理的还是不合理的,会假定输入的值是合理的进行处理;但不建议采用NULL,1, 2 等值来建立依赖关系,建议采用实际的内存地址,因为前者使用不当会建立起不必要的依赖,影响并发
151484543d1Sopenharmony_ci
152484543d1Sopenharmony_ci`attr`
153484543d1Sopenharmony_ci
154484543d1Sopenharmony_ci* 该参数是可选的
155484543d1Sopenharmony_ci* 该参数用于描述Task 的属性,比如qos 等,详见 [task_attr](#task_attr)章节
156484543d1Sopenharmony_ci
157484543d1Sopenharmony_ci#### 返回值
158484543d1Sopenharmony_ci
159484543d1Sopenharmony_ci* 不涉及
160484543d1Sopenharmony_ci
161484543d1Sopenharmony_ci#### 描述
162484543d1Sopenharmony_ci* 该接口支持在FFRT task 内部调用,也支持在FFRT task 外部调用
163484543d1Sopenharmony_ci
164484543d1Sopenharmony_ci* 该接口支持嵌套调用,即任务中可以继续提交子任务
165484543d1Sopenharmony_ci
166484543d1Sopenharmony_ci* 该接口在实现上使用多个重载版本以优化性能(基于移动语义,初始化列表等),用户只需按上述原型使用,编译时会自动选择最佳版本,支持的重载版本有:
167484543d1Sopenharmony_ci
168484543d1Sopenharmony_ci  ```{.cpp}
169484543d1Sopenharmony_ci  void submit(std::function<void()>&& func);
170484543d1Sopenharmony_ci  void submit(std::function<void()>&& func, std::initializer_list<const void*> in_deps);
171484543d1Sopenharmony_ci  void submit(std::function<void()>&& func, std::initializer_list<const void*> in_deps, std::initializer_list<const void*> out_deps);
172484543d1Sopenharmony_ci  void submit(std::function<void()>&& func, std::initializer_list<const void*> in_deps, std::initializer_list<const void*> out_deps, const task_attr& attr);
173484543d1Sopenharmony_ci  
174484543d1Sopenharmony_ci  void submit(std::function<void()>&& func, const std::vector<const void*>& in_deps);
175484543d1Sopenharmony_ci  void submit(std::function<void()>&& func, const std::vector<const void*>& in_deps, const std::vector<const void*>& out_deps);
176484543d1Sopenharmony_ci  void submit(std::function<void()>&& func, const std::vector<const void*>& in_deps, const std::vector<const void*>& out_deps, const task_attr& attr);
177484543d1Sopenharmony_ci  
178484543d1Sopenharmony_ci  void submit(const std::function<void()>& func);
179484543d1Sopenharmony_ci  void submit(const std::function<void()>& func, std::initializer_list<const void*> in_deps);
180484543d1Sopenharmony_ci  void submit(const std::function<void()>& func, std::initializer_list<const void*> in_deps, std::initializer_list<const void*> out_deps);
181484543d1Sopenharmony_ci  void submit(const std::function<void()>& func, std::initializer_list<const void*> in_deps, std::initializer_list<const void*> out_deps, const task_attr& attr);
182484543d1Sopenharmony_ci  
183484543d1Sopenharmony_ci  void submit(const std::function<void()>& func, const std::vector<const void*>& in_deps);
184484543d1Sopenharmony_ci  void submit(const std::function<void()>& func, const std::vector<const void*>& in_deps, const std::vector<const void*>& out_deps);
185484543d1Sopenharmony_ci  void submit(const std::function<void()>& func, const std::vector<const void*>& in_deps, const std::vector<const void*>& out_deps, const task_attr& attr);
186484543d1Sopenharmony_ci  ```
187484543d1Sopenharmony_ci
188484543d1Sopenharmony_ci
189484543d1Sopenharmony_ci#### 样例
190484543d1Sopenharmony_ci
191484543d1Sopenharmony_ci**submit and wait**
192484543d1Sopenharmony_ci
193484543d1Sopenharmony_ci```{.cpp}
194484543d1Sopenharmony_ci#include <iostream>
195484543d1Sopenharmony_ci#include "ffrt.h"
196484543d1Sopenharmony_ci
197484543d1Sopenharmony_ciint main(int narg, char** argv)
198484543d1Sopenharmony_ci{
199484543d1Sopenharmony_ci    int i = 0;
200484543d1Sopenharmony_ci    for (i = 0; i < 3; i++) {
201484543d1Sopenharmony_ci        ffrt::submit([i] { std::cout << "num: " << i << std::endl; });
202484543d1Sopenharmony_ci    }
203484543d1Sopenharmony_ci    ffrt::wait();
204484543d1Sopenharmony_ci    return 0;
205484543d1Sopenharmony_ci}
206484543d1Sopenharmony_ci```
207484543d1Sopenharmony_ci
208484543d1Sopenharmony_ci`解析`:
209484543d1Sopenharmony_ci
210484543d1Sopenharmony_ci1)   该示例中连续下发了3个Task,Task 使用C++ 11 Lambda 来描述(实际中Task 还可以使用函数指针,函数对象来描述),这些 Task 都会读取i,但是不会写任何变量;
211484543d1Sopenharmony_ci
212484543d1Sopenharmony_ci2)   ffrt::submit 为异步下发,因此,Task2 并不会等到 Task1 执行完成之后再下发;
213484543d1Sopenharmony_ci
214484543d1Sopenharmony_ci3)   ffrt::wait 用于实现待所有Task 都执行完成之后 main 函数再退出;
215484543d1Sopenharmony_ci
216484543d1Sopenharmony_ci4)   由于3个Task 在数据依赖关系上没有生产者-消费者或生产者-生产者依赖关系,因此3个 Task 是可以并行的,1种可能的输出是:
217484543d1Sopenharmony_ci
218484543d1Sopenharmony_ci```{.cpp}
219484543d1Sopenharmony_cinum: 0   
220484543d1Sopenharmony_cinum: 2
221484543d1Sopenharmony_cinum: 1
222484543d1Sopenharmony_ci```
223484543d1Sopenharmony_ci
224484543d1Sopenharmony_ci`注意`:
225484543d1Sopenharmony_ci
226484543d1Sopenharmony_ci如果将Lambda 表达式中的值捕获设置成引用捕获(即`[&i] { std::cout << "num: " << i << std::endl; }`),可能得到的输出为:
227484543d1Sopenharmony_ci
228484543d1Sopenharmony_ci```{.cpp}
229484543d1Sopenharmony_cinum: 2
230484543d1Sopenharmony_cinum: 2
231484543d1Sopenharmony_cinum: 2
232484543d1Sopenharmony_ci```
233484543d1Sopenharmony_ci
234484543d1Sopenharmony_ci这是因为FFRT 是异步编程模型,在第一个task 真正开始执行的时候,i 的值可能已经被修改为1或者2
235484543d1Sopenharmony_ci
236484543d1Sopenharmony_ci 
237484543d1Sopenharmony_ci
238484543d1Sopenharmony_ci**data verison**
239484543d1Sopenharmony_ci
240484543d1Sopenharmony_ci<img src="images/image-20220926150341102.png" style="zoom:60%" />
241484543d1Sopenharmony_ci
242484543d1Sopenharmony_ci```{.cpp}
243484543d1Sopenharmony_ci#include <iostream>
244484543d1Sopenharmony_ci#include "ffrt.h"
245484543d1Sopenharmony_ci
246484543d1Sopenharmony_ciint main(int narg, char** argv)
247484543d1Sopenharmony_ci{
248484543d1Sopenharmony_ci    int x = 1;
249484543d1Sopenharmony_ci    ffrt::submit([&] {x = 100; std::cout << "x:" << x << std::endl;}, {}, {&x});
250484543d1Sopenharmony_ci    ffrt::submit([&] {std::cout << "x:" << x << std::endl;}, {&x}, {});
251484543d1Sopenharmony_ci    ffrt::submit([&] {std::cout << "x:" << x << std::endl;}, {&x}, {});
252484543d1Sopenharmony_ci    ffrt::submit([&] {x++; std::cout << "x:" << x << std::endl;}, {}, {&x});
253484543d1Sopenharmony_ci    ffrt::submit([&] {x++; std::cout << "x:" << x << std::endl;}, {}, {&x});
254484543d1Sopenharmony_ci
255484543d1Sopenharmony_ci    ffrt::wait();
256484543d1Sopenharmony_ci    return 0;
257484543d1Sopenharmony_ci}
258484543d1Sopenharmony_ci```
259484543d1Sopenharmony_ci
260484543d1Sopenharmony_ci `解析`:
261484543d1Sopenharmony_ci
262484543d1Sopenharmony_ci1)   按上一章节[Data-Driven 特性](#Data-Driven 特性)的描述,输出一定为:
263484543d1Sopenharmony_ci
264484543d1Sopenharmony_ci```{.cpp}
265484543d1Sopenharmony_cix:100
266484543d1Sopenharmony_cix:100
267484543d1Sopenharmony_cix:100
268484543d1Sopenharmony_cix:101
269484543d1Sopenharmony_cix:102
270484543d1Sopenharmony_ci```
271484543d1Sopenharmony_ci
272484543d1Sopenharmony_ci**nested task**
273484543d1Sopenharmony_ci
274484543d1Sopenharmony_ci```{.cpp}
275484543d1Sopenharmony_ci#include <iostream>
276484543d1Sopenharmony_ci#include "ffrt.h"
277484543d1Sopenharmony_ci
278484543d1Sopenharmony_ciint main(int narg, char** argv)
279484543d1Sopenharmony_ci{
280484543d1Sopenharmony_ci    ffrt::submit([&] {
281484543d1Sopenharmony_ci        std::cout << "task 1" << std::endl;
282484543d1Sopenharmony_ci        ffrt::submit([&] {std::cout << "nested task 1.1" << std::endl;}, {}, {});
283484543d1Sopenharmony_ci        ffrt::submit([&] {std::cout << "nested task 1.2" << std::endl;}, {}, {});
284484543d1Sopenharmony_ci        ffrt::wait();
285484543d1Sopenharmony_ci    }, {}, {});
286484543d1Sopenharmony_ci
287484543d1Sopenharmony_ci    ffrt::submit([&] {
288484543d1Sopenharmony_ci        std::cout << "task 2" << std::endl;
289484543d1Sopenharmony_ci        ffrt::submit([&] {std::cout << "nested task 2.1" << std::endl;}, {}, {});
290484543d1Sopenharmony_ci        ffrt::submit([&] {std::cout << "nested task 2.2" << std::endl;}, {}, {});
291484543d1Sopenharmony_ci        ffrt::wait();
292484543d1Sopenharmony_ci    }, {}, {});
293484543d1Sopenharmony_ci    ffrt::wait();
294484543d1Sopenharmony_ci    return 0;
295484543d1Sopenharmony_ci}
296484543d1Sopenharmony_ci```
297484543d1Sopenharmony_ci
298484543d1Sopenharmony_ci `解析`:
299484543d1Sopenharmony_ci
300484543d1Sopenharmony_ci1)   FFRT允许在 Task 内部继续提交多个SubTask,这样 Task 之间可以建立起一颗调用树;
301484543d1Sopenharmony_ci
302484543d1Sopenharmony_ci2)   Task1 和Task2 可以并行,Task 1.1/1.2/2.1/2.2 之间也可以并行,因此1种可行的输出为:
303484543d1Sopenharmony_ci
304484543d1Sopenharmony_ci```
305484543d1Sopenharmony_citask 1
306484543d1Sopenharmony_cinested task  1.1
307484543d1Sopenharmony_citask 2
308484543d1Sopenharmony_cinested task 1.2
309484543d1Sopenharmony_cinested task 2.2
310484543d1Sopenharmony_cinested task 2.1  
311484543d1Sopenharmony_ci```
312484543d1Sopenharmony_ci
313484543d1Sopenharmony_ci### wait
314484543d1Sopenharmony_ci<hr/>
315484543d1Sopenharmony_ci* 同步等待,与[submit](#submit) 配合使用
316484543d1Sopenharmony_ci* 等待指定的数据被生产完成,或等待当前任务的所有子任务完成,在不满足条件之前,当前的执行上下文被suspend,在满足条件后恢复执行
317484543d1Sopenharmony_ci
318484543d1Sopenharmony_ci#### 声明
319484543d1Sopenharmony_ci
320484543d1Sopenharmony_ci```{.cpp}
321484543d1Sopenharmony_cinamespace ffrt {
322484543d1Sopenharmony_civoid wait(const std::vector<const void*>& deps);
323484543d1Sopenharmony_civoid wait(); 
324484543d1Sopenharmony_ci}
325484543d1Sopenharmony_ci```
326484543d1Sopenharmony_ci
327484543d1Sopenharmony_ci#### 参数
328484543d1Sopenharmony_ci
329484543d1Sopenharmony_ci`deps`
330484543d1Sopenharmony_ci
331484543d1Sopenharmony_ci* 需要等待被生产完成的数据的虚拟地址,这些地址可能作为某些任务在submit 时的out_deps
332484543d1Sopenharmony_ci
333484543d1Sopenharmony_ci#### 返回值
334484543d1Sopenharmony_ci
335484543d1Sopenharmony_ci* 不涉及
336484543d1Sopenharmony_ci
337484543d1Sopenharmony_ci#### 描述
338484543d1Sopenharmony_ci* wait(deps) 用于等待deps指代的数据被生产完成才能执行后面的代码
339484543d1Sopenharmony_ci* wait() 用于等待当前上下文提交的所有子任务(`注意:不包括孙子任务`)都完成才能执行后面的代码
340484543d1Sopenharmony_ci* 该接口支持在FFRT task 内部调用,也支持在FFRT task 外部调用
341484543d1Sopenharmony_ci* 在FFRT task 外部调用的wait 是OS 能够感知的等待,相对于FFRT task 内部调用的wait 是更加昂贵的,因此我们希望尽可能让更多的wait 发生在FFRT task 内部 ,而不是FFRT task 外部
342484543d1Sopenharmony_ci
343484543d1Sopenharmony_ci#### 样例
344484543d1Sopenharmony_ci
345484543d1Sopenharmony_ci**recursive fibonacci**
346484543d1Sopenharmony_ci
347484543d1Sopenharmony_ci串行版的fibonacci 可以实现为:
348484543d1Sopenharmony_ci
349484543d1Sopenharmony_ci```{.cpp}
350484543d1Sopenharmony_ci#include <iostream>
351484543d1Sopenharmony_ci
352484543d1Sopenharmony_civoid fib(int x, int& y) {
353484543d1Sopenharmony_ci    if (x <= 1) {
354484543d1Sopenharmony_ci        y = x;
355484543d1Sopenharmony_ci    } else {
356484543d1Sopenharmony_ci        int y1, y2;
357484543d1Sopenharmony_ci        fib(x - 1, y1);
358484543d1Sopenharmony_ci        fib(x - 2, y2);
359484543d1Sopenharmony_ci        y = y1 + y2;
360484543d1Sopenharmony_ci    }
361484543d1Sopenharmony_ci}
362484543d1Sopenharmony_ci
363484543d1Sopenharmony_ciint main(int narg, char** argv)
364484543d1Sopenharmony_ci{
365484543d1Sopenharmony_ci    int r;
366484543d1Sopenharmony_ci    fib(10, r);
367484543d1Sopenharmony_ci    std::cout << "fibonacci 10: " << r << std::endl;
368484543d1Sopenharmony_ci    return 0;
369484543d1Sopenharmony_ci}
370484543d1Sopenharmony_ci```
371484543d1Sopenharmony_ci
372484543d1Sopenharmony_ci若要使用 FFRT 实现并行(注,对于单纯的fibonacci,单个 Task 的计算量极小,不具有并行加速的意义,但这种调用pattern 对并行编程模型的灵活性考验是非常高的),其中1种可行的实现为:
373484543d1Sopenharmony_ci
374484543d1Sopenharmony_ci```{.cpp}
375484543d1Sopenharmony_ci#include <iostream>
376484543d1Sopenharmony_ci
377484543d1Sopenharmony_ci#include "ffrt.h"
378484543d1Sopenharmony_ci
379484543d1Sopenharmony_civoid fib_ffrt(int x, int& y)
380484543d1Sopenharmony_ci{
381484543d1Sopenharmony_ci    if (x <= 1) {
382484543d1Sopenharmony_ci        y = x;
383484543d1Sopenharmony_ci    } else {
384484543d1Sopenharmony_ci        int y1, y2;
385484543d1Sopenharmony_ci        ffrt::submit([&] {fib_ffrt(x - 1, y1);}, {&x}, {&y1} );
386484543d1Sopenharmony_ci        ffrt::submit([&] {fib_ffrt(x - 2, y2);}, {&x}, {&y2} );
387484543d1Sopenharmony_ci        ffrt::wait({&y1, &y2});
388484543d1Sopenharmony_ci        y = y1 + y2;
389484543d1Sopenharmony_ci    }
390484543d1Sopenharmony_ci}
391484543d1Sopenharmony_ci
392484543d1Sopenharmony_ciint main(int narg, char** argv)
393484543d1Sopenharmony_ci{
394484543d1Sopenharmony_ci    int r;
395484543d1Sopenharmony_ci    ffrt::submit([&] { fib_ffrt(10, r); }, {}, {&r});
396484543d1Sopenharmony_ci    ffrt::wait({&r});
397484543d1Sopenharmony_ci    std::cout << "fibonacci 10: " << r << std::endl;
398484543d1Sopenharmony_ci    return 0;
399484543d1Sopenharmony_ci}
400484543d1Sopenharmony_ci```
401484543d1Sopenharmony_ci
402484543d1Sopenharmony_ci`解析`:
403484543d1Sopenharmony_ci
404484543d1Sopenharmony_ci1)   将fibonacci (x-1)和fibonacci (x-2) 作为2个Task 提交给FFRT,在两个Task 完成之后将结果累加;
405484543d1Sopenharmony_ci
406484543d1Sopenharmony_ci2)   虽然单个Task 只能拆分成2个SubTask 但是子Task 可以继续拆分,因此,整个计算图的并行度是非常高的,Task 之间在FFRT 内部形成了一颗调用树;
407484543d1Sopenharmony_ci
408484543d1Sopenharmony_ci<img src="images/image-20220926152331554.png" style="zoom:100%" />
409484543d1Sopenharmony_ci
410484543d1Sopenharmony_ci
411484543d1Sopenharmony_ci### task_attr
412484543d1Sopenharmony_ci<hr/>
413484543d1Sopenharmony_ci* 定义task 的属性的辅助类,与[submit](#submit) 配合使用
414484543d1Sopenharmony_ci
415484543d1Sopenharmony_ci#### 声明
416484543d1Sopenharmony_ci
417484543d1Sopenharmony_ci```{.cpp}
418484543d1Sopenharmony_cinamespace ffrt {
419484543d1Sopenharmony_cienum qos {
420484543d1Sopenharmony_ci    qos_inherit = -1,
421484543d1Sopenharmony_ci    qos_background,
422484543d1Sopenharmony_ci    qos_utility,
423484543d1Sopenharmony_ci    qos_default,
424484543d1Sopenharmony_ci    qos_user_initiated,
425484543d1Sopenharmony_ci};
426484543d1Sopenharmony_ci
427484543d1Sopenharmony_ciclass task_attr {
428484543d1Sopenharmony_cipublic:
429484543d1Sopenharmony_ci    task_attr& qos(enum qos qos); // set qos
430484543d1Sopenharmony_ci    enum qos qos() const; // get qos
431484543d1Sopenharmony_ci    task_attr& name(const char* name); // set name
432484543d1Sopenharmony_ci    const char* name() const; // get name
433484543d1Sopenharmony_ci};
434484543d1Sopenharmony_ci}
435484543d1Sopenharmony_ci```
436484543d1Sopenharmony_ci
437484543d1Sopenharmony_ci#### 参数
438484543d1Sopenharmony_ci
439484543d1Sopenharmony_ci`qos`
440484543d1Sopenharmony_ci
441484543d1Sopenharmony_ci* qos 设定的枚举类型
442484543d1Sopenharmony_ci* inherent 是一个qos 设定策略,代表即将submit 的task 的qos 继承当前task 的qos
443484543d1Sopenharmony_ci
444484543d1Sopenharmony_ci#### 返回值
445484543d1Sopenharmony_ci
446484543d1Sopenharmony_ci* 不涉及
447484543d1Sopenharmony_ci
448484543d1Sopenharmony_ci#### 描述
449484543d1Sopenharmony_ci* 约定
450484543d1Sopenharmony_ci  * 在submit 时,如果不通过task_attr 设定qos,那么默认该提交的task的qos 为`qos_default`
451484543d1Sopenharmony_ci  * 在submit 时,如果通过task_attr 设定qos 为`qos_inherent`,表示将该提交的task 的qos 与当前task 的qos 相同,在FFRT task 外部提交的属性为`qos_inherent` 的task,其qos 为`qos_default`
452484543d1Sopenharmony_ci  * 其他情况下,该提交的task 的qos 被设定为指定的值
453484543d1Sopenharmony_ci* qos 级别从上到下依次递增,qos_user_interactive拥有最高优先级
454484543d1Sopenharmony_ci
455484543d1Sopenharmony_ci#### 样例
456484543d1Sopenharmony_ci
457484543d1Sopenharmony_ci```{.cpp}
458484543d1Sopenharmony_ci#include <iostream>
459484543d1Sopenharmony_ci#include "ffrt.h"
460484543d1Sopenharmony_ci
461484543d1Sopenharmony_ciint main(int narg, char** argv)
462484543d1Sopenharmony_ci{
463484543d1Sopenharmony_ci    ffrt::submit([] { std::cout << "hello ffrt" << std::endl; }, {}, {}, 
464484543d1Sopenharmony_ci        ffrt::task_attr().qos(ffrt::qos_background));
465484543d1Sopenharmony_ci    ffrt::wait();
466484543d1Sopenharmony_ci    return 0;
467484543d1Sopenharmony_ci}
468484543d1Sopenharmony_ci```
469484543d1Sopenharmony_ci
470484543d1Sopenharmony_ci* 提交一个qos 级别为background 的任务
471484543d1Sopenharmony_ci
472484543d1Sopenharmony_ci
473484543d1Sopenharmony_ci
474484543d1Sopenharmony_ci### submit_h
475484543d1Sopenharmony_ci
476484543d1Sopenharmony_ci<hr/>
477484543d1Sopenharmony_ci
478484543d1Sopenharmony_ci* 向调度器提交一个task,与[submit](#submit) 的差别在于返回task 的句柄,该句柄可以用于建立task 之间的依赖,或用于在wait 语句中实现同步
479484543d1Sopenharmony_ci
480484543d1Sopenharmony_ci#### 声明
481484543d1Sopenharmony_ci
482484543d1Sopenharmony_ci```{.cpp}
483484543d1Sopenharmony_cinamespace ffrt {
484484543d1Sopenharmony_ciclass task_handle {
485484543d1Sopenharmony_cipublic:
486484543d1Sopenharmony_ci    task_handle();
487484543d1Sopenharmony_ci    task_handle(ffrt_task_handle_t p);
488484543d1Sopenharmony_ci
489484543d1Sopenharmony_ci    task_handle(task_handle const&) = delete;
490484543d1Sopenharmony_ci    void operator=(task_handle const&) = delete;
491484543d1Sopenharmony_ci
492484543d1Sopenharmony_ci    task_handle(task_handle&& h);
493484543d1Sopenharmony_ci    task_handle& operator=(task_handle&& h);
494484543d1Sopenharmony_ci
495484543d1Sopenharmony_ci    operator void* () const;
496484543d1Sopenharmony_ci};
497484543d1Sopenharmony_ci
498484543d1Sopenharmony_citask_handle submit_h(std::function<void()>&& func, const std::vector<const void*>& in_deps = {}, const std::vector<const void*>& out_deps = {}, const task_attr& attr = {});
499484543d1Sopenharmony_citask_handle submit_h(const std::function<void()>& func, const std::vector<const void*>& in_deps = {}, const std::vector<const void*>& out_deps = {}, const task_attr& attr = {});
500484543d1Sopenharmony_ci}
501484543d1Sopenharmony_ci```
502484543d1Sopenharmony_ci
503484543d1Sopenharmony_ci#### 参数
504484543d1Sopenharmony_ci
505484543d1Sopenharmony_ci`func`
506484543d1Sopenharmony_ci
507484543d1Sopenharmony_ci* 同submit,详见[submit](#submit) 定义
508484543d1Sopenharmony_ci
509484543d1Sopenharmony_ci`in_deps`
510484543d1Sopenharmony_ci
511484543d1Sopenharmony_ci* 同submit,详见[submit](#submit) 定义
512484543d1Sopenharmony_ci
513484543d1Sopenharmony_ci`out_deps`
514484543d1Sopenharmony_ci
515484543d1Sopenharmony_ci* 同submit,详见[submit](#submit) 定义
516484543d1Sopenharmony_ci
517484543d1Sopenharmony_ci`attr`
518484543d1Sopenharmony_ci
519484543d1Sopenharmony_ci* 同submit,详见[submit](#submit) 定义
520484543d1Sopenharmony_ci
521484543d1Sopenharmony_ci#### 返回值
522484543d1Sopenharmony_ci
523484543d1Sopenharmony_ci* task 的句柄,该句柄可以用于建立task 之间的依赖,或用于在wait 语句中实现同步
524484543d1Sopenharmony_ci
525484543d1Sopenharmony_ci#### 描述
526484543d1Sopenharmony_ci
527484543d1Sopenharmony_ci* 该接口与submit 使用基本相同,从性能的角度,在不需要返回task handle 的场景,可以调用submit 接口相对于submit_h 有更好的性能
528484543d1Sopenharmony_ci* task_handle 可以和其他的数据depends 同时作为某个task 的in_deps,表示该task 的执行依赖task_handle 对应的task 执行完成
529484543d1Sopenharmony_ci* task_handle 可以和其他的数据depends 同时作为wait 的deps,表示当前任务将被suspend,直到task_handle 对应的task 执行完成后将被恢复
530484543d1Sopenharmony_ci* task_handle 不建议作为某个task 的out_deps,其行为是未定义的
531484543d1Sopenharmony_ci
532484543d1Sopenharmony_ci
533484543d1Sopenharmony_ci#### 样例
534484543d1Sopenharmony_ci
535484543d1Sopenharmony_ci```{.cpp}
536484543d1Sopenharmony_ci#include <iostream>
537484543d1Sopenharmony_ci#include "ffrt.h"
538484543d1Sopenharmony_ci
539484543d1Sopenharmony_ciint main(int narg, char** argv)
540484543d1Sopenharmony_ci{
541484543d1Sopenharmony_ci    // handle work with submit
542484543d1Sopenharmony_ci    ffrt::task_handle h = ffrt::submit_h([] { std::cout << "hello "; }); // not need some data in this task
543484543d1Sopenharmony_ci    int x = 1;
544484543d1Sopenharmony_ci    ffrt::submit([&] { x++; }, {}, {&x});
545484543d1Sopenharmony_ci    ffrt::submit([&] { std::cout << "world, x = " << x << std::endl; }, {&x, h}); // this task depend x and h
546484543d1Sopenharmony_ci    
547484543d1Sopenharmony_ci    // handle work with wait
548484543d1Sopenharmony_ci    ffrt::task_handle h2 = ffrt::submit_h([&] { std::cout << "handle wait" << std::endl; x++; });
549484543d1Sopenharmony_ci    ffrt::wait({h2});
550484543d1Sopenharmony_ci    std::cout << "x = " << x << std::endl;
551484543d1Sopenharmony_ci    ffrt::wait();
552484543d1Sopenharmony_ci    return 0;
553484543d1Sopenharmony_ci}
554484543d1Sopenharmony_ci```
555484543d1Sopenharmony_ci
556484543d1Sopenharmony_ci* 预期的输出为
557484543d1Sopenharmony_ci
558484543d1Sopenharmony_ci```
559484543d1Sopenharmony_cihello world, x = 2
560484543d1Sopenharmony_cihandle wait
561484543d1Sopenharmony_cix = 3
562484543d1Sopenharmony_ci```
563484543d1Sopenharmony_ci
564484543d1Sopenharmony_ci### get_id
565484543d1Sopenharmony_ci
566484543d1Sopenharmony_ci<hr/>
567484543d1Sopenharmony_ci
568484543d1Sopenharmony_ci* 返回当前task的id标识,更多使用用于维测(原因是task name可能重名)
569484543d1Sopenharmony_ci
570484543d1Sopenharmony_ci#### 声明
571484543d1Sopenharmony_ci
572484543d1Sopenharmony_ci```{.cpp}
573484543d1Sopenharmony_cinamespace ffrt {
574484543d1Sopenharmony_cinamespace this_task {
575484543d1Sopenharmony_ciuint64_t get_id();
576484543d1Sopenharmony_ci}
577484543d1Sopenharmony_ci}
578484543d1Sopenharmony_ci```
579484543d1Sopenharmony_ci
580484543d1Sopenharmony_ci#### 参数
581484543d1Sopenharmony_ci
582484543d1Sopenharmony_ci* 不涉及
583484543d1Sopenharmony_ci
584484543d1Sopenharmony_ci#### 返回值
585484543d1Sopenharmony_ci
586484543d1Sopenharmony_ci* 当前task的id
587484543d1Sopenharmony_ci
588484543d1Sopenharmony_ci#### 描述
589484543d1Sopenharmony_ci
590484543d1Sopenharmony_ci* 该接口在task内部调用将返回当前task的id标识,在task外部调用将返回0
591484543d1Sopenharmony_ci* 可以基于该接口在task外部调用返回0的特性来区分函数是运行在FFRT 工作线程上还是非FFRT工作线程上
592484543d1Sopenharmony_ci* task id为从1开始编码,每提交一个task便增加1,被设计成64bit,即便是每秒百万次提交,也需要292471.2年才会发生翻转
593484543d1Sopenharmony_ci
594484543d1Sopenharmony_ci#### 样例
595484543d1Sopenharmony_ci
596484543d1Sopenharmony_ci```{.cpp}
597484543d1Sopenharmony_ci#include <iostream>
598484543d1Sopenharmony_ci#include "ffrt.h"
599484543d1Sopenharmony_ci
600484543d1Sopenharmony_ciint main(int narg, char** argv)
601484543d1Sopenharmony_ci{
602484543d1Sopenharmony_ci    ffrt::submit([] { std::cout << "task id: " << ffrt::this_task::get_id() << std::endl; });
603484543d1Sopenharmony_ci    ffrt::submit([] { std::cout <<"task id: " << ffrt::this_task::get_id() << std::endl; });
604484543d1Sopenharmony_ci    ffrt::wait();
605484543d1Sopenharmony_ci    std::cout << "task id: " << ffrt::this_task::get_id() << std::endl;
606484543d1Sopenharmony_ci    return 0;
607484543d1Sopenharmony_ci}
608484543d1Sopenharmony_ci```
609484543d1Sopenharmony_ci
610484543d1Sopenharmony_ci* 可能的输出为:
611484543d1Sopenharmony_ci
612484543d1Sopenharmony_ci```
613484543d1Sopenharmony_citask id: 1
614484543d1Sopenharmony_citask id: 2
615484543d1Sopenharmony_citask id: 0
616484543d1Sopenharmony_ci```
617484543d1Sopenharmony_ci
618484543d1Sopenharmony_ci### update_qos
619484543d1Sopenharmony_ci
620484543d1Sopenharmony_ci<hr/>
621484543d1Sopenharmony_ci
622484543d1Sopenharmony_ci* 更新当前正在执行的task的优先级
623484543d1Sopenharmony_ci
624484543d1Sopenharmony_ci#### 声明
625484543d1Sopenharmony_ci
626484543d1Sopenharmony_ci```{.cpp}
627484543d1Sopenharmony_cinamespace ffrt {
628484543d1Sopenharmony_cinamespace this_task {
629484543d1Sopenharmony_ciint update_qos(enum qos qos);
630484543d1Sopenharmony_ci}
631484543d1Sopenharmony_ci}
632484543d1Sopenharmony_ci```
633484543d1Sopenharmony_ci
634484543d1Sopenharmony_ci#### 参数
635484543d1Sopenharmony_ci
636484543d1Sopenharmony_ci`qos`
637484543d1Sopenharmony_ci* 新的qos等级
638484543d1Sopenharmony_ci
639484543d1Sopenharmony_ci#### 返回值
640484543d1Sopenharmony_ci
641484543d1Sopenharmony_ci* 0表示成功,非0表示失败
642484543d1Sopenharmony_ci
643484543d1Sopenharmony_ci#### 描述
644484543d1Sopenharmony_ci
645484543d1Sopenharmony_ci* 该接口对当前task的qos调整会立即生效
646484543d1Sopenharmony_ci* 如果新设定的qos与当前的qos不一致,则会block当前task的执行,再按照新的qos恢复执行
647484543d1Sopenharmony_ci* 如果新设定的qos与当前的qos一致,则接口会立即返回,不做任何处理
648484543d1Sopenharmony_ci* **如果在非task内部调用该接口,则返回非0值,用户可以选择忽略或其他处理**
649484543d1Sopenharmony_ci
650484543d1Sopenharmony_ci#### 样例
651484543d1Sopenharmony_ci
652484543d1Sopenharmony_ci```{.cpp}
653484543d1Sopenharmony_ci#include <iostream>
654484543d1Sopenharmony_ci#include <thread>
655484543d1Sopenharmony_ci#include "ffrt.h"
656484543d1Sopenharmony_ci
657484543d1Sopenharmony_ciint main(int narg, char** argv)
658484543d1Sopenharmony_ci{
659484543d1Sopenharmony_ci    ffrt::submit([] {
660484543d1Sopenharmony_ci        std::cout << "thread id: " << std::this_thread::get_id() << std::endl;
661484543d1Sopenharmony_ci        std::cout << "return " << ffrt::this_task::update_qos(ffrt::qos_user_initiated) << std::endl;
662484543d1Sopenharmony_ci        std::cout << "thread id: " << std::this_thread::get_id() << std::endl;
663484543d1Sopenharmony_ci    });
664484543d1Sopenharmony_ci    ffrt::wait();
665484543d1Sopenharmony_ci    std::cout << "return " << ffrt::this_task::update_qos(ffrt::qos_user_initiated) << std::endl;
666484543d1Sopenharmony_ci    return 0;
667484543d1Sopenharmony_ci}
668484543d1Sopenharmony_ci```
669484543d1Sopenharmony_ci
670484543d1Sopenharmony_ci* 可能的输出为:
671484543d1Sopenharmony_ci
672484543d1Sopenharmony_ci```
673484543d1Sopenharmony_cithread id: 1024
674484543d1Sopenharmony_cireturn 0
675484543d1Sopenharmony_cithread id: 2222
676484543d1Sopenharmony_cireturn 1
677484543d1Sopenharmony_ci```
678484543d1Sopenharmony_ci
679484543d1Sopenharmony_ci
680484543d1Sopenharmony_ci
681484543d1Sopenharmony_ci## 串行队列
682484543d1Sopenharmony_ci<hr />
683484543d1Sopenharmony_ci
684484543d1Sopenharmony_ci串行队列基于FFRT协程调度模型,实现了消息队列功能。串行任务执行在FFRT worker上,用户无需维护一个专用的线程,拥有更轻量级的调度开销。
685484543d1Sopenharmony_ci
686484543d1Sopenharmony_ci支持以下基本功能:
687484543d1Sopenharmony_ci
688484543d1Sopenharmony_ci* 支持创建队列,创建队列时可指定队列名称和优先级,每个队列在功能上相当于一个单独的线程,队列中的任务相对于用户线程异步执行。
689484543d1Sopenharmony_ci
690484543d1Sopenharmony_ci* 支持延时任务,向队列提交任务时支持设置 delay 属性,单位为微秒 us,提交给队列的延时任务,在提交时刻+delay时间后才会被调度执行。
691484543d1Sopenharmony_ci
692484543d1Sopenharmony_ci* 支持串行调度,同一个队列中的多个任务按照 uptime (提交时刻+delay时间)升序排列、串行执行,队列中一个任务完成后下一个任务才会开始。
693484543d1Sopenharmony_ci
694484543d1Sopenharmony_ci* 支持取消任务,支持根据任务句柄取消单个未执行的任务,如果这个任务已出队(开始执行或已执行完),取消接口返回异常值。
695484543d1Sopenharmony_ci
696484543d1Sopenharmony_ci* 支持同步等待,支持根据任务句柄等待指定任务完成,该任务完成,也代表同一队列中uptime在此任务之前的所有任务都已完成。
697484543d1Sopenharmony_ci
698484543d1Sopenharmony_ci### queue
699484543d1Sopenharmony_ci<hr/>
700484543d1Sopenharmony_ci
701484543d1Sopenharmony_ci#### 描述
702484543d1Sopenharmony_ciFFRT串行队列 C++ API,提供提交任务、取消任务、等待任务执行完成等功能
703484543d1Sopenharmony_ci
704484543d1Sopenharmony_ci#### 声明
705484543d1Sopenharmony_ci
706484543d1Sopenharmony_ci```{.cpp}
707484543d1Sopenharmony_cinamespace ffrt {
708484543d1Sopenharmony_ciclass queue {
709484543d1Sopenharmony_cipublic:
710484543d1Sopenharmony_ci    queue(queue const&) = delete;
711484543d1Sopenharmony_ci    void operator=(queue const&) = delete;
712484543d1Sopenharmony_ci
713484543d1Sopenharmony_ci    void submit(const std::function<void()>& func);
714484543d1Sopenharmony_ci    void submit(const std::function<void()>& func, const task_attr& attr);
715484543d1Sopenharmony_ci    void submit(std::function<void()>&& func);
716484543d1Sopenharmony_ci    void submit(std::function<void()>&& func, const task_attr& attr);
717484543d1Sopenharmony_ci
718484543d1Sopenharmony_ci    task_handle submit_h(const std::function<void()>& func);
719484543d1Sopenharmony_ci    task_handle submit_h(const std::function<void()>& func, const task_attr& attr);
720484543d1Sopenharmony_ci    task_handle submit_h(std::function<void()>&& func);
721484543d1Sopenharmony_ci    task_handle submit_h(std::function<void()>&& func, const task_attr& attr);
722484543d1Sopenharmony_ci
723484543d1Sopenharmony_ci    int cancel(const task_handle& handle);
724484543d1Sopenharmony_ci
725484543d1Sopenharmony_ci    void wait(const task_handle& handle);
726484543d1Sopenharmony_ci};
727484543d1Sopenharmony_ci}
728484543d1Sopenharmony_ci```
729484543d1Sopenharmony_ci
730484543d1Sopenharmony_ci#### 方法
731484543d1Sopenharmony_ci
732484543d1Sopenharmony_ci##### submit
733484543d1Sopenharmony_ci
734484543d1Sopenharmony_ci```{.cpp}
735484543d1Sopenharmony_cinamespace ffrt {
736484543d1Sopenharmony_civoid queue::submit(const std::function<void()>& func);
737484543d1Sopenharmony_civoid queue::submit(const std::function<void()>& func, const task_attr& attr);
738484543d1Sopenharmony_civoid queue::submit(std::function<void()>&& func);
739484543d1Sopenharmony_civoid queue::submit(std::function<void()>&& func, const task_attr& attr);
740484543d1Sopenharmony_ci}
741484543d1Sopenharmony_ci```
742484543d1Sopenharmony_ci
743484543d1Sopenharmony_ci* 描述:提交一个任务到队列中调度执行
744484543d1Sopenharmony_ci
745484543d1Sopenharmony_ci* 参数:
746484543d1Sopenharmony_ci
747484543d1Sopenharmony_ci  `func`:可被std::function接收的一切CPU可执行体,可以为C++定义的Lambda函数闭包,函数指针,甚至是函数对象
748484543d1Sopenharmony_ci
749484543d1Sopenharmony_ci  `attr`:该参数是可选的,用于描述task的属性,如qos、delay、timeout等,详见[task_attr](#task_attr)章节
750484543d1Sopenharmony_ci
751484543d1Sopenharmony_ci* 返回值:不涉及
752484543d1Sopenharmony_ci
753484543d1Sopenharmony_ci##### submit_h
754484543d1Sopenharmony_ci
755484543d1Sopenharmony_ci```{.cpp}
756484543d1Sopenharmony_cinamespace ffrt {
757484543d1Sopenharmony_citask_handle queue::submit_h(const std::function<void()>& func);
758484543d1Sopenharmony_citask_handle queue::submit_h(const std::function<void()>& func, const task_attr& attr);
759484543d1Sopenharmony_citask_handle queue::submit_h(std::function<void()>&& func);
760484543d1Sopenharmony_citask_handle queue::submit_h(std::function<void()>&& func, const task_attr& attr);
761484543d1Sopenharmony_ci}
762484543d1Sopenharmony_ci```
763484543d1Sopenharmony_ci
764484543d1Sopenharmony_ci* 描述:提交一个任务到队列中调度执行,并返回一个句柄
765484543d1Sopenharmony_ci
766484543d1Sopenharmony_ci* 参数:
767484543d1Sopenharmony_ci
768484543d1Sopenharmony_ci  `func`:可被std::function接收的一切CPU可执行体,可以为C++定义的Lambda函数闭包,函数指针,甚至是函数对象
769484543d1Sopenharmony_ci
770484543d1Sopenharmony_ci  `attr`:该参数时可选的,用于描述task的属性,如qos、delay、timeout等,详见[task_attr](#task_attr)章节
771484543d1Sopenharmony_ci
772484543d1Sopenharmony_ci* 返回值:
773484543d1Sopenharmony_ci
774484543d1Sopenharmony_ci  `task_handle`:task的句柄,该句柄可以用于建立task之间的依赖
775484543d1Sopenharmony_ci
776484543d1Sopenharmony_ci##### cancel
777484543d1Sopenharmony_ci
778484543d1Sopenharmony_ci```{.cpp}
779484543d1Sopenharmony_cinamespace ffrt {
780484543d1Sopenharmony_ciint queue::cancel(const task_handle& handle);
781484543d1Sopenharmony_ci}
782484543d1Sopenharmony_ci```
783484543d1Sopenharmony_ci
784484543d1Sopenharmony_ci* 描述:根据句柄取消对应的任务
785484543d1Sopenharmony_ci
786484543d1Sopenharmony_ci* 参数:
787484543d1Sopenharmony_ci
788484543d1Sopenharmony_ci  `handle`:任务的句柄
789484543d1Sopenharmony_ci
790484543d1Sopenharmony_ci* 返回值:
791484543d1Sopenharmony_ci
792484543d1Sopenharmony_ci  若成功返回0,否则返回其他非0值
793484543d1Sopenharmony_ci
794484543d1Sopenharmony_ci##### wait
795484543d1Sopenharmony_ci
796484543d1Sopenharmony_ci```{.cpp}
797484543d1Sopenharmony_cinamespace ffrt {
798484543d1Sopenharmony_civoid queue::wait(const task_handle& handle);
799484543d1Sopenharmony_ci}
800484543d1Sopenharmony_ci```
801484543d1Sopenharmony_ci
802484543d1Sopenharmony_ci* 描述:等待句柄对应的任务执行完成
803484543d1Sopenharmony_ci
804484543d1Sopenharmony_ci* 参数:
805484543d1Sopenharmony_ci
806484543d1Sopenharmony_ci  `handle`:任务的句柄
807484543d1Sopenharmony_ci
808484543d1Sopenharmony_ci* 返回值:不涉及
809484543d1Sopenharmony_ci
810484543d1Sopenharmony_ci
811484543d1Sopenharmony_ci#### 样例
812484543d1Sopenharmony_ci
813484543d1Sopenharmony_ci```{.cpp}
814484543d1Sopenharmony_ci#include "ffrt.h"
815484543d1Sopenharmony_ci
816484543d1Sopenharmony_ciint main(int narg, char** argv)
817484543d1Sopenharmony_ci{
818484543d1Sopenharmony_ci    // 创建队列,可设置队列优先级,默认为default等级
819484543d1Sopenharmony_ci    ffrt::queue q("test_queue", ffrt::queue_attr().qos(ffrt::qos_utility));
820484543d1Sopenharmony_ci
821484543d1Sopenharmony_ci    int x = 0;
822484543d1Sopenharmony_ci    // 提交串行任务
823484543d1Sopenharmony_ci    q.submit([&x] { x += 10; });
824484543d1Sopenharmony_ci
825484543d1Sopenharmony_ci    // 提交串行任务,并返回任务句柄
826484543d1Sopenharmony_ci    ffrt::task_handle t1 = q.submit_h([&x] { x += 10; });
827484543d1Sopenharmony_ci
828484543d1Sopenharmony_ci    // 提交串行任务,设置延时时间1000us,并返回任务句柄
829484543d1Sopenharmony_ci    ffrt::task_handle t2 = q.submit_h([&x] { x += 10; }, ffrt::task_attr().delay(1000));
830484543d1Sopenharmony_ci
831484543d1Sopenharmony_ci    // 等待指定任务执行完成
832484543d1Sopenharmony_ci    q.wait(t1);
833484543d1Sopenharmony_ci
834484543d1Sopenharmony_ci    // 取消句柄为t2的任务
835484543d1Sopenharmony_ci    q.cancel(t2);
836484543d1Sopenharmony_ci}
837484543d1Sopenharmony_ci```
838484543d1Sopenharmony_ci
839484543d1Sopenharmony_ci#### 使用约束
840484543d1Sopenharmony_ci
841484543d1Sopenharmony_ci* 队列销毁时,会等待正在执行的任务执行完成,队列中还没有开始执行的任务会被取消。
842484543d1Sopenharmony_ci
843484543d1Sopenharmony_ci* 任务粒度,串行队列支持任务执行超时检测(默认阈值30s,进程可配),因此队列中的单个任务不应该常驻(如循环任务),超过30s会向DFX上报超时。
844484543d1Sopenharmony_ci
845484543d1Sopenharmony_ci* 同步原语,任务中如果使用了 std::mutex/std::shared_mutex/std::condition_variable等std同步原语,会影响协程效率,需修改ffrt同步原语。
846484543d1Sopenharmony_ci
847484543d1Sopenharmony_ci  当前FFRT仅支持ffrt::mutex / ffrt::shared_mutex / ffrt::recursive_mutex / ffrt::condition_variable,用法和std相同,在ffrt的任务中使用未支持同步原语可能导致未定义的行为。
848484543d1Sopenharmony_ci
849484543d1Sopenharmony_ci* 生命周期,进程结束前需要释放FFRT资源。
850484543d1Sopenharmony_ci
851484543d1Sopenharmony_ci  例如SA业务,会在全局变量中管理串行队列。由于进程会先卸载libffrt.so再释放全局变量,如果进程结束时,SA未显示释放持有的串行队列,队列将随全局变量析构,析构时会访问已释放的ffrt资源,导致Fuzz用例出现use-after-free问题。
852484543d1Sopenharmony_ci
853484543d1Sopenharmony_ci* 不允许在串行任务中调用ffrt::submit和ffrt::wait,其行为是未定义的
854484543d1Sopenharmony_ci
855484543d1Sopenharmony_ci* 不允许使用ffrt::wait等待一个串行任务
856484543d1Sopenharmony_ci
857484543d1Sopenharmony_ci### queue_attr
858484543d1Sopenharmony_ci<hr/>
859484543d1Sopenharmony_ci
860484543d1Sopenharmony_ci#### 描述
861484543d1Sopenharmony_ciFFRT串行队列 C++ API,提供设置与获取串行队列优先级、设置与获取串行队列任务执行超时时间、设置与获取串行队列超时回调函数等功能
862484543d1Sopenharmony_ci
863484543d1Sopenharmony_ci#### 声明
864484543d1Sopenharmony_ci
865484543d1Sopenharmony_ci```{.cpp}
866484543d1Sopenharmony_cinamespace ffrt {
867484543d1Sopenharmony_ciclass queue_attr {
868484543d1Sopenharmony_cipublic: 
869484543d1Sopenharmony_ci    queue_attr(const queue_attr&) = delete;
870484543d1Sopenharmony_ci    queue_attr& operator=(const queue_attr&) = delete;
871484543d1Sopenharmony_ci
872484543d1Sopenharmony_ci    queue_attr& qos(qos qos_);
873484543d1Sopenharmony_ci    uint64_t timeout() const;
874484543d1Sopenharmony_ci
875484543d1Sopenharmony_ci    queue_attr& callback(const std::function<void()>& func);
876484543d1Sopenharmony_ci    ffrt_function_header_t* callback() const;
877484543d1Sopenharmony_ci};
878484543d1Sopenharmony_ci}
879484543d1Sopenharmony_ci```
880484543d1Sopenharmony_ci
881484543d1Sopenharmony_ci#### 方法
882484543d1Sopenharmony_ci
883484543d1Sopenharmony_ci##### set qos
884484543d1Sopenharmony_ci
885484543d1Sopenharmony_ci```{.cpp}
886484543d1Sopenharmony_cinamespace ffrt {
887484543d1Sopenharmony_ciqueue_attr& queue_attr::qos(qos qos_);
888484543d1Sopenharmony_ci}
889484543d1Sopenharmony_ci```
890484543d1Sopenharmony_ci
891484543d1Sopenharmony_ci* 描述:设置队列属性的qos成员
892484543d1Sopenharmony_ci
893484543d1Sopenharmony_ci* 参数:
894484543d1Sopenharmony_ci
895484543d1Sopenharmony_ci  `qos_`:串行队列的优先级
896484543d1Sopenharmony_ci
897484543d1Sopenharmony_ci* 返回值:
898484543d1Sopenharmony_ci
899484543d1Sopenharmony_ci  `queue_attr`:串行队列的属性
900484543d1Sopenharmony_ci
901484543d1Sopenharmony_ci##### get qos
902484543d1Sopenharmony_ci
903484543d1Sopenharmony_ci```{.cpp}
904484543d1Sopenharmony_cinamespace ffrt {
905484543d1Sopenharmony_ciint queue_attr::qos() const;
906484543d1Sopenharmony_ci}
907484543d1Sopenharmony_ci```
908484543d1Sopenharmony_ci
909484543d1Sopenharmony_ci* 描述:获取队列的优先级
910484543d1Sopenharmony_ci
911484543d1Sopenharmony_ci* 参数:不涉及
912484543d1Sopenharmony_ci
913484543d1Sopenharmony_ci* 返回值:
914484543d1Sopenharmony_ci
915484543d1Sopenharmony_ci  `qos`:串行队列的优先级
916484543d1Sopenharmony_ci
917484543d1Sopenharmony_ci##### set timeout
918484543d1Sopenharmony_ci
919484543d1Sopenharmony_ci```{.cpp}
920484543d1Sopenharmony_cinamespace ffrt {
921484543d1Sopenharmony_ciqueue_attr& queue_attr::timeout(uint64_t timeout_us);
922484543d1Sopenharmony_ci}
923484543d1Sopenharmony_ci```
924484543d1Sopenharmony_ci
925484543d1Sopenharmony_ci* 描述:设置串行队列任务执行超时时间
926484543d1Sopenharmony_ci
927484543d1Sopenharmony_ci* 参数:
928484543d1Sopenharmony_ci
929484543d1Sopenharmony_ci  `timeout_us`:串行队列任务执行超时时间,单位为us
930484543d1Sopenharmony_ci
931484543d1Sopenharmony_ci* 返回值:
932484543d1Sopenharmony_ci
933484543d1Sopenharmony_ci  `queue_attr`:串行队列的属性
934484543d1Sopenharmony_ci
935484543d1Sopenharmony_ci##### get timeout
936484543d1Sopenharmony_ci
937484543d1Sopenharmony_ci```{.cpp}
938484543d1Sopenharmony_cinamespace ffrt {
939484543d1Sopenharmony_ciuint64_t queue_attr::timeout() const;
940484543d1Sopenharmony_ci}
941484543d1Sopenharmony_ci```
942484543d1Sopenharmony_ci
943484543d1Sopenharmony_ci* 描述:获取所设的串行队列任务执行超时时间
944484543d1Sopenharmony_ci
945484543d1Sopenharmony_ci* 参数:不涉及
946484543d1Sopenharmony_ci
947484543d1Sopenharmony_ci* 返回值:
948484543d1Sopenharmony_ci
949484543d1Sopenharmony_ci  `timeout`:串行队列任务执行超时时间,单位为us
950484543d1Sopenharmony_ci
951484543d1Sopenharmony_ci##### set timeout callback
952484543d1Sopenharmony_ci
953484543d1Sopenharmony_ci```{.cpp}
954484543d1Sopenharmony_cinamespace ffrt {
955484543d1Sopenharmony_ciqueue_attr& callback(std::function<void()>& func);
956484543d1Sopenharmony_ci}
957484543d1Sopenharmony_ci```
958484543d1Sopenharmony_ci
959484543d1Sopenharmony_ci* 描述:设置串行队列超时回调函数
960484543d1Sopenharmony_ci
961484543d1Sopenharmony_ci* 参数:
962484543d1Sopenharmony_ci
963484543d1Sopenharmony_ci  `func`:可被std::function接收的一切CPU可执行体,可以为C++定义的Lambda函数闭包,函数指针,甚至是函数对象
964484543d1Sopenharmony_ci
965484543d1Sopenharmony_ci* 返回值:
966484543d1Sopenharmony_ci
967484543d1Sopenharmony_ci  `queue_attr`:串行队列的属性
968484543d1Sopenharmony_ci
969484543d1Sopenharmony_ci##### get timeout callback
970484543d1Sopenharmony_ci
971484543d1Sopenharmony_ci```{.cpp}
972484543d1Sopenharmony_cinamespace ffrt {
973484543d1Sopenharmony_ciffrt_function_header_t* callback() const;
974484543d1Sopenharmony_ci}
975484543d1Sopenharmony_ci```
976484543d1Sopenharmony_ci
977484543d1Sopenharmony_ci* 描述:获取所设的串行队列超时回调函数
978484543d1Sopenharmony_ci
979484543d1Sopenharmony_ci* 参数:不涉及
980484543d1Sopenharmony_ci
981484543d1Sopenharmony_ci* 返回值:
982484543d1Sopenharmony_ci
983484543d1Sopenharmony_ci  `ffrt_function_header_t`:任务执行器,描述了该CPU Task如何执行和销毁的函数指针
984484543d1Sopenharmony_ci
985484543d1Sopenharmony_ci#### 样例
986484543d1Sopenharmony_ci```{.cpp}
987484543d1Sopenharmony_ci#include <stdio.h>
988484543d1Sopenharmony_ci#include "ffrt.h"
989484543d1Sopenharmony_ci
990484543d1Sopenharmony_ciint main(int narg, char** argv)
991484543d1Sopenharmony_ci{
992484543d1Sopenharmony_ci    int x = 0;
993484543d1Sopenharmony_ci    std::function<void()> callbackFunc = [&x]() {
994484543d1Sopenharmony_ci        x++;
995484543d1Sopenharmony_ci    };
996484543d1Sopenharmony_ci
997484543d1Sopenharmony_ci    // 创建队列,可设置队列优先级,默认为default等级
998484543d1Sopenharmony_ci    ffrt::queue q1("test_queue", queue_attr().qos(qos_utility));
999484543d1Sopenharmony_ci
1000484543d1Sopenharmony_ci    // 创建队列,可通过设置timeout打开队列任务超时监测,默认不设置(关闭)
1001484543d1Sopenharmony_ci    // 超时会打印Error日志并执行用户设置的callback(可选)
1002484543d1Sopenharmony_ci    ffrt::queue q2("test_queue", ffrt::queue_attr().timeout(1000).callback(callbackFunc));
1003484543d1Sopenharmony_ci
1004484543d1Sopenharmony_ci    return 0;
1005484543d1Sopenharmony_ci}
1006484543d1Sopenharmony_ci```
1007484543d1Sopenharmony_ci
1008484543d1Sopenharmony_ci
1009484543d1Sopenharmony_ci## 同步原语
1010484543d1Sopenharmony_ci
1011484543d1Sopenharmony_ci### mutex
1012484543d1Sopenharmony_ci<hr/>
1013484543d1Sopenharmony_ci* FFRT提供的类似std::mutex 的性能实现
1014484543d1Sopenharmony_ci
1015484543d1Sopenharmony_ci#### 声明
1016484543d1Sopenharmony_ci
1017484543d1Sopenharmony_ci```{.cpp}
1018484543d1Sopenharmony_cinamespace ffrt {
1019484543d1Sopenharmony_ciclass mutex {
1020484543d1Sopenharmony_cipublic:
1021484543d1Sopenharmony_ci    mutex(mutex const &) = delete;
1022484543d1Sopenharmony_ci    void operator =(mutex const &) = delete;
1023484543d1Sopenharmony_ci
1024484543d1Sopenharmony_ci    void lock();
1025484543d1Sopenharmony_ci    void unlock();
1026484543d1Sopenharmony_ci    bool try_lock();
1027484543d1Sopenharmony_ci};
1028484543d1Sopenharmony_ci}
1029484543d1Sopenharmony_ci```
1030484543d1Sopenharmony_ci
1031484543d1Sopenharmony_ci#### 参数
1032484543d1Sopenharmony_ci
1033484543d1Sopenharmony_ci* 不涉及
1034484543d1Sopenharmony_ci
1035484543d1Sopenharmony_ci#### 返回值
1036484543d1Sopenharmony_ci
1037484543d1Sopenharmony_ci* 不涉及
1038484543d1Sopenharmony_ci
1039484543d1Sopenharmony_ci#### 描述
1040484543d1Sopenharmony_ci* 该功能能够避免传统的std::mutex 在抢不到锁时陷入内核的问题,在使用得当的条件下将会有更好的性能
1041484543d1Sopenharmony_ci
1042484543d1Sopenharmony_ci#### 样例
1043484543d1Sopenharmony_ci
1044484543d1Sopenharmony_ci```{.cpp}
1045484543d1Sopenharmony_ci#include <iostream>
1046484543d1Sopenharmony_ci#include "ffrt.h"
1047484543d1Sopenharmony_ci
1048484543d1Sopenharmony_civoid ffrt_mutex_task()
1049484543d1Sopenharmony_ci{
1050484543d1Sopenharmony_ci    int sum = 0;
1051484543d1Sopenharmony_ci    ffrt::mutex mtx;
1052484543d1Sopenharmony_ci    for (int i = 0; i < 10; i++) {
1053484543d1Sopenharmony_ci        ffrt::submit([&sum, i, &mtx] {
1054484543d1Sopenharmony_ci             mtx.lock();
1055484543d1Sopenharmony_ci             sum = sum + i;
1056484543d1Sopenharmony_ci             mtx.unlock();
1057484543d1Sopenharmony_ci        }, {}, {});
1058484543d1Sopenharmony_ci    }
1059484543d1Sopenharmony_ci    ffrt::wait();
1060484543d1Sopenharmony_ci    std::cout << "sum = " << sum << std::endl;
1061484543d1Sopenharmony_ci}
1062484543d1Sopenharmony_ci
1063484543d1Sopenharmony_ciint main(int narg, char** argv)
1064484543d1Sopenharmony_ci{
1065484543d1Sopenharmony_ci    int r;
1066484543d1Sopenharmony_ci    ffrt::submit(ffrt_mutex_task);
1067484543d1Sopenharmony_ci    ffrt::wait();
1068484543d1Sopenharmony_ci    return 0;
1069484543d1Sopenharmony_ci}
1070484543d1Sopenharmony_ci```
1071484543d1Sopenharmony_ci
1072484543d1Sopenharmony_ci预期输出为
1073484543d1Sopenharmony_ci
1074484543d1Sopenharmony_ci```
1075484543d1Sopenharmony_cisum=45
1076484543d1Sopenharmony_ci```
1077484543d1Sopenharmony_ci
1078484543d1Sopenharmony_ci* 该例子为功能示例,实际中并不鼓励这样使用
1079484543d1Sopenharmony_ci
1080484543d1Sopenharmony_ci### shared_mutex
1081484543d1Sopenharmony_ci<hr/>
1082484543d1Sopenharmony_ci* FFRT提供的类似std::shared_mutex 的性能实现
1083484543d1Sopenharmony_ci
1084484543d1Sopenharmony_ci#### 声明
1085484543d1Sopenharmony_ci
1086484543d1Sopenharmony_ci```{.cpp}
1087484543d1Sopenharmony_cinamespace ffrt {
1088484543d1Sopenharmony_ciclass shared_mutex {
1089484543d1Sopenharmony_cipublic:
1090484543d1Sopenharmony_ci    shared_mutex(shared_mutex const &) = delete;
1091484543d1Sopenharmony_ci    void operator =(shared_mutex const &) = delete;
1092484543d1Sopenharmony_ci
1093484543d1Sopenharmony_ci    void lock();
1094484543d1Sopenharmony_ci    void unlock();
1095484543d1Sopenharmony_ci    bool try_lock();
1096484543d1Sopenharmony_ci
1097484543d1Sopenharmony_ci    void lock_shared();
1098484543d1Sopenharmony_ci    void unlock_shared();
1099484543d1Sopenharmony_ci    bool try_lock_shared();
1100484543d1Sopenharmony_ci};
1101484543d1Sopenharmony_ci}
1102484543d1Sopenharmony_ci```
1103484543d1Sopenharmony_ci
1104484543d1Sopenharmony_ci#### 参数
1105484543d1Sopenharmony_ci
1106484543d1Sopenharmony_ci* 不涉及
1107484543d1Sopenharmony_ci
1108484543d1Sopenharmony_ci#### 返回值
1109484543d1Sopenharmony_ci
1110484543d1Sopenharmony_ci* 不涉及
1111484543d1Sopenharmony_ci
1112484543d1Sopenharmony_ci#### 描述
1113484543d1Sopenharmony_ci* 该功能能够避免传统的std::shared_mutex 在抢不到锁时陷入内核的问题,在使用得当的条件下将会有更好的性能
1114484543d1Sopenharmony_ci
1115484543d1Sopenharmony_ci#### 样例
1116484543d1Sopenharmony_ci
1117484543d1Sopenharmony_ci```{.cpp}
1118484543d1Sopenharmony_ci#include <iostream>
1119484543d1Sopenharmony_ci#include "ffrt_inner.h"
1120484543d1Sopenharmony_ci
1121484543d1Sopenharmony_civoid ffrt_shared_mutex_task()
1122484543d1Sopenharmony_ci{
1123484543d1Sopenharmony_ci    int sum = 0;
1124484543d1Sopenharmony_ci    ffrt::shared_mutex mtx;
1125484543d1Sopenharmony_ci    for (int i = 0; i < 10; i++) {
1126484543d1Sopenharmony_ci        ffrt::submit([&sum, i, &mtx] {
1127484543d1Sopenharmony_ci             mtx.lock();
1128484543d1Sopenharmony_ci             sum = sum + i;
1129484543d1Sopenharmony_ci             mtx.unlock();
1130484543d1Sopenharmony_ci        }, {}, {});
1131484543d1Sopenharmony_ci        for (int j = 0; j < 5; j++) {
1132484543d1Sopenharmony_ci            ffrt::submit([&sum, j, &mtx] {
1133484543d1Sopenharmony_ci                mtx.lock_shared();
1134484543d1Sopenharmony_ci                std::cout << "sum = " << sum << std::endl;
1135484543d1Sopenharmony_ci                mtx.unlock_shared();
1136484543d1Sopenharmony_ci            }, {}, {});
1137484543d1Sopenharmony_ci        }
1138484543d1Sopenharmony_ci    }
1139484543d1Sopenharmony_ci    ffrt::wait();
1140484543d1Sopenharmony_ci    std::cout << "sum = " << sum << std::endl;
1141484543d1Sopenharmony_ci}
1142484543d1Sopenharmony_ci
1143484543d1Sopenharmony_ciint main(int narg, char** argv)
1144484543d1Sopenharmony_ci{
1145484543d1Sopenharmony_ci    int r;
1146484543d1Sopenharmony_ci    ffrt::submit(ffrt_shared_mutex_task);
1147484543d1Sopenharmony_ci    ffrt::wait();
1148484543d1Sopenharmony_ci    return 0;
1149484543d1Sopenharmony_ci}
1150484543d1Sopenharmony_ci```
1151484543d1Sopenharmony_ci
1152484543d1Sopenharmony_ci预期输出为
1153484543d1Sopenharmony_ci
1154484543d1Sopenharmony_ci```
1155484543d1Sopenharmony_cisum=45
1156484543d1Sopenharmony_ci```
1157484543d1Sopenharmony_ci
1158484543d1Sopenharmony_ci* 该例子为功能示例,实际中并不鼓励这样使用
1159484543d1Sopenharmony_ci
1160484543d1Sopenharmony_ci### condition_variable
1161484543d1Sopenharmony_ci<hr/>
1162484543d1Sopenharmony_ci
1163484543d1Sopenharmony_ci* FFRT提供的类似std::condition_variable 的性能实现
1164484543d1Sopenharmony_ci
1165484543d1Sopenharmony_ci#### 声明
1166484543d1Sopenharmony_ci
1167484543d1Sopenharmony_ci```{.cpp}
1168484543d1Sopenharmony_cinamespace ffrt {
1169484543d1Sopenharmony_cienum class cv_status {
1170484543d1Sopenharmony_ci    no_timeout,
1171484543d1Sopenharmony_ci    timeout
1172484543d1Sopenharmony_ci};
1173484543d1Sopenharmony_ci
1174484543d1Sopenharmony_ciclass condition_variable {
1175484543d1Sopenharmony_cipublic:
1176484543d1Sopenharmony_ci    using TimePoint = std::chrono::steady_clock::time_point;
1177484543d1Sopenharmony_ci    template<typename Clock, typename Duration, typename Pred>
1178484543d1Sopenharmony_ci    bool wait_until(std::unique_lock<mutex>& lk,
1179484543d1Sopenharmony_ci            const std::chrono::time_point<Clock, Duration>& tp,
1180484543d1Sopenharmony_ci            Pred&& pred) noexcept;
1181484543d1Sopenharmony_ci
1182484543d1Sopenharmony_ci    template<typename Clock, typename Duration>
1183484543d1Sopenharmony_ci    cv_status wait_until(std::unique_lock<mutex>& lk,
1184484543d1Sopenharmony_ci            const std::chrono::time_point<Clock, Duration>& tp) noexcept;
1185484543d1Sopenharmony_ci
1186484543d1Sopenharmony_ci    template<typename Rep, typename Period>
1187484543d1Sopenharmony_ci    cv_status wait_for(std::unique_lock<mutex>& lk,
1188484543d1Sopenharmony_ci            const std::chrono::duration<Rep, Period>& sleep_time) noexcept;
1189484543d1Sopenharmony_ci
1190484543d1Sopenharmony_ci    template<typename Rep, typename Period, typename Pred>
1191484543d1Sopenharmony_ci    bool wait_for(std::unique_lock<mutex>& lk,
1192484543d1Sopenharmony_ci            const std::chrono::duration<Rep, Period>& sleepTime,
1193484543d1Sopenharmony_ci            Pred&& pred) noexcept;
1194484543d1Sopenharmony_ci
1195484543d1Sopenharmony_ci    void wait(std::unique_lock<mutex>& lk);
1196484543d1Sopenharmony_ci
1197484543d1Sopenharmony_ci    template<typename Pred>
1198484543d1Sopenharmony_ci    void wait(std::unique_lock<mutex>& lk, Pred&& pred);
1199484543d1Sopenharmony_ci
1200484543d1Sopenharmony_ci    void notify_one() noexcept;
1201484543d1Sopenharmony_ci
1202484543d1Sopenharmony_ci    void notify_all() noexcept;
1203484543d1Sopenharmony_ci};
1204484543d1Sopenharmony_ci}
1205484543d1Sopenharmony_ci```
1206484543d1Sopenharmony_ci
1207484543d1Sopenharmony_ci#### 参数
1208484543d1Sopenharmony_ci
1209484543d1Sopenharmony_ci`lk`
1210484543d1Sopenharmony_ci* mutex互斥量
1211484543d1Sopenharmony_ci`tp`
1212484543d1Sopenharmony_ci* 等待时间
1213484543d1Sopenharmony_ci`sleep_time`
1214484543d1Sopenharmony_ci* 等待时间
1215484543d1Sopenharmony_ci`pred`
1216484543d1Sopenharmony_ci* 检查是否等待函数
1217484543d1Sopenharmony_ci#### 返回值
1218484543d1Sopenharmony_ci
1219484543d1Sopenharmony_ci* 不涉及
1220484543d1Sopenharmony_ci
1221484543d1Sopenharmony_ci#### 描述
1222484543d1Sopenharmony_ci* 该接口只能在FFRT task 内部调用,在FFRT task 外部调用存在未定义的行为
1223484543d1Sopenharmony_ci* 该功能能够避免传统的std::condition_variable  在条件不满足时陷入内核的问题,在使用得当的条件下将会有更好的性能
1224484543d1Sopenharmony_ci
1225484543d1Sopenharmony_ci#### 样例
1226484543d1Sopenharmony_ci
1227484543d1Sopenharmony_ci```{.cpp}
1228484543d1Sopenharmony_ci#include <iostream>
1229484543d1Sopenharmony_ci#include "ffrt.h"
1230484543d1Sopenharmony_ci
1231484543d1Sopenharmony_civoid ffrt_cv_task()
1232484543d1Sopenharmony_ci{
1233484543d1Sopenharmony_ci    ffrt::condition_variable cond;
1234484543d1Sopenharmony_ci    int a = 0;
1235484543d1Sopenharmony_ci    ffrt::mutex lock_;
1236484543d1Sopenharmony_ci    ffrt::submit([&] {
1237484543d1Sopenharmony_ci        std::unique_lock lck(lock_);
1238484543d1Sopenharmony_ci        cond.wait(lck, [&] { return a == 1; });
1239484543d1Sopenharmony_ci        std::cout << "a = " << a << std::endl;
1240484543d1Sopenharmony_ci    }, {}, {});
1241484543d1Sopenharmony_ci    ffrt::submit([&] {
1242484543d1Sopenharmony_ci        std::unique_lock lck(lock_);
1243484543d1Sopenharmony_ci        a = 1;
1244484543d1Sopenharmony_ci        cond.notify_one();
1245484543d1Sopenharmony_ci    }, {}, {});
1246484543d1Sopenharmony_ci
1247484543d1Sopenharmony_ci    ffrt::wait();
1248484543d1Sopenharmony_ci}
1249484543d1Sopenharmony_ci
1250484543d1Sopenharmony_ciint main(int narg, char** argv)
1251484543d1Sopenharmony_ci{
1252484543d1Sopenharmony_ci    int r;
1253484543d1Sopenharmony_ci    ffrt::submit(ffrt_cv_task);
1254484543d1Sopenharmony_ci    ffrt::wait();
1255484543d1Sopenharmony_ci    return 0;
1256484543d1Sopenharmony_ci}
1257484543d1Sopenharmony_ci
1258484543d1Sopenharmony_ci```
1259484543d1Sopenharmony_ci
1260484543d1Sopenharmony_ci预期输出为:
1261484543d1Sopenharmony_ci
1262484543d1Sopenharmony_ci```
1263484543d1Sopenharmony_cia=1
1264484543d1Sopenharmony_ci```
1265484543d1Sopenharmony_ci
1266484543d1Sopenharmony_ci* 该例子为功能示例,实际中并不鼓励这样使用
1267484543d1Sopenharmony_ci
1268484543d1Sopenharmony_ci## 杂项
1269484543d1Sopenharmony_ci
1270484543d1Sopenharmony_ci### sleep
1271484543d1Sopenharmony_ci
1272484543d1Sopenharmony_ci<hr/>
1273484543d1Sopenharmony_ci* FFRT提供的类似std::this_thread::sleep_for / std::this_thread::sleep_until 的性能实现
1274484543d1Sopenharmony_ci
1275484543d1Sopenharmony_ci#### 声明
1276484543d1Sopenharmony_ci
1277484543d1Sopenharmony_ci```{.cpp}
1278484543d1Sopenharmony_cinamespace ffrt {
1279484543d1Sopenharmony_cinamespace this_task {
1280484543d1Sopenharmony_citemplate<class _Rep, class _Period>
1281484543d1Sopenharmony_civoid sleep_for(const std::chrono::duration<_Rep, _Period>& sleep_duration);
1282484543d1Sopenharmony_ci
1283484543d1Sopenharmony_citemplate<class _Clock, class _Duration>
1284484543d1Sopenharmony_civoid sleep_until(const std::chrono::time_point<_Clock, _Duration>& sleep_time);
1285484543d1Sopenharmony_ci}
1286484543d1Sopenharmony_ci}
1287484543d1Sopenharmony_ci```
1288484543d1Sopenharmony_ci
1289484543d1Sopenharmony_ci#### 参数
1290484543d1Sopenharmony_ci
1291484543d1Sopenharmony_ci`sleep_duration`
1292484543d1Sopenharmony_ci
1293484543d1Sopenharmony_ci* 睡眠的时长
1294484543d1Sopenharmony_ci
1295484543d1Sopenharmony_ci`sleep_time`
1296484543d1Sopenharmony_ci
1297484543d1Sopenharmony_ci* 睡眠到达的时间点
1298484543d1Sopenharmony_ci
1299484543d1Sopenharmony_ci#### 返回值
1300484543d1Sopenharmony_ci
1301484543d1Sopenharmony_ci* 不涉及
1302484543d1Sopenharmony_ci
1303484543d1Sopenharmony_ci#### 描述
1304484543d1Sopenharmony_ci* 该接口只能在FFRT task 内部调用,在FFRT task 外部调用存在未定义的行为
1305484543d1Sopenharmony_ci* 该功能能够避免传统的std::this_thread::sleep_for 睡眠时陷入内核的问题,在使用得当的条件下将会有更好的性能
1306484543d1Sopenharmony_ci* 该接口调用后实际睡眠时长不小于配置值
1307484543d1Sopenharmony_ci
1308484543d1Sopenharmony_ci#### 样例
1309484543d1Sopenharmony_ci
1310484543d1Sopenharmony_ci```{.cpp}
1311484543d1Sopenharmony_ci#include <chrono>
1312484543d1Sopenharmony_ci#include <iostream>
1313484543d1Sopenharmony_ci#include "ffrt.h"
1314484543d1Sopenharmony_ci
1315484543d1Sopenharmony_ciusing namespace std::chrono_literals;
1316484543d1Sopenharmony_ciint main(int narg, char** argv)
1317484543d1Sopenharmony_ci{
1318484543d1Sopenharmony_ci    ffrt::submit([] {
1319484543d1Sopenharmony_ci        std::cout << "Hello waiter\n" << std::flush;
1320484543d1Sopenharmony_ci        auto start = std::chrono::high_resolution_clock::now();
1321484543d1Sopenharmony_ci        ffrt::this_task::sleep_for(2000ms);
1322484543d1Sopenharmony_ci        auto end = std::chrono::high_resolution_clock::now();
1323484543d1Sopenharmony_ci        std::chrono::duration<double, std::milli> elapsed = end-start;
1324484543d1Sopenharmony_ci        std::cout << "Waited " << elapsed.count() << " ms\n";
1325484543d1Sopenharmony_ci    });
1326484543d1Sopenharmony_ci    ffrt::wait();
1327484543d1Sopenharmony_ci    return 0;
1328484543d1Sopenharmony_ci}
1329484543d1Sopenharmony_ci```
1330484543d1Sopenharmony_ci
1331484543d1Sopenharmony_ci* 预期输出为
1332484543d1Sopenharmony_ci
1333484543d1Sopenharmony_ci```
1334484543d1Sopenharmony_ciHello waiter
1335484543d1Sopenharmony_ciWaited 2000.12 ms
1336484543d1Sopenharmony_ci```
1337484543d1Sopenharmony_ci
1338484543d1Sopenharmony_ci### yield
1339484543d1Sopenharmony_ci<hr/>
1340484543d1Sopenharmony_ci* 当前task 主动让出CPU 执行资源,让其他可以被执行的task 先执行,如果没有其他可被执行的task,yield 无效
1341484543d1Sopenharmony_ci
1342484543d1Sopenharmony_ci#### 声明
1343484543d1Sopenharmony_ci
1344484543d1Sopenharmony_ci```{.cpp}
1345484543d1Sopenharmony_cinamespace ffrt {
1346484543d1Sopenharmony_cinamespace this_task {
1347484543d1Sopenharmony_civoid yield();
1348484543d1Sopenharmony_ci}
1349484543d1Sopenharmony_ci}
1350484543d1Sopenharmony_ci```
1351484543d1Sopenharmony_ci
1352484543d1Sopenharmony_ci#### 参数
1353484543d1Sopenharmony_ci
1354484543d1Sopenharmony_ci* 不涉及
1355484543d1Sopenharmony_ci
1356484543d1Sopenharmony_ci#### 返回值
1357484543d1Sopenharmony_ci
1358484543d1Sopenharmony_ci* 不涉及
1359484543d1Sopenharmony_ci
1360484543d1Sopenharmony_ci#### 描述
1361484543d1Sopenharmony_ci* 该接口只能在FFRT task 内部调用,在FFRT task 外部调用存在未定义的行为
1362484543d1Sopenharmony_ci* 此函数的确切行为取决于实现,特别是使用中的FFRT 调度程序的机制和系统状态
1363484543d1Sopenharmony_ci
1364484543d1Sopenharmony_ci#### 样例
1365484543d1Sopenharmony_ci
1366484543d1Sopenharmony_ci```{.cpp}
1367484543d1Sopenharmony_ci#include <chrono>
1368484543d1Sopenharmony_ci#include "ffrt.h"
1369484543d1Sopenharmony_ci
1370484543d1Sopenharmony_ciusing namespace std::chrono_literals;
1371484543d1Sopenharmony_ci// "busy sleep" while suggesting that other tasks run 
1372484543d1Sopenharmony_ci// for a small amount of time
1373484543d1Sopenharmony_civoid little_sleep(std::chrono::microseconds us)
1374484543d1Sopenharmony_ci{
1375484543d1Sopenharmony_ci    auto start = std::chrono::high_resolution_clock::now();
1376484543d1Sopenharmony_ci    auto end = start + us;
1377484543d1Sopenharmony_ci    do {
1378484543d1Sopenharmony_ci        ffrt::this_task::yield();
1379484543d1Sopenharmony_ci    } while (std::chrono::high_resolution_clock::now() < end);
1380484543d1Sopenharmony_ci}
1381484543d1Sopenharmony_ci
1382484543d1Sopenharmony_ciint main(int narg, char** argv)
1383484543d1Sopenharmony_ci{
1384484543d1Sopenharmony_ci    ffrt::submit([] { little_sleep(200us); });
1385484543d1Sopenharmony_ci    ffrt::wait();
1386484543d1Sopenharmony_ci    return 0;
1387484543d1Sopenharmony_ci}
1388484543d1Sopenharmony_ci```
1389484543d1Sopenharmony_ci
1390484543d1Sopenharmony_ci* 这是一个`busy sleep`,同时允许其他可以被执行的task 插入执行
1391484543d1Sopenharmony_ci
1392484543d1Sopenharmony_ci
1393484543d1Sopenharmony_ci# C API
1394484543d1Sopenharmony_ci
1395484543d1Sopenharmony_ci> C API采用接近C11/pthread (https://zh.cppreference.com/w/c) 的命名风格,并冠以`ffrt_`前缀,以`_base`为后缀的API是内部API,通常不被用户直接调用
1396484543d1Sopenharmony_ci>
1397484543d1Sopenharmony_ci> **出于易用性方面的考虑,除非必要,强烈建议你使用C++ API(亦满足二进制兼容要求),调用C API将会使你的代码非常臃肿** 
1398484543d1Sopenharmony_ci
1399484543d1Sopenharmony_ci## 任务管理
1400484543d1Sopenharmony_ci
1401484543d1Sopenharmony_ci### ffrt_submit_base
1402484543d1Sopenharmony_ci
1403484543d1Sopenharmony_ci* 该接口为ffrt动态库的导出接口,基于此可以封装出不同的C++ API ffrt::submit和C API ffrt_submit,满足二进制兼容
1404484543d1Sopenharmony_ci
1405484543d1Sopenharmony_ci#### 声明
1406484543d1Sopenharmony_ci
1407484543d1Sopenharmony_ci```{.cpp}
1408484543d1Sopenharmony_ciconst int ffrt_auto_managed_function_storage_size = 64 + sizeof(ffrt_function_header_t);
1409484543d1Sopenharmony_citypedef enum {
1410484543d1Sopenharmony_ci    ffrt_function_kind_general,
1411484543d1Sopenharmony_ci    ffrt_function_kind_queue
1412484543d1Sopenharmony_ci} ffrt_function_kind_t;
1413484543d1Sopenharmony_ci
1414484543d1Sopenharmony_civoid* ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_t kind);
1415484543d1Sopenharmony_ci
1416484543d1Sopenharmony_citypedef void(*ffrt_function_t)(void*);
1417484543d1Sopenharmony_citypedef struct {
1418484543d1Sopenharmony_ci    ffrt_function_t exec;
1419484543d1Sopenharmony_ci    ffrt_function_t destroy;
1420484543d1Sopenharmony_ci    uint64_t reserve[2];
1421484543d1Sopenharmony_ci} ffrt_function_header_t;
1422484543d1Sopenharmony_ci
1423484543d1Sopenharmony_civoid ffrt_submit_base(ffrt_function_header_t* func, const ffrt_deps_t* in_deps, const ffrt_deps_t* out_deps, const ffrt_task_attr_t* attr);
1424484543d1Sopenharmony_ci```
1425484543d1Sopenharmony_ci
1426484543d1Sopenharmony_ci#### 参数
1427484543d1Sopenharmony_ci
1428484543d1Sopenharmony_ci`kind`
1429484543d1Sopenharmony_ci
1430484543d1Sopenharmony_ci* function子类型,用于优化内部数据结构,默认使用ffrt_function_kind_general类型
1431484543d1Sopenharmony_ci
1432484543d1Sopenharmony_ci`func`
1433484543d1Sopenharmony_ci
1434484543d1Sopenharmony_ci* CPU Function的指针,该指针执行的数据结构,按照`ffrt_function_header_t`定义的描述了该CPU Task如何执行和销毁的函数指针,FFRT通过这两个函数指针完成Task的执行和销毁
1435484543d1Sopenharmony_ci
1436484543d1Sopenharmony_ci`in_deps`
1437484543d1Sopenharmony_ci
1438484543d1Sopenharmony_ci* 同ffrt_submit
1439484543d1Sopenharmony_ci
1440484543d1Sopenharmony_ci
1441484543d1Sopenharmony_ci`out_deps`
1442484543d1Sopenharmony_ci
1443484543d1Sopenharmony_ci* 同ffrt_submit
1444484543d1Sopenharmony_ci
1445484543d1Sopenharmony_ci`attr`
1446484543d1Sopenharmony_ci
1447484543d1Sopenharmony_ci* 同ffrt_submit
1448484543d1Sopenharmony_ci
1449484543d1Sopenharmony_ci#### 返回值
1450484543d1Sopenharmony_ci
1451484543d1Sopenharmony_ci* 不涉及
1452484543d1Sopenharmony_ci
1453484543d1Sopenharmony_ci#### 描述
1454484543d1Sopenharmony_ci
1455484543d1Sopenharmony_ci* ffrt_submit_base不建议用户直接调用,推荐使用基于此封装的C++接口(亦满足二进制兼容)
1456484543d1Sopenharmony_ci* **ffrt_submit_base作为底层能力,只有在用户需要自定义task类型时使用,使用时需要满足以下限制:**
1457484543d1Sopenharmony_ci  * ffrt_submit_base入参中的func指针只能通过ffrt_alloc_auto_managed_function_storage_base申请,且二者的调用需一一对应
1458484543d1Sopenharmony_ci  * ffrt_alloc_auto_managed_function_storage_base申请的内存为ffrt_auto_managed_function_storage_size字节,其生命周期归ffrt管理,在该task结束时,由FFRT自动释放,用户无需释放
1459484543d1Sopenharmony_ci* ffrt_function_header_t 中定义了两个函数指针:
1460484543d1Sopenharmony_ci  * exec:用于描述该Task如何被执行,当FFRT需要执行该Task时由FFRT调用
1461484543d1Sopenharmony_ci  * destroy:用于描述该Task如何被执行,当FFRT需要执行该Task时由FFRT调用
1462484543d1Sopenharmony_ci
1463484543d1Sopenharmony_ci#### 样例
1464484543d1Sopenharmony_ci
1465484543d1Sopenharmony_ci* 通过该接口提供C++11 Lambda表达式的支持(该代码已经在ffrr.h中提供,默认支持)
1466484543d1Sopenharmony_ci
1467484543d1Sopenharmony_ci```{.cpp}
1468484543d1Sopenharmony_citemplate<class T>
1469484543d1Sopenharmony_cistruct function {
1470484543d1Sopenharmony_ci    template<class CT>
1471484543d1Sopenharmony_ci    function(ffrt_function_header_t h, CT&& c) : header(h), closure(std::forward<CT>(c)) {}
1472484543d1Sopenharmony_ci    ffrt_function_header_t header;
1473484543d1Sopenharmony_ci    T closure;
1474484543d1Sopenharmony_ci};
1475484543d1Sopenharmony_ci
1476484543d1Sopenharmony_citemplate<class T>
1477484543d1Sopenharmony_civoid exec_function_wrapper(void* t)
1478484543d1Sopenharmony_ci{
1479484543d1Sopenharmony_ci    auto f = (function<std::decay_t<T>>*)t;
1480484543d1Sopenharmony_ci    f->closure();
1481484543d1Sopenharmony_ci}
1482484543d1Sopenharmony_ci
1483484543d1Sopenharmony_citemplate<class T>
1484484543d1Sopenharmony_civoid destroy_function_wrapper(void* t)
1485484543d1Sopenharmony_ci{
1486484543d1Sopenharmony_ci    auto f = (function<std::decay_t<T>>*)t;
1487484543d1Sopenharmony_ci    f->closure = nullptr;
1488484543d1Sopenharmony_ci}
1489484543d1Sopenharmony_ci
1490484543d1Sopenharmony_citemplate<class T>
1491484543d1Sopenharmony_ciinline ffrt_function_header_t* create_function_wrapper(T&& func)
1492484543d1Sopenharmony_ci{
1493484543d1Sopenharmony_ci    using function_type = function<std::decay_t<T>>;
1494484543d1Sopenharmony_ci    static_assert(sizeof(function_type) <= ffrt_auto_managed_function_storage_size,
1495484543d1Sopenharmony_ci        "size of function must be less than ffrt_auto_managed_function_storage_size");
1496484543d1Sopenharmony_ci
1497484543d1Sopenharmony_ci    auto p = ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
1498484543d1Sopenharmony_ci    auto f = new (p) function_type(
1499484543d1Sopenharmony_ci        {exec_function_wrapper<T>, destroy_function_wrapper<T>},
1500484543d1Sopenharmony_ci        std::forward<T>(func));
1501484543d1Sopenharmony_ci    return (ffrt_function_header_t*)f;
1502484543d1Sopenharmony_ci}
1503484543d1Sopenharmony_ci
1504484543d1Sopenharmony_cistatic inline void submit(std::function<void()>&& func)
1505484543d1Sopenharmony_ci{
1506484543d1Sopenharmony_ci    return ffrt_submit_base(create_function_wrapper(std::move(func)), NULL, NULL, NULL);
1507484543d1Sopenharmony_ci}
1508484543d1Sopenharmony_ci```
1509484543d1Sopenharmony_ci
1510484543d1Sopenharmony_ci### ffrt_wait
1511484543d1Sopenharmony_ci
1512484543d1Sopenharmony_ci<hr/>
1513484543d1Sopenharmony_ci* 同步等待,与ffrt_submit 配合使用
1514484543d1Sopenharmony_ci* 等待指定的数据被生产完成,或等待当前任务的所有子任务完成,在不满足条件之前,当前的执行上下文被suspend,在满足条件后恢复执行
1515484543d1Sopenharmony_ci
1516484543d1Sopenharmony_ci#### 声明
1517484543d1Sopenharmony_ci
1518484543d1Sopenharmony_ci```{.cpp}
1519484543d1Sopenharmony_civoid ffrt_wait_deps(ffrt_deps_t* deps);
1520484543d1Sopenharmony_civoid ffrt_wait();
1521484543d1Sopenharmony_ci```
1522484543d1Sopenharmony_ci
1523484543d1Sopenharmony_ci#### 参数
1524484543d1Sopenharmony_ci
1525484543d1Sopenharmony_ci`deps`
1526484543d1Sopenharmony_ci
1527484543d1Sopenharmony_ci* 需要等待被生产完成的数据的虚拟地址,这些地址可能作为某些任务在submit 时的out_deps,该依赖的生成见ffrt_deps_t章节,空指针表示无依赖
1528484543d1Sopenharmony_ci
1529484543d1Sopenharmony_ci#### 返回值
1530484543d1Sopenharmony_ci
1531484543d1Sopenharmony_ci* 不涉及
1532484543d1Sopenharmony_ci
1533484543d1Sopenharmony_ci#### 描述
1534484543d1Sopenharmony_ci* ffrt_wait_deps(deps) 用于等待deps指代的数据被生产完成才能执行后面的代码
1535484543d1Sopenharmony_ci* ffrt_wait() 用于等待当前上下文提交的所有子任务(`注意:不包括孙任务和下级子任务`)都完成才能执行后面的代码
1536484543d1Sopenharmony_ci* 该接口支持在FFRT task 内部调用,也支持在FFRT task 外部调用
1537484543d1Sopenharmony_ci* 在FFRT task 外部调用的wait 是OS 能够感知的等待,相对于FFRT task 内部调用的wait 是更加昂贵的,因此我们希望尽可能让更多的wait 发生在FFRT task 内部 ,而不是FFRT task 外部
1538484543d1Sopenharmony_ci
1539484543d1Sopenharmony_ci#### 样例
1540484543d1Sopenharmony_ci
1541484543d1Sopenharmony_ci**recursive fibonacci**
1542484543d1Sopenharmony_ci
1543484543d1Sopenharmony_ci串行版的fibonacci 可以实现为:
1544484543d1Sopenharmony_ci
1545484543d1Sopenharmony_ci```{.c}
1546484543d1Sopenharmony_ci#include <stdio.h>
1547484543d1Sopenharmony_ci
1548484543d1Sopenharmony_civoid fib(int x, int* y) {
1549484543d1Sopenharmony_ci    if (x <= 1) {
1550484543d1Sopenharmony_ci        *y = x;
1551484543d1Sopenharmony_ci    } else {
1552484543d1Sopenharmony_ci        int y1, y2;
1553484543d1Sopenharmony_ci        fib(x - 1, &y1);
1554484543d1Sopenharmony_ci        fib(x - 2, &y2);
1555484543d1Sopenharmony_ci        *y = y1 + y2;
1556484543d1Sopenharmony_ci    }
1557484543d1Sopenharmony_ci}
1558484543d1Sopenharmony_ciint main(int narg, char** argv)
1559484543d1Sopenharmony_ci{
1560484543d1Sopenharmony_ci    int r;
1561484543d1Sopenharmony_ci    fib(10, &r);
1562484543d1Sopenharmony_ci    printf("fibonacci 10: %d\n", r);
1563484543d1Sopenharmony_ci    return 0;
1564484543d1Sopenharmony_ci}
1565484543d1Sopenharmony_ci```
1566484543d1Sopenharmony_ci
1567484543d1Sopenharmony_ci若要使用 FFRT 实现并行(注,对于单纯的fibonacci,单个 Task 的计算量极小,不具有并行加速的意义,但这种调用pattern 对并行编程模型的灵活性考验是非常高的),其中1种可行的实现为:
1568484543d1Sopenharmony_ci
1569484543d1Sopenharmony_ci```{.c}
1570484543d1Sopenharmony_ci#include <stdio.h>
1571484543d1Sopenharmony_ci#include "ffrt.h"
1572484543d1Sopenharmony_ci
1573484543d1Sopenharmony_citypedef struct {
1574484543d1Sopenharmony_ci    int x;
1575484543d1Sopenharmony_ci    int* y;
1576484543d1Sopenharmony_ci} fib_ffrt_s;
1577484543d1Sopenharmony_ci
1578484543d1Sopenharmony_citypedef struct {
1579484543d1Sopenharmony_ci    ffrt_function_header_t header;
1580484543d1Sopenharmony_ci    ffrt_function_t func;
1581484543d1Sopenharmony_ci    ffrt_function_t after_func;
1582484543d1Sopenharmony_ci    void* arg;
1583484543d1Sopenharmony_ci} c_function;
1584484543d1Sopenharmony_ci
1585484543d1Sopenharmony_cistatic void ffrt_exec_function_wrapper(void* t)
1586484543d1Sopenharmony_ci{
1587484543d1Sopenharmony_ci    c_function* f = (c_function*)t;
1588484543d1Sopenharmony_ci    if (f->func) {
1589484543d1Sopenharmony_ci        f->func(f->arg);
1590484543d1Sopenharmony_ci    }
1591484543d1Sopenharmony_ci}
1592484543d1Sopenharmony_ci
1593484543d1Sopenharmony_cistatic void ffrt_destroy_function_wrapper(void* t)
1594484543d1Sopenharmony_ci{
1595484543d1Sopenharmony_ci    c_function* f = (c_function*)t;
1596484543d1Sopenharmony_ci    if (f->after_func) {
1597484543d1Sopenharmony_ci        f->after_func(f->arg);
1598484543d1Sopenharmony_ci    }
1599484543d1Sopenharmony_ci}
1600484543d1Sopenharmony_ci
1601484543d1Sopenharmony_ci#define FFRT_STATIC_ASSERT(cond, msg) int x(int static_assertion_##msg[(cond) ? 1 : -1])
1602484543d1Sopenharmony_cistatic inline ffrt_function_header_t* ffrt_create_function_wrapper(const ffrt_function_t func,
1603484543d1Sopenharmony_ci    const ffrt_function_t after_func, void* arg)
1604484543d1Sopenharmony_ci{
1605484543d1Sopenharmony_ci    FFRT_STATIC_ASSERT(sizeof(c_function) <= ffrt_auto_managed_function_storage_size,
1606484543d1Sopenharmony_ci        size_of_function_must_be_less_than_ffrt_auto_managed_function_storage_size);
1607484543d1Sopenharmony_ci    c_function* f = (c_function*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
1608484543d1Sopenharmony_ci    f->header.exec = ffrt_exec_function_wrapper;
1609484543d1Sopenharmony_ci    f->header.destroy = ffrt_destroy_function_wrapper;
1610484543d1Sopenharmony_ci    f->func = func;
1611484543d1Sopenharmony_ci    f->after_func = after_func;
1612484543d1Sopenharmony_ci    f->arg = arg;
1613484543d1Sopenharmony_ci    return (ffrt_function_header_t*)f;
1614484543d1Sopenharmony_ci}
1615484543d1Sopenharmony_ci
1616484543d1Sopenharmony_cistatic inline void ffrt_submit_c(ffrt_function_t func, const ffrt_function_t after_func,
1617484543d1Sopenharmony_ci    void* arg, const ffrt_deps_t* in_deps, const ffrt_deps_t* out_deps, const ffrt_task_attr_t* attr)
1618484543d1Sopenharmony_ci{
1619484543d1Sopenharmony_ci    ffrt_submit_base(ffrt_create_function_wrapper(func, after_func, arg), in_deps, out_deps, attr);
1620484543d1Sopenharmony_ci}
1621484543d1Sopenharmony_ci
1622484543d1Sopenharmony_civoid fib_ffrt(void* arg)
1623484543d1Sopenharmony_ci{
1624484543d1Sopenharmony_ci    fib_ffrt_s* p = (fib_ffrt_s*)arg;
1625484543d1Sopenharmony_ci    int x = p->x;
1626484543d1Sopenharmony_ci    int* y = p->y;
1627484543d1Sopenharmony_ci
1628484543d1Sopenharmony_ci    if (x <= 1) {
1629484543d1Sopenharmony_ci        *y = x;
1630484543d1Sopenharmony_ci    } else {
1631484543d1Sopenharmony_ci        int y1, y2;
1632484543d1Sopenharmony_ci        fib_ffrt_s s1 = {x - 1, &y1};
1633484543d1Sopenharmony_ci        fib_ffrt_s s2 = {x - 2, &y2};
1634484543d1Sopenharmony_ci        const std::vector<ffrt_dependence_t> dx_deps = {{ffrt_dependence_data, &x}};
1635484543d1Sopenharmony_ci        ffrt_deps_t dx{static_cast<uint32_t>(dx_deps.size()), dx_deps.data()};
1636484543d1Sopenharmony_ci        const std::vector<ffrt_dependence_t> dy1_deps = {{ffrt_dependence_data, &y1}};
1637484543d1Sopenharmony_ci        ffrt_deps_t dy1{static_cast<uint32_t>(dy1_deps.size()), dy1_deps.data()};
1638484543d1Sopenharmony_ci        const std::vector<ffrt_dependence_t> dy2_deps = {{ffrt_dependence_data, &y2}};
1639484543d1Sopenharmony_ci        ffrt_deps_t dy2{static_cast<uint32_t>(dy2_deps.size()), dy2_deps.data()};
1640484543d1Sopenharmony_ci        const std::vector<ffrt_dependence_t> dy12_deps = {{ffrt_dependence_data, &y1}, {ffrt_dependence_data, &y2}};
1641484543d1Sopenharmony_ci        ffrt_deps_t dy12{static_cast<uint32_t>(dy12_deps.size()), dy12_deps.data()};
1642484543d1Sopenharmony_ci        ffrt_submit_c(fib_ffrt, NULL, &s1, &dx, &dy1, NULL);
1643484543d1Sopenharmony_ci        ffrt_submit_c(fib_ffrt, NULL, &s2, &dx, &dy2, NULL);
1644484543d1Sopenharmony_ci        ffrt_wait_deps(&dy12);
1645484543d1Sopenharmony_ci        *y = y1 + y2;
1646484543d1Sopenharmony_ci    }
1647484543d1Sopenharmony_ci}
1648484543d1Sopenharmony_ci
1649484543d1Sopenharmony_ciint main(int narg, char** argv)
1650484543d1Sopenharmony_ci{
1651484543d1Sopenharmony_ci    int r;
1652484543d1Sopenharmony_ci    fib_ffrt_s s = {10, &r};
1653484543d1Sopenharmony_ci    const std::vector<ffrt_dependence_t> dr_deps = {{ffrt_dependence_data, &r}};
1654484543d1Sopenharmony_ci    ffrt_deps_t dr{static_cast<uint32_t>(dr_deps.size()), dr_deps.data()};
1655484543d1Sopenharmony_ci    ffrt_submit_c(fib_ffrt, NULL, &s, NULL, &dr, NULL);
1656484543d1Sopenharmony_ci    ffrt_wait_deps(&dr);
1657484543d1Sopenharmony_ci    printf("fibonacci 10: %d\n", r);
1658484543d1Sopenharmony_ci    return 0;
1659484543d1Sopenharmony_ci}
1660484543d1Sopenharmony_ci```
1661484543d1Sopenharmony_ci
1662484543d1Sopenharmony_ci`解析`:
1663484543d1Sopenharmony_ci
1664484543d1Sopenharmony_ci1)   将fibonacci (x-1)和fibonacci (x-2) 作为2个Task 提交给FFRT,在两个Task 完成之后将结果累加;
1665484543d1Sopenharmony_ci
1666484543d1Sopenharmony_ci2)   虽然单个Task 只能拆分成2个SubTask 但是子Task 可以继续拆分,因此,整个计算图的并行度是非常高的,Task 之间在FFRT 内部形成了一颗调用树;
1667484543d1Sopenharmony_ci
1668484543d1Sopenharmony_ci<img src="images/image-20220926152331554.png" style="zoom:100%" />
1669484543d1Sopenharmony_ci
1670484543d1Sopenharmony_ci> 以上实现,逻辑上虽与C++ API中的实现类似,但是用户显式管理数据生命周期和函数入参打包两个因素将使代码异常复杂
1671484543d1Sopenharmony_ci
1672484543d1Sopenharmony_ci
1673484543d1Sopenharmony_ci
1674484543d1Sopenharmony_ci### ffrt_deps_t
1675484543d1Sopenharmony_ci
1676484543d1Sopenharmony_ci* C API中对依赖数组的抽象,逻辑上等同于C++ API中的`std::vector<void*>`
1677484543d1Sopenharmony_ci
1678484543d1Sopenharmony_ci#### 声明
1679484543d1Sopenharmony_ci
1680484543d1Sopenharmony_ci```{.cpp}
1681484543d1Sopenharmony_citypedef struct {
1682484543d1Sopenharmony_ci    uint32_t len;
1683484543d1Sopenharmony_ci    const ffrt_dependence_t* items;
1684484543d1Sopenharmony_ci} ffrt_deps_t;
1685484543d1Sopenharmony_ci```
1686484543d1Sopenharmony_ci
1687484543d1Sopenharmony_ci#### 参数
1688484543d1Sopenharmony_ci
1689484543d1Sopenharmony_ci`len`
1690484543d1Sopenharmony_ci
1691484543d1Sopenharmony_ci* 所依赖的Signature的个数,取值大于等于0
1692484543d1Sopenharmony_ci
1693484543d1Sopenharmony_ci`item`
1694484543d1Sopenharmony_ci
1695484543d1Sopenharmony_ci* len个Signature的起始地址指针
1696484543d1Sopenharmony_ci
1697484543d1Sopenharmony_ci#### 返回值
1698484543d1Sopenharmony_ci
1699484543d1Sopenharmony_ci* 不涉及
1700484543d1Sopenharmony_ci
1701484543d1Sopenharmony_ci#### 描述
1702484543d1Sopenharmony_ci
1703484543d1Sopenharmony_ci* item为len个Signature的起始指针,该指针可以指向堆空间,也可以指向栈空间,但是要求分配的空间大于等于len * sizeof(void*)
1704484543d1Sopenharmony_ci
1705484543d1Sopenharmony_ci#### 样例
1706484543d1Sopenharmony_ci
1707484543d1Sopenharmony_ci* item指向栈空间的ffrt_deps_t
1708484543d1Sopenharmony_ci
1709484543d1Sopenharmony_ci```{.c}
1710484543d1Sopenharmony_ci#include "ffrt.h"
1711484543d1Sopenharmony_ci
1712484543d1Sopenharmony_ciint main(int narg, char** argv)
1713484543d1Sopenharmony_ci{
1714484543d1Sopenharmony_ci    int x1 = 1;
1715484543d1Sopenharmony_ci    int x2 = 2;
1716484543d1Sopenharmony_ci    
1717484543d1Sopenharmony_ci    const std::vector<ffrt_dependence_t> t_deps = {{ffrt_dependence_data, &x1}, {ffrt_dependence_data, &x2}};
1718484543d1Sopenharmony_ci    ffrt_deps_t deps{static_cast<uint32_t>(t_deps.size()), t_deps.data()};
1719484543d1Sopenharmony_ci    // some code use deps
1720484543d1Sopenharmony_ci    return 0;
1721484543d1Sopenharmony_ci}
1722484543d1Sopenharmony_ci```
1723484543d1Sopenharmony_ci
1724484543d1Sopenharmony_ci* item指向栈空间的ffrt_deps_t
1725484543d1Sopenharmony_ci
1726484543d1Sopenharmony_ci```{.c}
1727484543d1Sopenharmony_ci#include <stdlib.h>
1728484543d1Sopenharmony_ci#include "ffrt.h"
1729484543d1Sopenharmony_ci
1730484543d1Sopenharmony_ciint main(int narg, char** argv)
1731484543d1Sopenharmony_ci{
1732484543d1Sopenharmony_ci    int x1 = 1;
1733484543d1Sopenharmony_ci    int x2 = 2;
1734484543d1Sopenharmony_ci    
1735484543d1Sopenharmony_ci    ffrt_dependence_t* t = new ffrt_dependence_t[2];
1736484543d1Sopenharmony_ci    t[0]= {ffrt_dependence_data, &x1};
1737484543d1Sopenharmony_ci    t[1]= {ffrt_dependence_data, &x2};
1738484543d1Sopenharmony_ci    ffrt_deps_t deps = {2, t};
1739484543d1Sopenharmony_ci    
1740484543d1Sopenharmony_ci    // some code use deps
1741484543d1Sopenharmony_ci    return 0;
1742484543d1Sopenharmony_ci}
1743484543d1Sopenharmony_ci```
1744484543d1Sopenharmony_ci
1745484543d1Sopenharmony_ci### ffrt_task_attr_t
1746484543d1Sopenharmony_ci
1747484543d1Sopenharmony_ci<hr/>
1748484543d1Sopenharmony_ci* 定义task 的属性的辅助类,与ffrt_submit 配合使用
1749484543d1Sopenharmony_ci
1750484543d1Sopenharmony_ci#### 声明
1751484543d1Sopenharmony_ci
1752484543d1Sopenharmony_ci```{.c}
1753484543d1Sopenharmony_citypedef enum {
1754484543d1Sopenharmony_ci    ffrt_qos_inherent = -1,
1755484543d1Sopenharmony_ci    ffrt_qos_background,
1756484543d1Sopenharmony_ci    ffrt_qos_utility,
1757484543d1Sopenharmony_ci    ffrt_qos_default,
1758484543d1Sopenharmony_ci    ffrt_qos_user_initiated,
1759484543d1Sopenharmony_ci} ffrt_qos_t;
1760484543d1Sopenharmony_ci
1761484543d1Sopenharmony_citypedef struct {
1762484543d1Sopenharmony_ci    char storage[ffrt_task_attr_storage_size];
1763484543d1Sopenharmony_ci} ffrt_task_attr_t;
1764484543d1Sopenharmony_citypedef void* ffrt_task_handle_t;
1765484543d1Sopenharmony_ci
1766484543d1Sopenharmony_ciint ffrt_task_attr_init(ffrt_task_attr_t* attr);
1767484543d1Sopenharmony_civoid ffrt_task_attr_destroy(ffrt_task_attr_t* attr);
1768484543d1Sopenharmony_civoid ffrt_task_attr_set_qos(ffrt_task_attr_t* attr, ffrt_qos_t qos);
1769484543d1Sopenharmony_ciffrt_qos_t ffrt_task_attr_get_qos(const ffrt_task_attr_t* attr);
1770484543d1Sopenharmony_civoid ffrt_task_attr_set_name(ffrt_task_attr_t* attr, const char* name);
1771484543d1Sopenharmony_ciconst char* ffrt_task_attr_get_name(const ffrt_task_attr_t* attr);
1772484543d1Sopenharmony_ci```
1773484543d1Sopenharmony_ci
1774484543d1Sopenharmony_ci#### 参数
1775484543d1Sopenharmony_ci
1776484543d1Sopenharmony_ci`attr`
1777484543d1Sopenharmony_ci
1778484543d1Sopenharmony_ci* 创建的tasks属性的句柄
1779484543d1Sopenharmony_ci
1780484543d1Sopenharmony_ci`qos`
1781484543d1Sopenharmony_ci
1782484543d1Sopenharmony_ci* qos 设定的枚举类型
1783484543d1Sopenharmony_ci* inherent 是一个qos 设定策略,代表即将ffrt_submit 的task 的qos 继承当前task 的qos
1784484543d1Sopenharmony_ci
1785484543d1Sopenharmony_ci#### 返回值
1786484543d1Sopenharmony_ci
1787484543d1Sopenharmony_ci* 不涉及
1788484543d1Sopenharmony_ci
1789484543d1Sopenharmony_ci#### 描述
1790484543d1Sopenharmony_ci* `attr`所传递的内容会在ffrt_submit内部完成取存,ffrt_submit返回后用户即可销毁
1791484543d1Sopenharmony_ci* 约定
1792484543d1Sopenharmony_ci  * 在submit 时,如果不通过task_attr 设定qos,那么默认该提交的task的qos 为`ffrt_qos_default`
1793484543d1Sopenharmony_ci  * 在submit 时,如果通过task_attr 设定qos 为`ffrt_qos_inherent`,表示将该提交的task 的qos 与当前task 的qos 相同,在FFRT task 外部提交的属性为`ffrt_qos_inherent` 的task,其qos 为`ffrt_qos_default`
1794484543d1Sopenharmony_ci  * 其他情况下,该提交的task 的qos 被设定为指定的值
1795484543d1Sopenharmony_ci* ffrt_task_attr_t对象的置空和销毁由用户完成,对同一个ffrt_task_attr_t仅能调用一次`ffrt_task_attr_destroy`,重复对同一个ffrt_task_attr_t调用`ffrt_task_attr_destroy`,其行为是未定义的
1796484543d1Sopenharmony_ci* 在`ffrt_task_attr_destroy`之后再对task_attr进行访问,其行为是未定义的
1797484543d1Sopenharmony_ci
1798484543d1Sopenharmony_ci#### 样例
1799484543d1Sopenharmony_ci
1800484543d1Sopenharmony_ci```{.c}
1801484543d1Sopenharmony_ci#include <stdio.h>
1802484543d1Sopenharmony_ci#include "ffrt.h"
1803484543d1Sopenharmony_ci
1804484543d1Sopenharmony_civoid my_print(void* arg)
1805484543d1Sopenharmony_ci{
1806484543d1Sopenharmony_ci    printf("hello ffrt\n");
1807484543d1Sopenharmony_ci}
1808484543d1Sopenharmony_ci
1809484543d1Sopenharmony_citypedef struct {
1810484543d1Sopenharmony_ci    ffrt_function_header_t header;
1811484543d1Sopenharmony_ci    ffrt_function_t func;
1812484543d1Sopenharmony_ci    ffrt_function_t after_func;
1813484543d1Sopenharmony_ci    void* arg;
1814484543d1Sopenharmony_ci} c_function;
1815484543d1Sopenharmony_ci
1816484543d1Sopenharmony_cistatic void ffrt_exec_function_wrapper(void* t)
1817484543d1Sopenharmony_ci{
1818484543d1Sopenharmony_ci    c_function* f = (c_function*)t;
1819484543d1Sopenharmony_ci    if (f->func) {
1820484543d1Sopenharmony_ci        f->func(f->arg);
1821484543d1Sopenharmony_ci    }
1822484543d1Sopenharmony_ci}
1823484543d1Sopenharmony_ci
1824484543d1Sopenharmony_cistatic void ffrt_destroy_function_wrapper(void* t)
1825484543d1Sopenharmony_ci{
1826484543d1Sopenharmony_ci    c_function* f = (c_function*)t;
1827484543d1Sopenharmony_ci    if (f->after_func) {
1828484543d1Sopenharmony_ci        f->after_func(f->arg);
1829484543d1Sopenharmony_ci    }
1830484543d1Sopenharmony_ci}
1831484543d1Sopenharmony_ci
1832484543d1Sopenharmony_ci#define FFRT_STATIC_ASSERT(cond, msg) int x(int static_assertion_##msg[(cond) ? 1 : -1])
1833484543d1Sopenharmony_cistatic inline ffrt_function_header_t* ffrt_create_function_wrapper(const ffrt_function_t func,
1834484543d1Sopenharmony_ci    const ffrt_function_t after_func, void* arg)
1835484543d1Sopenharmony_ci{
1836484543d1Sopenharmony_ci    FFRT_STATIC_ASSERT(sizeof(c_function) <= ffrt_auto_managed_function_storage_size,
1837484543d1Sopenharmony_ci        size_of_function_must_be_less_than_ffrt_auto_managed_function_storage_size);
1838484543d1Sopenharmony_ci    c_function* f = (c_function*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
1839484543d1Sopenharmony_ci    f->header.exec = ffrt_exec_function_wrapper;
1840484543d1Sopenharmony_ci    f->header.destroy = ffrt_destroy_function_wrapper;
1841484543d1Sopenharmony_ci    f->func = func;
1842484543d1Sopenharmony_ci    f->after_func = after_func;
1843484543d1Sopenharmony_ci    f->arg = arg;
1844484543d1Sopenharmony_ci    return (ffrt_function_header_t*)f;
1845484543d1Sopenharmony_ci}
1846484543d1Sopenharmony_ci
1847484543d1Sopenharmony_cistatic inline void ffrt_submit_c(ffrt_function_t func, const ffrt_function_t after_func,
1848484543d1Sopenharmony_ci    void* arg, const ffrt_deps_t* in_deps, const ffrt_deps_t* out_deps, const ffrt_task_attr_t* attr)
1849484543d1Sopenharmony_ci{
1850484543d1Sopenharmony_ci    ffrt_submit_base(ffrt_create_function_wrapper(func, after_func, arg), in_deps, out_deps, attr);
1851484543d1Sopenharmony_ci}
1852484543d1Sopenharmony_ci
1853484543d1Sopenharmony_ciint main(int narg, char** argv)
1854484543d1Sopenharmony_ci{
1855484543d1Sopenharmony_ci    ffrt_task_attr_t attr;
1856484543d1Sopenharmony_ci    ffrt_task_attr_init(&attr);
1857484543d1Sopenharmony_ci    ffrt_task_attr_set_qos(&attr, ffrt_qos_background);
1858484543d1Sopenharmony_ci    ffrt_submit_c(my_print, NULL, NULL, NULL, NULL, &attr);
1859484543d1Sopenharmony_ci    ffrt_task_attr_destroy(&attr);
1860484543d1Sopenharmony_ci    ffrt_wait();
1861484543d1Sopenharmony_ci    return 0;
1862484543d1Sopenharmony_ci}
1863484543d1Sopenharmony_ci```
1864484543d1Sopenharmony_ci
1865484543d1Sopenharmony_ci* 提交一个qos 级别为background 的任务
1866484543d1Sopenharmony_ci
1867484543d1Sopenharmony_ci
1868484543d1Sopenharmony_ci
1869484543d1Sopenharmony_ci### ffrt_submit_h
1870484543d1Sopenharmony_ci
1871484543d1Sopenharmony_ci<hr/>
1872484543d1Sopenharmony_ci
1873484543d1Sopenharmony_ci* 向调度器提交一个task,与ffrt_submit 的差别在于返回task 的句柄,该句柄可以用于建立task 之间的依赖,或用于在wait 语句中实现同步
1874484543d1Sopenharmony_ci
1875484543d1Sopenharmony_ci#### 声明
1876484543d1Sopenharmony_ci
1877484543d1Sopenharmony_ci```{.cpp}
1878484543d1Sopenharmony_citypedef void* ffrt_task_handle_t;
1879484543d1Sopenharmony_ci
1880484543d1Sopenharmony_ciffrt_task_handle_t ffrt_submit_h(ffrt_function_t func, void* arg, const ffrt_deps_t* in_deps, const ffrt_deps_t* out_deps, const ffrt_task_attr_t* attr);
1881484543d1Sopenharmony_civoid ffrt_task_handle_destroy(ffrt_task_handle_t handle);
1882484543d1Sopenharmony_ci```
1883484543d1Sopenharmony_ci
1884484543d1Sopenharmony_ci#### 参数
1885484543d1Sopenharmony_ci
1886484543d1Sopenharmony_ci`func`
1887484543d1Sopenharmony_ci
1888484543d1Sopenharmony_ci* 同ffrt_submit,详见[ffrt_submit](#ffrt_submit) 定义
1889484543d1Sopenharmony_ci
1890484543d1Sopenharmony_ci`in_deps`
1891484543d1Sopenharmony_ci
1892484543d1Sopenharmony_ci* 同ffrt_submit,详见[ffrt_submit](#ffrt_submit) 定义
1893484543d1Sopenharmony_ci
1894484543d1Sopenharmony_ci`out_deps`
1895484543d1Sopenharmony_ci
1896484543d1Sopenharmony_ci* 同ffrt_submit,详见[ffrt_submit](#ffrt_submit) 定义
1897484543d1Sopenharmony_ci
1898484543d1Sopenharmony_ci`attr`
1899484543d1Sopenharmony_ci
1900484543d1Sopenharmony_ci* 同ffrt_submit,详见[ffrt_submit](#ffrt_submit) 定义
1901484543d1Sopenharmony_ci
1902484543d1Sopenharmony_ci#### 返回值
1903484543d1Sopenharmony_ci
1904484543d1Sopenharmony_ci* task 的句柄,该句柄可以用于建立task 之间的依赖,或用于在wait 语句中实现同步
1905484543d1Sopenharmony_ci
1906484543d1Sopenharmony_ci#### 描述
1907484543d1Sopenharmony_ci
1908484543d1Sopenharmony_ci* C API中的ffrt_task_handle_t的使用与C++ API中的ffrt::task_handle相同
1909484543d1Sopenharmony_ci* **差异在于:C API中的ffrt_task_handle_t需要用户调用`ffrt_task_handle_destroy`显式销毁,而C++ API无需该操作**
1910484543d1Sopenharmony_ci* C API中的task_handle_t对象的置空和销毁由用户完成,对同一个ffrt_task_handle_t仅能调用一次`ffrt_task_handle_destroy`,重复对同一个ffrt_task_handle_t调用`ffrt_task_handle_destroy`,其行为是未定义的
1911484543d1Sopenharmony_ci* 在`ffrt_task_handle_destroy`之后再对ffrt_task_handle_t进行访问,其行为是未定义的
1912484543d1Sopenharmony_ci
1913484543d1Sopenharmony_ci#### 样例
1914484543d1Sopenharmony_ci
1915484543d1Sopenharmony_ci```{.c}
1916484543d1Sopenharmony_ci#include <stdio.h>
1917484543d1Sopenharmony_ci#include "ffrt.h"
1918484543d1Sopenharmony_ci
1919484543d1Sopenharmony_civoid func0(void* arg)
1920484543d1Sopenharmony_ci{
1921484543d1Sopenharmony_ci    printf("hello ");
1922484543d1Sopenharmony_ci}
1923484543d1Sopenharmony_ci
1924484543d1Sopenharmony_civoid func1(void* arg)
1925484543d1Sopenharmony_ci{
1926484543d1Sopenharmony_ci    (*(int*)arg)++;
1927484543d1Sopenharmony_ci}
1928484543d1Sopenharmony_ci
1929484543d1Sopenharmony_civoid func2(void* arg)
1930484543d1Sopenharmony_ci{
1931484543d1Sopenharmony_ci    printf("world, x = %d\n", *(int*)arg);
1932484543d1Sopenharmony_ci}
1933484543d1Sopenharmony_ci
1934484543d1Sopenharmony_civoid func3(void* arg)
1935484543d1Sopenharmony_ci{
1936484543d1Sopenharmony_ci    printf("handle wait");
1937484543d1Sopenharmony_ci    (*(int*)arg)++;
1938484543d1Sopenharmony_ci}
1939484543d1Sopenharmony_ci
1940484543d1Sopenharmony_citypedef struct {
1941484543d1Sopenharmony_ci    ffrt_function_header_t header;
1942484543d1Sopenharmony_ci    ffrt_function_t func;
1943484543d1Sopenharmony_ci    ffrt_function_t after_func;
1944484543d1Sopenharmony_ci    void* arg;
1945484543d1Sopenharmony_ci} c_function;
1946484543d1Sopenharmony_ci
1947484543d1Sopenharmony_cistatic void ffrt_exec_function_wrapper(void* t)
1948484543d1Sopenharmony_ci{
1949484543d1Sopenharmony_ci    c_function* f = (c_function*)t;
1950484543d1Sopenharmony_ci    if (f->func) {
1951484543d1Sopenharmony_ci        f->func(f->arg);
1952484543d1Sopenharmony_ci    }
1953484543d1Sopenharmony_ci}
1954484543d1Sopenharmony_ci
1955484543d1Sopenharmony_cistatic void ffrt_destroy_function_wrapper(void* t)
1956484543d1Sopenharmony_ci{
1957484543d1Sopenharmony_ci    c_function* f = (c_function*)t;
1958484543d1Sopenharmony_ci    if (f->after_func) {
1959484543d1Sopenharmony_ci        f->after_func(f->arg);
1960484543d1Sopenharmony_ci    }
1961484543d1Sopenharmony_ci}
1962484543d1Sopenharmony_ci
1963484543d1Sopenharmony_ci#define FFRT_STATIC_ASSERT(cond, msg) int x(int static_assertion_##msg[(cond) ? 1 : -1])
1964484543d1Sopenharmony_cistatic inline ffrt_function_header_t* ffrt_create_function_wrapper(const ffrt_function_t func,
1965484543d1Sopenharmony_ci    const ffrt_function_t after_func, void* arg)
1966484543d1Sopenharmony_ci{
1967484543d1Sopenharmony_ci    FFRT_STATIC_ASSERT(sizeof(c_function) <= ffrt_auto_managed_function_storage_size,
1968484543d1Sopenharmony_ci        size_of_function_must_be_less_than_ffrt_auto_managed_function_storage_size);
1969484543d1Sopenharmony_ci    c_function* f = (c_function*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
1970484543d1Sopenharmony_ci    f->header.exec = ffrt_exec_function_wrapper;
1971484543d1Sopenharmony_ci    f->header.destroy = ffrt_destroy_function_wrapper;
1972484543d1Sopenharmony_ci    f->func = func;
1973484543d1Sopenharmony_ci    f->after_func = after_func;
1974484543d1Sopenharmony_ci    f->arg = arg;
1975484543d1Sopenharmony_ci    return (ffrt_function_header_t*)f;
1976484543d1Sopenharmony_ci}
1977484543d1Sopenharmony_ci
1978484543d1Sopenharmony_cistatic inline ffrt_task_handle_t ffrt_submit_h_c(ffrt_function_t func, const ffrt_function_t after_func,
1979484543d1Sopenharmony_ci    void* arg, const ffrt_deps_t* in_deps, const ffrt_deps_t* out_deps, const ffrt_task_attr_t* attr)
1980484543d1Sopenharmony_ci{
1981484543d1Sopenharmony_ci    return ffrt_submit_h_base(ffrt_create_function_wrapper(func, after_func, arg), in_deps, out_deps, attr);
1982484543d1Sopenharmony_ci}
1983484543d1Sopenharmony_ci
1984484543d1Sopenharmony_cistatic inline void ffrt_submit_c(ffrt_function_t func, const ffrt_function_t after_func,
1985484543d1Sopenharmony_ci    void* arg, const ffrt_deps_t* in_deps, const ffrt_deps_t* out_deps, const ffrt_task_attr_t* attr)
1986484543d1Sopenharmony_ci{
1987484543d1Sopenharmony_ci    ffrt_submit_base(ffrt_create_function_wrapper(func, after_func, arg), in_deps, out_deps, attr);
1988484543d1Sopenharmony_ci}
1989484543d1Sopenharmony_ci
1990484543d1Sopenharmony_ciint main(int narg, char** argv)
1991484543d1Sopenharmony_ci{  
1992484543d1Sopenharmony_ci    // handle work with submit
1993484543d1Sopenharmony_ci    ffrt_task_handle_t h = ffrt_submit_h_c(func0, NULL, NULL, NULL, NULL, NULL); // not need some data in this task
1994484543d1Sopenharmony_ci    int x = 1;
1995484543d1Sopenharmony_ci    const std::vector<ffrt_dependence_t> d1_deps = {{ffrt_dependence_data, &x}};
1996484543d1Sopenharmony_ci    ffrt_deps_t d1{static_cast<uint32_t>(d1_deps.size()), d1_deps.data()};
1997484543d1Sopenharmony_ci    const std::vector<ffrt_dependence_t> d2_deps = {{ffrt_dependence_data, &x}, {ffrt_dependence_data, h}};
1998484543d1Sopenharmony_ci    ffrt_deps_t d2{static_cast<uint32_t>(d2_deps.size()), d2_deps.data()};
1999484543d1Sopenharmony_ci    ffrt_submit_c(func1, NULL, &x, NULL, &d1, NULL);
2000484543d1Sopenharmony_ci    ffrt_submit_c(func2, NULL, &x, &d2, NULL, NULL); // this task depend x and h
2001484543d1Sopenharmony_ci    ffrt_task_handle_destroy(h);
2002484543d1Sopenharmony_ci    
2003484543d1Sopenharmony_ci    // handle work with wait
2004484543d1Sopenharmony_ci    ffrt_task_handle_t h2 = ffrt_submit_h_c(func3, NULL, &x, NULL, NULL, NULL);
2005484543d1Sopenharmony_ci    const std::vector<ffrt_dependence_t> d3_deps = {{ffrt_dependence_data, h2}};
2006484543d1Sopenharmony_ci    ffrt_deps_t d3{static_cast<uint32_t>(d3_deps.size()), d3_deps.data()};
2007484543d1Sopenharmony_ci    ffrt_wait_deps(&d3);
2008484543d1Sopenharmony_ci    ffrt_task_handle_destroy(h2);
2009484543d1Sopenharmony_ci    printf("x = %d", x);
2010484543d1Sopenharmony_ci    ffrt_wait();
2011484543d1Sopenharmony_ci    return 0;
2012484543d1Sopenharmony_ci}
2013484543d1Sopenharmony_ci```
2014484543d1Sopenharmony_ci
2015484543d1Sopenharmony_ci* 预期的输出为
2016484543d1Sopenharmony_ci
2017484543d1Sopenharmony_ci```
2018484543d1Sopenharmony_cihello world, x = 2
2019484543d1Sopenharmony_cihandle wait
2020484543d1Sopenharmony_cix = 3
2021484543d1Sopenharmony_ci```
2022484543d1Sopenharmony_ci
2023484543d1Sopenharmony_ci
2024484543d1Sopenharmony_ci
2025484543d1Sopenharmony_ci### ffrt_this_task_get_id
2026484543d1Sopenharmony_ci
2027484543d1Sopenharmony_ci<hr/>
2028484543d1Sopenharmony_ci
2029484543d1Sopenharmony_ci* 返回当前task的id标识,更多使用用于维测(原因是task name可能重名)
2030484543d1Sopenharmony_ci
2031484543d1Sopenharmony_ci#### 声明
2032484543d1Sopenharmony_ci
2033484543d1Sopenharmony_ci```{.c}
2034484543d1Sopenharmony_ciuint64_t ffrt_this_task_get_id();
2035484543d1Sopenharmony_ci```
2036484543d1Sopenharmony_ci
2037484543d1Sopenharmony_ci#### 参数
2038484543d1Sopenharmony_ci
2039484543d1Sopenharmony_ci* 不涉及
2040484543d1Sopenharmony_ci
2041484543d1Sopenharmony_ci#### 返回值
2042484543d1Sopenharmony_ci
2043484543d1Sopenharmony_ci* 当前task的id
2044484543d1Sopenharmony_ci
2045484543d1Sopenharmony_ci#### 描述
2046484543d1Sopenharmony_ci
2047484543d1Sopenharmony_ci* 该接口在task内部调用将返回当前task的id标识,在task外部调用将返回0
2048484543d1Sopenharmony_ci* 可以基于该接口在task外部调用返回0的特性来区分函数是运行在FFRT 工作线程上还是非FFRT工作线程上
2049484543d1Sopenharmony_ci* task id为从1开始编码,每提交一个task便增加1,被设计成64bit,即便是每秒百万次提交,也需要292471.2年才会发生翻转
2050484543d1Sopenharmony_ci
2051484543d1Sopenharmony_ci#### 样例
2052484543d1Sopenharmony_ci
2053484543d1Sopenharmony_ci* 忽略
2054484543d1Sopenharmony_ci
2055484543d1Sopenharmony_ci
2056484543d1Sopenharmony_ci
2057484543d1Sopenharmony_ci### ffrt_this_task_update_qos
2058484543d1Sopenharmony_ci
2059484543d1Sopenharmony_ci<hr/>
2060484543d1Sopenharmony_ci
2061484543d1Sopenharmony_ci* 更新当前正在执行的task的优先级
2062484543d1Sopenharmony_ci
2063484543d1Sopenharmony_ci#### 声明
2064484543d1Sopenharmony_ci
2065484543d1Sopenharmony_ci```{.cpp}
2066484543d1Sopenharmony_ciint ffrt_this_task_update_qos(ffrt_qos_t qos);
2067484543d1Sopenharmony_ci```
2068484543d1Sopenharmony_ci
2069484543d1Sopenharmony_ci#### 参数
2070484543d1Sopenharmony_ci
2071484543d1Sopenharmony_ci* `qos` 新的优先级
2072484543d1Sopenharmony_ci
2073484543d1Sopenharmony_ci#### 返回值
2074484543d1Sopenharmony_ci
2075484543d1Sopenharmony_ci* 0表示成功,非0表示失败
2076484543d1Sopenharmony_ci
2077484543d1Sopenharmony_ci#### 描述
2078484543d1Sopenharmony_ci
2079484543d1Sopenharmony_ci* 该接口对当前task的qos调整会立即生效
2080484543d1Sopenharmony_ci* 如果新设定的qos与当前的qos不一致,则会block当前task的执行,再按照新的qos恢复执行
2081484543d1Sopenharmony_ci* 如果新设定的qos与当前的qos一致,则接口会立即返回0,不做任何处理
2082484543d1Sopenharmony_ci* **如果在非task内部调用该接口,则返回非0值,用户可以选择忽略或其他处理**
2083484543d1Sopenharmony_ci
2084484543d1Sopenharmony_ci#### 样例
2085484543d1Sopenharmony_ci
2086484543d1Sopenharmony_ci* 忽略
2087484543d1Sopenharmony_ci
2088484543d1Sopenharmony_ci## 串行队列
2089484543d1Sopenharmony_ci<hr />
2090484543d1Sopenharmony_ci
2091484543d1Sopenharmony_ci基本功能与使用约束见 C++ API 中的串行队列部分
2092484543d1Sopenharmony_ci
2093484543d1Sopenharmony_ci### ffrt_queue_t 
2094484543d1Sopenharmony_ci<hr/>
2095484543d1Sopenharmony_ci
2096484543d1Sopenharmony_ci#### 描述
2097484543d1Sopenharmony_ciFFRT串行队列 C API,提供提交任务、取消任务、等待任务执行完成等功能
2098484543d1Sopenharmony_ci
2099484543d1Sopenharmony_ci#### 声明
2100484543d1Sopenharmony_ci
2101484543d1Sopenharmony_ci```{.cpp}
2102484543d1Sopenharmony_citypedef enum { ffrt_queue_serial, ffrt_queue_max } ffrt_queue_type_t;
2103484543d1Sopenharmony_citypedef void* ffrt_queue_t;
2104484543d1Sopenharmony_ci
2105484543d1Sopenharmony_ciffrt_queue_t ffrt_queue_create(ffrt_queue_type_t type, const char* name, const ffrt_queue_attr_t* attr);
2106484543d1Sopenharmony_civoid ffrt_queue_destroy(ffrt_queue_t queue);
2107484543d1Sopenharmony_ci
2108484543d1Sopenharmony_civoid ffrt_queue_submit(ffrt_queue_t queue, ffrt_function_header_t* f, const ffrt_task_attr_t* attr);
2109484543d1Sopenharmony_ciffrt_task_handle_t ffrt_queue_submit_h(
2110484543d1Sopenharmony_ci    ffrt_queue_t queue, ffrt_function_header_t* f, const ffrt_task_attr_t* attr);
2111484543d1Sopenharmony_ci
2112484543d1Sopenharmony_civoid ffrt_queue_wait(ffrt_task_handle_t handle);
2113484543d1Sopenharmony_ci
2114484543d1Sopenharmony_ciint ffrt_queue_cancel(ffrt_task_handle_t handle);
2115484543d1Sopenharmony_ci```
2116484543d1Sopenharmony_ci
2117484543d1Sopenharmony_ci#### 方法
2118484543d1Sopenharmony_ci
2119484543d1Sopenharmony_ci##### ffrt_queue_create
2120484543d1Sopenharmony_ci
2121484543d1Sopenharmony_ci```{.cpp}
2122484543d1Sopenharmony_ciffrt_queue_t ffrt_queue_create(ffrt_queue_type_t type, const char* name, const ffrt_queue_attr_t* attr);
2123484543d1Sopenharmony_ci```
2124484543d1Sopenharmony_ci
2125484543d1Sopenharmony_ci* 描述:创建串行队列
2126484543d1Sopenharmony_ci
2127484543d1Sopenharmony_ci* 参数:
2128484543d1Sopenharmony_ci
2129484543d1Sopenharmony_ci  `type`:用于描述创建的队列类型,串行队列对应 `type` 为 `ffrt_queue_serial`
2130484543d1Sopenharmony_ci
2131484543d1Sopenharmony_ci  `name`:用于描述创建的队列名称
2132484543d1Sopenharmony_ci
2133484543d1Sopenharmony_ci  `attr`:所创建的queue属性,若未设定则会使用默认值
2134484543d1Sopenharmony_ci
2135484543d1Sopenharmony_ci* 返回值:如果成功创建了队列,则返回一个非空的队列句柄;否则返回空指针
2136484543d1Sopenharmony_ci
2137484543d1Sopenharmony_ci##### ffrt_queue_destroy
2138484543d1Sopenharmony_ci
2139484543d1Sopenharmony_ci```{.cpp}
2140484543d1Sopenharmony_civoid ffrt_queue_destroy(ffrt_queue_t queue);
2141484543d1Sopenharmony_ci```
2142484543d1Sopenharmony_ci
2143484543d1Sopenharmony_ci* 描述:销毁串行队列
2144484543d1Sopenharmony_ci
2145484543d1Sopenharmony_ci* 参数:
2146484543d1Sopenharmony_ci
2147484543d1Sopenharmony_ci  `queue`:想要销毁的队列的句柄
2148484543d1Sopenharmony_ci
2149484543d1Sopenharmony_ci* 返回值:不涉及
2150484543d1Sopenharmony_ci
2151484543d1Sopenharmony_ci##### ffrt_queue_submit
2152484543d1Sopenharmony_ci
2153484543d1Sopenharmony_ci```{.cpp}
2154484543d1Sopenharmony_civoid ffrt_queue_submit(ffrt_queue_t queue, ffrt_function_header_t* f, const ffrt_task_attr_t* attr);
2155484543d1Sopenharmony_ci```
2156484543d1Sopenharmony_ci
2157484543d1Sopenharmony_ci* 描述:提交一个任务到队列中调度执行
2158484543d1Sopenharmony_ci
2159484543d1Sopenharmony_ci* 参数:
2160484543d1Sopenharmony_ci
2161484543d1Sopenharmony_ci  `queue`:串行队列的句柄
2162484543d1Sopenharmony_ci
2163484543d1Sopenharmony_ci  `f`:任务执行指针
2164484543d1Sopenharmony_ci
2165484543d1Sopenharmony_ci  `attr`:所创建的queue属性
2166484543d1Sopenharmony_ci
2167484543d1Sopenharmony_ci* 返回值:不涉及
2168484543d1Sopenharmony_ci
2169484543d1Sopenharmony_ci##### ffrt_queue_submit_h
2170484543d1Sopenharmony_ci
2171484543d1Sopenharmony_ci```{.cpp}
2172484543d1Sopenharmony_ciffrt_task_handle_t ffrt_queue_submit_h(
2173484543d1Sopenharmony_ci    ffrt_queue_t queue, ffrt_function_header_t* f, const ffrt_task_attr_t* attr);
2174484543d1Sopenharmony_ci```
2175484543d1Sopenharmony_ci
2176484543d1Sopenharmony_ci* 描述:提交一个任务到队列中调度执行,并返回任务句柄
2177484543d1Sopenharmony_ci
2178484543d1Sopenharmony_ci* 参数:
2179484543d1Sopenharmony_ci
2180484543d1Sopenharmony_ci  `queue`:串行队列的句柄
2181484543d1Sopenharmony_ci
2182484543d1Sopenharmony_ci  `f`:任务执行指针
2183484543d1Sopenharmony_ci
2184484543d1Sopenharmony_ci  `attr`:所创建的queue属性
2185484543d1Sopenharmony_ci
2186484543d1Sopenharmony_ci* 返回值:如果任务被提交,则返回一个非空的任务句柄;否则返回空指针
2187484543d1Sopenharmony_ci
2188484543d1Sopenharmony_ci##### ffrt_queue_wait
2189484543d1Sopenharmony_ci
2190484543d1Sopenharmony_ci```{.cpp}
2191484543d1Sopenharmony_civoid ffrt_queue_wait(ffrt_task_handle_t handle);
2192484543d1Sopenharmony_ci```
2193484543d1Sopenharmony_ci
2194484543d1Sopenharmony_ci* 描述:等待串行队列中一个任务执行完成
2195484543d1Sopenharmony_ci
2196484543d1Sopenharmony_ci* 参数:
2197484543d1Sopenharmony_ci
2198484543d1Sopenharmony_ci  `handle`:任务的句柄
2199484543d1Sopenharmony_ci
2200484543d1Sopenharmony_ci* 返回值:不涉及
2201484543d1Sopenharmony_ci
2202484543d1Sopenharmony_ci##### ffrt_queue_cancel
2203484543d1Sopenharmony_ci
2204484543d1Sopenharmony_ci```{.cpp}
2205484543d1Sopenharmony_ciint ffrt_queue_cancel(ffrt_task_handle_t handle);
2206484543d1Sopenharmony_ci```
2207484543d1Sopenharmony_ci
2208484543d1Sopenharmony_ci* 描述:取消队列中一个任务。必须使用submit_h后拿到的task_handle,否则会报异常;任务开始执行后则无法取消,仅能成功取消未开始执行的任务
2209484543d1Sopenharmony_ci
2210484543d1Sopenharmony_ci* 参数:
2211484543d1Sopenharmony_ci
2212484543d1Sopenharmony_ci  `handle`:任务的句柄
2213484543d1Sopenharmony_ci
2214484543d1Sopenharmony_ci* 返回值:若成功返回0,否则返回其他非0值
2215484543d1Sopenharmony_ci
2216484543d1Sopenharmony_ci#### 样例
2217484543d1Sopenharmony_ci
2218484543d1Sopenharmony_ci```{.cpp}
2219484543d1Sopenharmony_ci#include <stdio.h>
2220484543d1Sopenharmony_ci#include "ffrt.h"
2221484543d1Sopenharmony_ci
2222484543d1Sopenharmony_ciusing namespace ffrt;
2223484543d1Sopenharmony_ciusing namespace std;
2224484543d1Sopenharmony_ci
2225484543d1Sopenharmony_ciint main(int narg, char** argv)
2226484543d1Sopenharmony_ci{
2227484543d1Sopenharmony_ci    ffrt_queue_attr_t queue_attr;
2228484543d1Sopenharmony_ci    // 1、初始化队列属性,必需
2229484543d1Sopenharmony_ci    (void)ffrt_queue_attr_init(&queue_attr);
2230484543d1Sopenharmony_ci
2231484543d1Sopenharmony_ci    // 2、创建串行队列,并返回队列句柄queue_handle
2232484543d1Sopenharmony_ci    ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
2233484543d1Sopenharmony_ci
2234484543d1Sopenharmony_ci    int result = 0;
2235484543d1Sopenharmony_ci    std::function<void()>&& basicFunc = [&result]() { result += 1; };
2236484543d1Sopenharmony_ci
2237484543d1Sopenharmony_ci    // 3、提交串行任务
2238484543d1Sopenharmony_ci    ffrt_queue_submit(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), nullptr);
2239484543d1Sopenharmony_ci
2240484543d1Sopenharmony_ci    // 4、提交串行任务,并返回任务句柄
2241484543d1Sopenharmony_ci    ffrt_task_handle_t t1 = ffrt_queue_submit_h(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), nullptr);
2242484543d1Sopenharmony_ci    // 5、等待指定任务执行完成
2243484543d1Sopenharmony_ci    ffrt_queue_wait(t1);
2244484543d1Sopenharmony_ci
2245484543d1Sopenharmony_ci    ffrt_task_handle_t t2 = ffrt_queue_submit_h(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), nullptr);
2246484543d1Sopenharmony_ci    // 6、取消句柄为t2的任务
2247484543d1Sopenharmony_ci    int ret = ffrt_queue_cancel(t2);
2248484543d1Sopenharmony_ci
2249484543d1Sopenharmony_ci    // 7、销毁提交给串行队列任务的句柄t1和t2,必需
2250484543d1Sopenharmony_ci    ffrt_task_handle_destroy(t1);
2251484543d1Sopenharmony_ci    ffrt_task_handle_destroy(t2);
2252484543d1Sopenharmony_ci    // 8、销毁队列属性,必需
2253484543d1Sopenharmony_ci    ffrt_queue_attr_destroy(&queue_attr);
2254484543d1Sopenharmony_ci    // 9、销毁队列句柄,必需
2255484543d1Sopenharmony_ci    ffrt_queue_destroy(queue_handle);
2256484543d1Sopenharmony_ci}
2257484543d1Sopenharmony_ci```
2258484543d1Sopenharmony_ci
2259484543d1Sopenharmony_ci### ffrt_queue_attr_t
2260484543d1Sopenharmony_ci<hr/>
2261484543d1Sopenharmony_ci
2262484543d1Sopenharmony_ci#### 描述
2263484543d1Sopenharmony_ciFFRT串行队列 C API,提供设置与获取串行队列优先级、设置与获取串行队列任务执行超时时间、设置与获取串行队列超时回调函数等功能
2264484543d1Sopenharmony_ci
2265484543d1Sopenharmony_ci#### 声明
2266484543d1Sopenharmony_ci
2267484543d1Sopenharmony_ci```{.cpp}
2268484543d1Sopenharmony_citypedef struct {
2269484543d1Sopenharmony_ci    uint32_t storage[(ffrt_queue_attr_storage_size + sizeof(uint32_t) - 1) / sizeof(uint32_t)];
2270484543d1Sopenharmony_ci} ffrt_queue_attr_t;
2271484543d1Sopenharmony_ci
2272484543d1Sopenharmony_ciint ffrt_queue_attr_init(ffrt_queue_attr_t* attr);
2273484543d1Sopenharmony_civoid ffrt_queue_attr_destroy(ffrt_queue_attr_t* attr);
2274484543d1Sopenharmony_ci
2275484543d1Sopenharmony_civoid ffrt_queue_attr_set_qos(ffrt_queue_attr_t* attr, ffrt_qos_t qos);
2276484543d1Sopenharmony_ciffrt_qos_t ffrt_queue_attr_get_qos(const ffrt_queue_attr_t* attr);
2277484543d1Sopenharmony_ci
2278484543d1Sopenharmony_civoid ffrt_queue_attr_set_timeout(ffrt_queue_attr_t* attr, uint64_t timeout_us);
2279484543d1Sopenharmony_ciuint64_t ffrt_queue_attr_get_timeout(const ffrt_queue_attr_t* attr);
2280484543d1Sopenharmony_ci
2281484543d1Sopenharmony_civoid ffrt_queue_attr_set_callback(ffrt_queue_attr_t* attr, ffrt_function_header_t* f);
2282484543d1Sopenharmony_ciffrt_function_header_t* ffrt_queue_attr_get_callback(const ffrt_queue_attr_t* attr);
2283484543d1Sopenharmony_ci```
2284484543d1Sopenharmony_ci
2285484543d1Sopenharmony_ci#### 方法
2286484543d1Sopenharmony_ci
2287484543d1Sopenharmony_ci##### ffrt_queue_attr_init
2288484543d1Sopenharmony_ci```{.cpp}
2289484543d1Sopenharmony_ciint ffrt_queue_attr_init(ffrt_queue_attr_t* attr);
2290484543d1Sopenharmony_ci```
2291484543d1Sopenharmony_ci
2292484543d1Sopenharmony_ci* 描述:初始化串行队列的属性
2293484543d1Sopenharmony_ci
2294484543d1Sopenharmony_ci* 参数:
2295484543d1Sopenharmony_ci
2296484543d1Sopenharmony_ci  `attr`:已初始化的串行队列属性
2297484543d1Sopenharmony_ci
2298484543d1Sopenharmony_ci* 返回值:若成功返回0,否则返回-1
2299484543d1Sopenharmony_ci
2300484543d1Sopenharmony_ci##### ffrt_queue_attr_destroy
2301484543d1Sopenharmony_ci```{.cpp}
2302484543d1Sopenharmony_civoid ffrt_queue_attr_destroy(ffrt_queue_attr_t* attr);
2303484543d1Sopenharmony_ci```
2304484543d1Sopenharmony_ci
2305484543d1Sopenharmony_ci* 描述:销毁串行队列的属性
2306484543d1Sopenharmony_ci
2307484543d1Sopenharmony_ci  ffrt_queue_attr_t对象的置空和销毁由用户完成,对同一个ffrt_queue_t仅能调用一次 `ffrt_queue_attr_destroy` ,重复对同一个ffrt_queue_t调用 `ffrt_queue_attr_destroy` ,其行为是未定义的
2308484543d1Sopenharmony_ci
2309484543d1Sopenharmony_ci  在`ffrt_queue_attr_destroy`之后再对ffrt_queue_t进行访问,其行为是未定义的
2310484543d1Sopenharmony_ci
2311484543d1Sopenharmony_ci* 参数:
2312484543d1Sopenharmony_ci
2313484543d1Sopenharmony_ci  `attr`:所创建的串行队列属性
2314484543d1Sopenharmony_ci
2315484543d1Sopenharmony_ci* 返回值:不涉及
2316484543d1Sopenharmony_ci
2317484543d1Sopenharmony_ci##### ffrt_queue_attr_set_qos
2318484543d1Sopenharmony_ci```{.cpp}
2319484543d1Sopenharmony_civoid ffrt_queue_attr_set_qos(ffrt_queue_attr_t* attr, ffrt_qos_t qos);
2320484543d1Sopenharmony_ci```
2321484543d1Sopenharmony_ci
2322484543d1Sopenharmony_ci* 描述:设置串行队列qos属性,默认为default等级
2323484543d1Sopenharmony_ci
2324484543d1Sopenharmony_ci* 参数:
2325484543d1Sopenharmony_ci
2326484543d1Sopenharmony_ci  `attr`:所创建的串行队列属性
2327484543d1Sopenharmony_ci
2328484543d1Sopenharmony_ci  `qos`:串行队列优先级
2329484543d1Sopenharmony_ci
2330484543d1Sopenharmony_ci* 返回值:不涉及
2331484543d1Sopenharmony_ci
2332484543d1Sopenharmony_ci##### ffrt_queue_attr_get_qos
2333484543d1Sopenharmony_ci```{.cpp}
2334484543d1Sopenharmony_ciffrt_qos_t ffrt_queue_attr_get_qos(const ffrt_queue_attr_t* attr);
2335484543d1Sopenharmony_ci```
2336484543d1Sopenharmony_ci
2337484543d1Sopenharmony_ci* 描述:获取串行队列qos属性
2338484543d1Sopenharmony_ci
2339484543d1Sopenharmony_ci* 参数:
2340484543d1Sopenharmony_ci
2341484543d1Sopenharmony_ci  `attr`:所创建的串行队列属性
2342484543d1Sopenharmony_ci
2343484543d1Sopenharmony_ci* 返回值:所设置的串行队列的qos等级,默认为default等级
2344484543d1Sopenharmony_ci
2345484543d1Sopenharmony_ci##### ffrt_queue_attr_set_timeout
2346484543d1Sopenharmony_ci```{.cpp}
2347484543d1Sopenharmony_civoid ffrt_queue_attr_set_timeout(ffrt_queue_attr_t* attr, uint64_t timeout_us);
2348484543d1Sopenharmony_ci```
2349484543d1Sopenharmony_ci
2350484543d1Sopenharmony_ci* 描述:设置串行队列任务执行超时时间
2351484543d1Sopenharmony_ci
2352484543d1Sopenharmony_ci* 参数:
2353484543d1Sopenharmony_ci
2354484543d1Sopenharmony_ci  `attr`:所创建的串行队列属性
2355484543d1Sopenharmony_ci
2356484543d1Sopenharmony_ci  `timeout_us`:串行队列任务执行超时时间,单位为us
2357484543d1Sopenharmony_ci
2358484543d1Sopenharmony_ci* 返回值:不涉及
2359484543d1Sopenharmony_ci
2360484543d1Sopenharmony_ci##### ffrt_queue_attr_get_timeout
2361484543d1Sopenharmony_ci```{.cpp}
2362484543d1Sopenharmony_ciuint64_t ffrt_queue_attr_get_timeout(const ffrt_queue_attr_t* attr);
2363484543d1Sopenharmony_ci```
2364484543d1Sopenharmony_ci
2365484543d1Sopenharmony_ci* 描述:获取所设置的串行队列任务执行超时时间
2366484543d1Sopenharmony_ci
2367484543d1Sopenharmony_ci* 参数:
2368484543d1Sopenharmony_ci
2369484543d1Sopenharmony_ci  `attr`:所创建的串行队列属性
2370484543d1Sopenharmony_ci
2371484543d1Sopenharmony_ci* 返回值:串行队列任务执行超时时间,单位为us
2372484543d1Sopenharmony_ci
2373484543d1Sopenharmony_ci##### ffrt_queue_attr_set_callback
2374484543d1Sopenharmony_ci```{.cpp}
2375484543d1Sopenharmony_civoid ffrt_queue_attr_set_callback(ffrt_queue_attr_t* attr, ffrt_function_header_t* f);
2376484543d1Sopenharmony_ci```
2377484543d1Sopenharmony_ci
2378484543d1Sopenharmony_ci* 描述:设置串行队列超时回调函数
2379484543d1Sopenharmony_ci
2380484543d1Sopenharmony_ci* 参数:
2381484543d1Sopenharmony_ci
2382484543d1Sopenharmony_ci  `attr`:所创建的串行队列属性
2383484543d1Sopenharmony_ci
2384484543d1Sopenharmony_ci  `f`:串行队列超时回调函数
2385484543d1Sopenharmony_ci
2386484543d1Sopenharmony_ci* 返回值:不涉及
2387484543d1Sopenharmony_ci
2388484543d1Sopenharmony_ci##### ffrt_queue_attr_get_callback
2389484543d1Sopenharmony_ci```{.cpp}
2390484543d1Sopenharmony_ciffrt_function_header_t* ffrt_queue_attr_get_callback(const ffrt_queue_attr_t* attr);
2391484543d1Sopenharmony_ci```
2392484543d1Sopenharmony_ci
2393484543d1Sopenharmony_ci* 描述:获取串行队列超时回调函数
2394484543d1Sopenharmony_ci
2395484543d1Sopenharmony_ci* 参数:
2396484543d1Sopenharmony_ci
2397484543d1Sopenharmony_ci  `attr`:所创建的串行队列属性
2398484543d1Sopenharmony_ci
2399484543d1Sopenharmony_ci* 返回值:串行队列任务超时回调函数
2400484543d1Sopenharmony_ci
2401484543d1Sopenharmony_ci#### 样例
2402484543d1Sopenharmony_ci```{.cpp}
2403484543d1Sopenharmony_ci#include <stdio.h>
2404484543d1Sopenharmony_ci#include "ffrt.h"
2405484543d1Sopenharmony_ci
2406484543d1Sopenharmony_ciusing namespace ffrt;
2407484543d1Sopenharmony_ciusing namespace std;
2408484543d1Sopenharmony_ci
2409484543d1Sopenharmony_ciint main(int narg, char** argv)
2410484543d1Sopenharmony_ci{
2411484543d1Sopenharmony_ci    ffrt_queue_attr_t queue_attr;
2412484543d1Sopenharmony_ci    // 1、初始化串行队列属性,必需
2413484543d1Sopenharmony_ci    int result = ffrt_queue_attr_init(&queue_attr);
2414484543d1Sopenharmony_ci
2415484543d1Sopenharmony_ci    int x = 0;
2416484543d1Sopenharmony_ci    std::function<void()>&& basicFunc = [&x]() { x += 1; };
2417484543d1Sopenharmony_ci
2418484543d1Sopenharmony_ci    // 2、可设置队列优先级,默认为default等级
2419484543d1Sopenharmony_ci    ffrt_queue_attr_set_qos(&queue_attr, static_cast<int>(ffrt_qos_utility));
2420484543d1Sopenharmony_ci    int qos = ffrt_queue_attr_get_qos(&queue_attr);
2421484543d1Sopenharmony_ci
2422484543d1Sopenharmony_ci    // 3、可通过设置timeout打开队列任务超时监测,默认不设置(关闭)
2423484543d1Sopenharmony_ci    ffrt_queue_attr_set_timeout(&queue_attr, 10000);
2424484543d1Sopenharmony_ci    uint64_t time = ffrt_queue_attr_get_timeout(&queue_attr);
2425484543d1Sopenharmony_ci
2426484543d1Sopenharmony_ci    // 4、超时会打印Error日志并执行用户设置的callback(可选)
2427484543d1Sopenharmony_ci    ffrt_queue_attr_set_callback(&queue_attr, ffrt::create_function_wrapper(basicFunc, ffrt_function_kind_queue));
2428484543d1Sopenharmony_ci    ffrt_function_header_t* func = ffrt_queue_attr_get_callback(&queue_attr);
2429484543d1Sopenharmony_ci
2430484543d1Sopenharmony_ci    // 5、销毁串行队列属性,必需
2431484543d1Sopenharmony_ci    ffrt_queue_attr_destroy(&queue_attr);
2432484543d1Sopenharmony_ci}
2433484543d1Sopenharmony_ci```
2434484543d1Sopenharmony_ci
2435484543d1Sopenharmony_ci### ffrt_loop_t
2436484543d1Sopenharmony_ci<hr/>
2437484543d1Sopenharmony_ci
2438484543d1Sopenharmony_ci* 为满足美团生态对接的要求,扩展了FFRT基本功能。新增了支持定时器、线程间通信、N并发队列、并提供Loop机制(在用户创建的线程内循环执行用户提交的任务)等功能
2439484543d1Sopenharmony_ci
2440484543d1Sopenharmony_ci#### 声明
2441484543d1Sopenharmony_ci
2442484543d1Sopenharmony_ci```{.c}
2443484543d1Sopenharmony_citypedef void* ffrt_loop_t
2444484543d1Sopenharmony_ci
2445484543d1Sopenharmony_ciffrt_loop_t ffrt_loop_create(ffrt_queue_t queue);
2446484543d1Sopenharmony_ciint ffrt_loop_destroy(ffrt_loop_t loop);
2447484543d1Sopenharmony_ciint ffrt_loop_run(ffrt_loop_t loop);
2448484543d1Sopenharmony_civoid ffrt_loop_stop(ffrt_loop_t loop);
2449484543d1Sopenharmony_ciint ffrt_loop_epoll_ctl(ffrt_loop_t loop, int op, int fd, uint32_t events, void *data, ffrt_poller_cb cb);
2450484543d1Sopenharmony_ciffrt_timer_t ffrt_loop_timer_start(
2451484543d1Sopenharmony_ci    ffrt_loop_t loop, uint64_t timeout, void* data, ffrt_timer_cb cb, bool repeat);
2452484543d1Sopenharmony_ciint ffrt_loop_timer_stop(ffrt_loop_t loop, ffrt_timer_t handle);
2453484543d1Sopenharmony_ci```
2454484543d1Sopenharmony_ci
2455484543d1Sopenharmony_ci#### 参数
2456484543d1Sopenharmony_ci
2457484543d1Sopenharmony_ci`queue`: 表示一个队列句柄
2458484543d1Sopenharmony_ci
2459484543d1Sopenharmony_ci`loop`: 表示一个loop句柄
2460484543d1Sopenharmony_ci
2461484543d1Sopenharmony_ci`op`: 表示目标文件描述符的操作
2462484543d1Sopenharmony_ci
2463484543d1Sopenharmony_ci`fd`: 表示执行操作的目标文件描述符
2464484543d1Sopenharmony_ci
2465484543d1Sopenharmony_ci`events`: 表示跟目标文件描述符相关联的事件类型
2466484543d1Sopenharmony_ci
2467484543d1Sopenharmony_ci`data`: 表示回调函数中被用户使用的数据
2468484543d1Sopenharmony_ci
2469484543d1Sopenharmony_ci`cb`: 表示一个回调函数,当目标文件描述符被获取时执行
2470484543d1Sopenharmony_ci
2471484543d1Sopenharmony_ci`timeout`: 表示函数调用中阻塞时间的上限,单位为毫秒
2472484543d1Sopenharmony_ci
2473484543d1Sopenharmony_ci`repeat`: 表示是否重复这个定时器
2474484543d1Sopenharmony_ci
2475484543d1Sopenharmony_ci#### 返回值
2476484543d1Sopenharmony_ci* ffrt_loop_create接口:当loop成功创建后返回一个非空的loop句柄,否则返回一个空指针
2477484543d1Sopenharmony_ci* ffrt_loop_destroy接口:当loop成功被销毁返回0,否则返回-1
2478484543d1Sopenharmony_ci* ffrt_loop_run接口:当loop成功运行返回0,否则返回-1
2479484543d1Sopenharmony_ci* ffrt_loop_epoll_ctl接口:如果成功在loop里添加/删除fd,返回0,否则返回-1
2480484543d1Sopenharmony_ci* ffrt_loop_timer_start接口:在loop里开启一个定时器,返回该定时器的句柄
2481484543d1Sopenharmony_ci* ffrt_loop_timer_stop接口:在loop里停止一个目标定时器,停止成功:返回0,如果停止失败:返回-1
2482484543d1Sopenharmony_ci
2483484543d1Sopenharmony_ci#### 描述
2484484543d1Sopenharmony_ci* FFRT提供loop的编程机制,loop支持任务提交,提交的任务直接在用户线程中执行
2485484543d1Sopenharmony_ci* FFRT loop基于FFRT queue构建任务队列,基于FFRT Poller实现事件监听,loop内部自动遍历任务队列执行任务,当没有任务时进入Poller的epoll_wait监听事件,线程进入休眠状态
2486484543d1Sopenharmony_ci* 支持用户通过接口创建loop,返回给用户loop句柄,创建loop时需要传入一个已创建的FFRT queue作为该loop的任务队列
2487484543d1Sopenharmony_ci* loop创建后支持向queue中提交任务,并支持在loop run的过程中向queue中提交任务
2488484543d1Sopenharmony_ci* 提供ffrt_loop_create接口创建loop,用户传入queue,创建时将loop和queue相互绑定
2489484543d1Sopenharmony_ci* **注意:这里对传入的queue要求从未提交过任务,即:不支持queue的任务既在worker上执行又在用户线程上执行**
2490484543d1Sopenharmony_ci* **注意:传入的queue类型仅支持N并发队列,不支持其它类型的队列**
2491484543d1Sopenharmony_ci* 提供ffrt_loop_run接口,运行loop,loop启动后遍历queue中的任务执行
2492484543d1Sopenharmony_ci* 提供ffrt_loop_stop接口,停止运行loop,停止后loop不能再运行
2493484543d1Sopenharmony_ci* 提供ffrt_loop_destroy接口,将loop销毁,同时解除queue和loop间的绑定关系,意味着loop销毁后不能再向该queue提交任务
2494484543d1Sopenharmony_ci* 提供ffrt_loop_epoll_ctl接口,使用户可以监听/删除一个fd,当fd被调用时,执行用户的回调函数
2495484543d1Sopenharmony_ci* 提供ffrt_loop_timer_start接口,在loop中开始一个定时器
2496484543d1Sopenharmony_ci* 提供ffrt_loop_timer_stop接口,在loop中停止一个目标定时器
2497484543d1Sopenharmony_ci
2498484543d1Sopenharmony_ci#### 样例
2499484543d1Sopenharmony_ci```{.c}
2500484543d1Sopenharmony_ci#include <stdio.h>
2501484543d1Sopenharmony_ci#include "ffrt.h"
2502484543d1Sopenharmony_ci
2503484543d1Sopenharmony_ciusing namespace ffrt;
2504484543d1Sopenharmony_ciusing namespace std;
2505484543d1Sopenharmony_ci
2506484543d1Sopenharmony_ciint main(int narg, char** argv)
2507484543d1Sopenharmony_ci{
2508484543d1Sopenharmony_ci    // step1: 创建queue
2509484543d1Sopenharmony_ci    ffrt_queue_attr_t queue_attr;
2510484543d1Sopenharmony_ci    (void)ffrt_queue_attr_init(&queue_attr);
2511484543d1Sopenharmony_ci    ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_concurrent, "test_queue", &queue_attr);
2512484543d1Sopenharmony_ci
2513484543d1Sopenharmony_ci    // step2: 创建loop
2514484543d1Sopenharmony_ci    auto loop = ffrt_loop_create(queue_handle);
2515484543d1Sopenharmony_ci
2516484543d1Sopenharmony_ci    // step3: 此时可以向loop提交任务
2517484543d1Sopenharmony_ci    int result1 = 0;
2518484543d1Sopenharmony_ci    std::function<void()>&& basicFunc1 = [&result1]() { result1 += 10; };
2519484543d1Sopenharmony_ci    ffrt_task_handle_t task1 = ffrt_queue_submit_h(queue_handle,
2520484543d1Sopenharmony_ci        create_function_wrapper(basicFunc1, ffrt_function_kind_queue), nullptr);
2521484543d1Sopenharmony_ci    
2522484543d1Sopenharmony_ci    // step4: 在进程中执行loop run
2523484543d1Sopenharmony_ci    pthread_t thread;
2524484543d1Sopenharmony_ci    pthread_create(&thread, 0, ThreadFunc, loop);
2525484543d1Sopenharmony_ci
2526484543d1Sopenharmony_ci    static int x = 0;
2527484543d1Sopenharmony_ci    int* xf = &x;
2528484543d1Sopenharmony_ci    void* data = xf;
2529484543d1Sopenharmony_ci    uint64_t timeout1 = 20;
2530484543d1Sopenharmony_ci    uint64_t timeout2 = 10;
2531484543d1Sopenharmony_ci    uint64_t expected = 0xabacadae;
2532484543d1Sopenharmony_ci    int testFd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
2533484543d1Sopenharmony_ci
2534484543d1Sopenharmony_ci    struct TestData testData {.fd = testFd, .expected = expected};
2535484543d1Sopenharmony_ci    EXPECT_EQ(0, ffrt_loop_timer_start(loop, timeout1, data, cb, false));
2536484543d1Sopenharmony_ci    EXPECT_EQ(1, ffrt_loop_timer_start(loop, timeout2, data, cb, false));
2537484543d1Sopenharmony_ci
2538484543d1Sopenharmony_ci    ffrt_loop_epoll_ctl(loop, EPOLL_CTL_ADD, testFd, EPOLLIN, (void*)(&testData), testCallBack);
2539484543d1Sopenharmony_ci    ssize_t n = write(testFd, &expected, sizeof(uint64_t));
2540484543d1Sopenharmony_ci    EXPECT_EQ(n, sizeof(uint64_t));
2541484543d1Sopenharmony_ci    usleep(25000);
2542484543d1Sopenharmony_ci    ffrt_loop_epoll_ctl(loop, EPOLL_CTL_DEL, testFd, 0, nullptr, nullptr);
2543484543d1Sopenharmony_ci
2544484543d1Sopenharmony_ci    EXPECT_EQ(2, x);
2545484543d1Sopenharmony_ci
2546484543d1Sopenharmony_ci    // step5: 继续向loop上提交任务
2547484543d1Sopenharmony_ci    int result2 = 0;
2548484543d1Sopenharmony_ci    std::function<void()>&& basicFunc2 = [&result2]() { result2 += 20; };
2549484543d1Sopenharmony_ci    ffrt_task_handle_t task2 = ffrt_queue_submit_h(queue_handle,
2550484543d1Sopenharmony_ci        create_function_wrapper(basicFunc2, ffrt_function_kind_queue), nullptr);
2551484543d1Sopenharmony_ci    
2552484543d1Sopenharmony_ci    ffrt_queue_wait(task1);
2553484543d1Sopenharmony_ci    ffrt_queue_wait(task2);
2554484543d1Sopenharmony_ci    EXPECT_EQ(result1, 10);
2555484543d1Sopenharmony_ci    EXPECT_EQ(result2, 20);
2556484543d1Sopenharmony_ci
2557484543d1Sopenharmony_ci    // step6: 停止loop
2558484543d1Sopenharmony_ci    ffrt_loop_stop(loop);
2559484543d1Sopenharmony_ci    pthread_join(thread, nullptr);
2560484543d1Sopenharmony_ci
2561484543d1Sopenharmony_ci    // step7: loop销毁
2562484543d1Sopenharmony_ci    ffrt_loop_destroy(loop);
2563484543d1Sopenharmony_ci
2564484543d1Sopenharmony_ci    // step8: 队列销毁
2565484543d1Sopenharmony_ci    ffrt_queue_attr_destroy(&queue_attr);
2566484543d1Sopenharmony_ci    ffrt_queue_destroy(queue_handle);
2567484543d1Sopenharmony_ci}
2568484543d1Sopenharmony_ci
2569484543d1Sopenharmony_ci```
2570484543d1Sopenharmony_ci
2571484543d1Sopenharmony_ci### ffrt_timer_t
2572484543d1Sopenharmony_ci<hr/>
2573484543d1Sopenharmony_ci
2574484543d1Sopenharmony_ci* FFRT timer基于epoll实现定时功能,epoll是一种I/O事件监听、通知机制。在定期执行PollOnce时会根据所设的timeout时间执行其中的epoll_wait阻塞等待注册的事件发生。epoll_wait的参数timeout是函数调用中阻塞时间的上限,单位是ms,若timeout > 0,则在期间有检测到对象变为ready状态或者捕获到信号然后返回,否则直到超时。Timeout = -1则会一直在阻塞。
2575484543d1Sopenharmony_ci
2576484543d1Sopenharmony_ci#### 声明
2577484543d1Sopenharmony_ci```{.c}
2578484543d1Sopenharmony_ciffrt_timer_t ffrt_timer_start(ffrt_qos_t qos, uint64_t timeout, void* data, ffrt_timer_cb cb, bool repeat);
2579484543d1Sopenharmony_ciint ffrt_timer_stop(ffrt_qos_t qos, ffrt_timer_t handle);
2580484543d1Sopenharmony_ci```
2581484543d1Sopenharmony_ci
2582484543d1Sopenharmony_ci#### 参数
2583484543d1Sopenharmony_ci
2584484543d1Sopenharmony_ci`qos`
2585484543d1Sopenharmony_ci
2586484543d1Sopenharmony_ci* 表示运行定时器work的优先级
2587484543d1Sopenharmony_ci
2588484543d1Sopenharmony_ci`timeout`
2589484543d1Sopenharmony_ci
2590484543d1Sopenharmony_ci* 表示函数调用中阻塞时长的上限,单位为毫秒
2591484543d1Sopenharmony_ci
2592484543d1Sopenharmony_ci`data`
2593484543d1Sopenharmony_ci
2594484543d1Sopenharmony_ci* 表示回调函数中使用的用户数据
2595484543d1Sopenharmony_ci
2596484543d1Sopenharmony_ci`cb`
2597484543d1Sopenharmony_ci
2598484543d1Sopenharmony_ci* 表示在超时之后被执行的用户回调函数
2599484543d1Sopenharmony_ci
2600484543d1Sopenharmony_ci`repeat`
2601484543d1Sopenharmony_ci
2602484543d1Sopenharmony_ci* 表示是否重复这个定时器
2603484543d1Sopenharmony_ci
2604484543d1Sopenharmony_ci`handle`
2605484543d1Sopenharmony_ci
2606484543d1Sopenharmony_ci* 表示目标定时器的句柄
2607484543d1Sopenharmony_ci
2608484543d1Sopenharmony_ci
2609484543d1Sopenharmony_ci#### 返回值
2610484543d1Sopenharmony_ci
2611484543d1Sopenharmony_ci* ffrt_timer_start接口:返回一个定时器句柄
2612484543d1Sopenharmony_ci* ffrt_timer_stop接口:成功停止一个目标定时器,返回0;否则返回-1
2613484543d1Sopenharmony_ci
2614484543d1Sopenharmony_ci
2615484543d1Sopenharmony_ci#### 描述
2616484543d1Sopenharmony_ci
2617484543d1Sopenharmony_ci* 提供接口ffrt_timer_start设定超时的绝对时间,用于设定epoll_wait阻塞时间,若调用PollOnce时已超时,则执行入参所设的回调函数cb
2618484543d1Sopenharmony_ci* 提供接口ffrt_timer_stop用于根据任务handle取消定时任务
2619484543d1Sopenharmony_ci* 当timer超时回调被执行时,ffrt会记录并保存handle的执行状态(执行中、执行完成),该记录会在ffrt_timer_stop被调用后删除。因此建议ffrt_timer_start和ffrt_timer_stop接口成对使用,否则可能造成记录数据的无限膨胀
2620484543d1Sopenharmony_ci
2621484543d1Sopenharmony_ci
2622484543d1Sopenharmony_ci#### 样例
2623484543d1Sopenharmony_ci
2624484543d1Sopenharmony_ci```{.c}
2625484543d1Sopenharmony_ci#include <stdio.h>
2626484543d1Sopenharmony_ci#include "ffrt.h"
2627484543d1Sopenharmony_ci
2628484543d1Sopenharmony_ciusing namespace ffrt
2629484543d1Sopenharmony_ciusing namespace std
2630484543d1Sopenharmony_ci
2631484543d1Sopenharmony_cistruct TestData {
2632484543d1Sopenharmony_ci    int fd;
2633484543d1Sopenharmony_ci    uint64_t expected;
2634484543d1Sopenharmony_ci};
2635484543d1Sopenharmony_ci
2636484543d1Sopenharmony_ciint main(int narg, char** argv)
2637484543d1Sopenharmony_ci{
2638484543d1Sopenharmony_ci    static int x = 0;
2639484543d1Sopenharmony_ci    int* xf = &x;
2640484543d1Sopenharmony_ci    void* data = xf;
2641484543d1Sopenharmony_ci    uint64_t timeout = 20;
2642484543d1Sopenharmony_ci    uint64_t expected = 0xabacadae;
2643484543d1Sopenharmony_ci    int testFd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
2644484543d1Sopenharmony_ci
2645484543d1Sopenharmony_ci    struct TestData testData {.fd = testFd, .expected = expected};
2646484543d1Sopenharmony_ci    ffrt::submit([=]() {
2647484543d1Sopenharmony_ci        ffrt_qos_t taskQos = ffrt_this_task_get_qos();
2648484543d1Sopenharmony_ci        int handle = ffrt_timer_start(taskQos, timeout, data, cb, false);
2649484543d1Sopenharmony_ci
2650484543d1Sopenharmony_ci        ffrt_epoll_ctl(taskQos, EPOLL_CTL_ADD, testFd, EPOLLIN, (void*)(&testData), testCallBack);
2651484543d1Sopenharmony_ci        ffrt_usleep(19000);
2652484543d1Sopenharmony_ci        ffrt_timer_stop(taskQos, handle);
2653484543d1Sopenharmony_ci        ssize_t n = write(testFd, &expected, sizeof(uint64_t));
2654484543d1Sopenharmony_ci        stall_us(200);
2655484543d1Sopenharmony_ci
2656484543d1Sopenharmony_ci        ffrt_epoll_ctl(taskQos, EPOLL_CTL_DEL, testFd, 0, nullptr, nullptr);
2657484543d1Sopenharmony_ci    }, {}, {});
2658484543d1Sopenharmony_ci    ffrt::wait();
2659484543d1Sopenharmony_ci}
2660484543d1Sopenharmony_ci
2661484543d1Sopenharmony_ci```
2662484543d1Sopenharmony_ci
2663484543d1Sopenharmony_ci
2664484543d1Sopenharmony_ci
2665484543d1Sopenharmony_ci
2666484543d1Sopenharmony_ci## 同步原语
2667484543d1Sopenharmony_ci
2668484543d1Sopenharmony_ci### ffrt_mutex_t
2669484543d1Sopenharmony_ci<hr/>
2670484543d1Sopenharmony_ci* FFRT提供的类似pthread mutex 的性能实现
2671484543d1Sopenharmony_ci
2672484543d1Sopenharmony_ci#### 声明
2673484543d1Sopenharmony_ci
2674484543d1Sopenharmony_ci```{.cpp}
2675484543d1Sopenharmony_citypedef enum {
2676484543d1Sopenharmony_ci    ffrt_error = -1,
2677484543d1Sopenharmony_ci    ffrt_success = 0,
2678484543d1Sopenharmony_ci    ffrt_error_nomem = ENOMEM,
2679484543d1Sopenharmony_ci    ffrt_error_timedout = ETIMEDOUT,
2680484543d1Sopenharmony_ci    ffrt_error_busy = EBUSY,
2681484543d1Sopenharmony_ci    ffrt_error_inval = EINVAL
2682484543d1Sopenharmony_ci} ffrt_error_t;
2683484543d1Sopenharmony_ci
2684484543d1Sopenharmony_cistruct ffrt_mutex_t;
2685484543d1Sopenharmony_ci
2686484543d1Sopenharmony_cistruct ffrt_mutexattr_t;
2687484543d1Sopenharmony_ci
2688484543d1Sopenharmony_citypedef enum {
2689484543d1Sopenharmony_ci    ffrt_mutex_normal = 0,
2690484543d1Sopenharmony_ci    ffrt_mutex_recursive = 2,
2691484543d1Sopenharmony_ci    ffrt_mutex_default = ffrt_mutex_normal
2692484543d1Sopenharmony_ci} ffrt_mutex_type;
2693484543d1Sopenharmony_ci
2694484543d1Sopenharmony_ciint ffrt_mutexattr_init(ffrt_mutexattr_t* attr);
2695484543d1Sopenharmony_ciint ffrt_mutexattr_settype(ffrt_mutexattr_t* attr, int type);
2696484543d1Sopenharmony_ciint ffrt_mutexattr_gettype(ffrt_mutexattr_t* attr, int* type);
2697484543d1Sopenharmony_ciint ffrt_mutexattr_destroy(ffrt_mutexattr_t* attr);
2698484543d1Sopenharmony_ciint ffrt_mutex_init(ffrt_mutex_t* mutex, const ffrt_mutexattr_t* attr);
2699484543d1Sopenharmony_ciint ffrt_mutex_lock(ffrt_mutex_t* mutex);
2700484543d1Sopenharmony_ciint ffrt_mutex_unlock(ffrt_mutex_t* mutex);
2701484543d1Sopenharmony_ciint ffrt_mutex_trylock(ffrt_mutex_t* mutex);
2702484543d1Sopenharmony_ciint ffrt_mutex_destroy(ffrt_mutex_t* mutex);
2703484543d1Sopenharmony_ci```
2704484543d1Sopenharmony_ci
2705484543d1Sopenharmony_ci#### 参数
2706484543d1Sopenharmony_ci`type`
2707484543d1Sopenharmony_ci
2708484543d1Sopenharmony_ci* FFRT锁类型,当前仅支持互斥锁ffrt_mutex_normal和递归锁ffrt_mutex_recursive
2709484543d1Sopenharmony_ci
2710484543d1Sopenharmony_ci`attr`
2711484543d1Sopenharmony_ci
2712484543d1Sopenharmony_ci* FFRT锁属性,attr如果为空指针代表互斥锁mutex
2713484543d1Sopenharmony_ci
2714484543d1Sopenharmony_ci`mutex`
2715484543d1Sopenharmony_ci
2716484543d1Sopenharmony_ci* 指向所操作的锁指针
2717484543d1Sopenharmony_ci
2718484543d1Sopenharmony_ci#### 返回值
2719484543d1Sopenharmony_ci
2720484543d1Sopenharmony_ci* 若成功则为 ffrt_success ,否则发生错误
2721484543d1Sopenharmony_ci
2722484543d1Sopenharmony_ci#### 描述
2723484543d1Sopenharmony_ci* 该接口支持在FFRT task 内部调用,也支持在FFRT task 外部调用
2724484543d1Sopenharmony_ci* 该功能能够避免pthread传统的pthread_mutex_t 在抢不到锁时陷入内核的问题,在使用得当的条件下将会有更好的性能
2725484543d1Sopenharmony_ci* **注意:目前暂不支持定时功能**
2726484543d1Sopenharmony_ci* **注意:C API中的ffrt_mutexattr_t需要用户调用`ffrt_mutexattr_init`和`ffrt_mutexattr_destroy`显示创建和销毁,而C++ API无需该操作**
2727484543d1Sopenharmony_ci* **注意:C API中的ffrt_mutex_t需要用户调用`ffrt_mutex_init`和`ffrt_mutex_destroy`显式创建和销毁,而C++ API无需该操作**
2728484543d1Sopenharmony_ci* **注意:C API中的ffrt_mutex_t对象的置空和销毁由用户完成,对同一个ffrt_mutex_t仅能调用一次`ffrt_mutex_destroy`,重复对同一个ffrt_mutex_t调用`ffrt_mutex_destroy`,其行为是未定义的**
2729484543d1Sopenharmony_ci* **注意:C API中的同一个ffrt_mutexattr_t只能调用一次`ffrt_mutexattr_init`和`ffrt_mutexattr_destroy`,重复调用其行为是未定义的**
2730484543d1Sopenharmony_ci* **注意:用户需要在调用`ffrt_mutex_init`之后和调用`ffrt_mutex_destroy`之前显示调用`ffrt_mutexattr_destroy`**
2731484543d1Sopenharmony_ci* **注意:在`ffrt_mutex_destroy`之后再对ffrt_mutex_t进行访问,其行为是未定义的**
2732484543d1Sopenharmony_ci
2733484543d1Sopenharmony_ci#### 样例
2734484543d1Sopenharmony_ci
2735484543d1Sopenharmony_ci```{.c}
2736484543d1Sopenharmony_ci#include <stdio.h>
2737484543d1Sopenharmony_ci#include "ffrt.h"
2738484543d1Sopenharmony_ci
2739484543d1Sopenharmony_citypedef struct {
2740484543d1Sopenharmony_ci    int* sum;
2741484543d1Sopenharmony_ci    ffrt_mutex_t* mtx;
2742484543d1Sopenharmony_ci} tuple;
2743484543d1Sopenharmony_ci
2744484543d1Sopenharmony_civoid func(void* arg)
2745484543d1Sopenharmony_ci{
2746484543d1Sopenharmony_ci    tuple* t = (tuple*)arg;
2747484543d1Sopenharmony_ci    
2748484543d1Sopenharmony_ci    int ret = ffrt_mutex_lock(t->mtx);
2749484543d1Sopenharmony_ci    if (ret != ffrt_success) {
2750484543d1Sopenharmony_ci        printf("error\n");
2751484543d1Sopenharmony_ci    }
2752484543d1Sopenharmony_ci    (*t->sum)++;
2753484543d1Sopenharmony_ci    ret = ffrt_mutex_unlock(t->mtx);
2754484543d1Sopenharmony_ci    if (ret != ffrt_success) {
2755484543d1Sopenharmony_ci        printf("error\n");
2756484543d1Sopenharmony_ci    }
2757484543d1Sopenharmony_ci}
2758484543d1Sopenharmony_ci
2759484543d1Sopenharmony_citypedef struct {
2760484543d1Sopenharmony_ci    ffrt_function_header_t header;
2761484543d1Sopenharmony_ci    ffrt_function_t func;
2762484543d1Sopenharmony_ci    ffrt_function_t after_func;
2763484543d1Sopenharmony_ci    void* arg;
2764484543d1Sopenharmony_ci} c_function;
2765484543d1Sopenharmony_ci
2766484543d1Sopenharmony_cistatic void ffrt_exec_function_wrapper(void* t)
2767484543d1Sopenharmony_ci{
2768484543d1Sopenharmony_ci    c_function* f = (c_function*)t;
2769484543d1Sopenharmony_ci    if (f->func) {
2770484543d1Sopenharmony_ci        f->func(f->arg);
2771484543d1Sopenharmony_ci    }
2772484543d1Sopenharmony_ci}
2773484543d1Sopenharmony_ci
2774484543d1Sopenharmony_cistatic void ffrt_destroy_function_wrapper(void* t)
2775484543d1Sopenharmony_ci{
2776484543d1Sopenharmony_ci    c_function* f = (c_function*)t;
2777484543d1Sopenharmony_ci    if (f->after_func) {
2778484543d1Sopenharmony_ci        f->after_func(f->arg);
2779484543d1Sopenharmony_ci    }
2780484543d1Sopenharmony_ci}
2781484543d1Sopenharmony_ci
2782484543d1Sopenharmony_ci#define FFRT_STATIC_ASSERT(cond, msg) int x(int static_assertion_##msg[(cond) ? 1 : -1])
2783484543d1Sopenharmony_cistatic inline ffrt_function_header_t* ffrt_create_function_wrapper(const ffrt_function_t func,
2784484543d1Sopenharmony_ci    const ffrt_function_t after_func, void* arg)
2785484543d1Sopenharmony_ci{
2786484543d1Sopenharmony_ci    FFRT_STATIC_ASSERT(sizeof(c_function) <= ffrt_auto_managed_function_storage_size,
2787484543d1Sopenharmony_ci        size_of_function_must_be_less_than_ffrt_auto_managed_function_storage_size);
2788484543d1Sopenharmony_ci    c_function* f = (c_function*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
2789484543d1Sopenharmony_ci    f->header.exec = ffrt_exec_function_wrapper;
2790484543d1Sopenharmony_ci    f->header.destroy = ffrt_destroy_function_wrapper;
2791484543d1Sopenharmony_ci    f->func = func;
2792484543d1Sopenharmony_ci    f->after_func = after_func;
2793484543d1Sopenharmony_ci    f->arg = arg;
2794484543d1Sopenharmony_ci    return (ffrt_function_header_t*)f;
2795484543d1Sopenharmony_ci}
2796484543d1Sopenharmony_ci
2797484543d1Sopenharmony_cistatic inline void ffrt_submit_c(ffrt_function_t func, const ffrt_function_t after_func,
2798484543d1Sopenharmony_ci    void* arg, const ffrt_deps_t* in_deps, const ffrt_deps_t* out_deps, const ffrt_task_attr_t* attr)
2799484543d1Sopenharmony_ci{
2800484543d1Sopenharmony_ci    ffrt_submit_base(ffrt_create_function_wrapper(func, after_func, arg), in_deps, out_deps, attr);
2801484543d1Sopenharmony_ci}
2802484543d1Sopenharmony_ci
2803484543d1Sopenharmony_civoid ffrt_mutex_task(void *)
2804484543d1Sopenharmony_ci{
2805484543d1Sopenharmony_ci    int sum = 0;
2806484543d1Sopenharmony_ci    ffrt_mutex_t mtx;
2807484543d1Sopenharmony_ci    tuple t = {&sum, &mtx};
2808484543d1Sopenharmony_ci    int ret = ffrt_mutex_init(&mtx, NULL);
2809484543d1Sopenharmony_ci    if (ret != ffrt_success) {
2810484543d1Sopenharmony_ci        printf("error\n");
2811484543d1Sopenharmony_ci    }
2812484543d1Sopenharmony_ci    for (int i = 0; i < 10; i++) {
2813484543d1Sopenharmony_ci        ffrt_submit_c(func, NULL, &t, NULL, NULL, NULL);
2814484543d1Sopenharmony_ci    }
2815484543d1Sopenharmony_ci    ffrt_mutex_destroy(&mtx);
2816484543d1Sopenharmony_ci    ffrt_wait();
2817484543d1Sopenharmony_ci    printf("sum = %d", sum);
2818484543d1Sopenharmony_ci}
2819484543d1Sopenharmony_ci
2820484543d1Sopenharmony_civoid ffrt_recursive_mutex_task(void *)
2821484543d1Sopenharmony_ci{
2822484543d1Sopenharmony_ci    int sum = 0;
2823484543d1Sopenharmony_ci    int ret = 0;
2824484543d1Sopenharmony_ci    ffrt_mutexattr_t attr;
2825484543d1Sopenharmony_ci    ffrt_mutex_t mtx;
2826484543d1Sopenharmony_ci    tuple t = {&sum, &mtx};
2827484543d1Sopenharmony_ci    ret = ffrt_recursive_mutex_init(&mtx, &attr);
2828484543d1Sopenharmony_ci    if (ret != ffrt_success) {
2829484543d1Sopenharmony_ci        printf("error\n");
2830484543d1Sopenharmony_ci    }
2831484543d1Sopenharmony_ci    for (int i = 0; i < 10; i++) {
2832484543d1Sopenharmony_ci        ffrt_submit_c(func, NULL, &t, NULL, NULL, NULL);
2833484543d1Sopenharmony_ci    }
2834484543d1Sopenharmony_ci    ffrt_recursive_mutex_destroy(&mtx);
2835484543d1Sopenharmony_ci    ffrt_wait();
2836484543d1Sopenharmony_ci    printf("sum = %d", sum);
2837484543d1Sopenharmony_ci}
2838484543d1Sopenharmony_ci
2839484543d1Sopenharmony_ciint main(int narg, char** argv)
2840484543d1Sopenharmony_ci{
2841484543d1Sopenharmony_ci    int r;
2842484543d1Sopenharmony_ci    /* mutex */
2843484543d1Sopenharmony_ci    ffrt_submit_c(ffrt_mutex_task, NULL, NULL, NULL, NULL, NULL);
2844484543d1Sopenharmony_ci    ffrt_wait();
2845484543d1Sopenharmony_ci    /* recursive mutex */
2846484543d1Sopenharmony_ci    ffrt_submit_c(ffrt_recursive_mutex_task, NULL, NULL, NULL, NULL, NULL);
2847484543d1Sopenharmony_ci    ffrt_wait();
2848484543d1Sopenharmony_ci    return 0;
2849484543d1Sopenharmony_ci}
2850484543d1Sopenharmony_ci```
2851484543d1Sopenharmony_ci
2852484543d1Sopenharmony_ci预期输出为
2853484543d1Sopenharmony_ci
2854484543d1Sopenharmony_ci```
2855484543d1Sopenharmony_cisum=10
2856484543d1Sopenharmony_ci```
2857484543d1Sopenharmony_ci
2858484543d1Sopenharmony_ci* 该例子为功能示例,实际中并不鼓励这样使用
2859484543d1Sopenharmony_ci
2860484543d1Sopenharmony_ci### ffrt_rwlock_t
2861484543d1Sopenharmony_ci<hr/>
2862484543d1Sopenharmony_ci* FFRT提供的类似pthread rwlock 的性能实现
2863484543d1Sopenharmony_ci
2864484543d1Sopenharmony_ci#### 声明
2865484543d1Sopenharmony_ci
2866484543d1Sopenharmony_ci```{.cpp}
2867484543d1Sopenharmony_citypedef enum {
2868484543d1Sopenharmony_ci    ffrt_error = -1,
2869484543d1Sopenharmony_ci    ffrt_success = 0,
2870484543d1Sopenharmony_ci    ffrt_error_nomem = ENOMEM,
2871484543d1Sopenharmony_ci    ffrt_error_timedout = ETIMEDOUT,
2872484543d1Sopenharmony_ci    ffrt_error_busy = EBUSY,
2873484543d1Sopenharmony_ci    ffrt_error_inval = EINVAL
2874484543d1Sopenharmony_ci} ffrt_error_t;
2875484543d1Sopenharmony_ci
2876484543d1Sopenharmony_cistruct ffrt_rwlock_t;
2877484543d1Sopenharmony_ci
2878484543d1Sopenharmony_ciint ffrt_rwlock_init(ffrt_rwlock_t* rwlock, const ffrt_rwlockattr_t* attr);
2879484543d1Sopenharmony_ciint ffrt_rwlock_wrlock(ffrt_rwlock_t* rwlock);
2880484543d1Sopenharmony_ciint ffrt_rwlock_trywrlock(ffrt_rwlock_t* rwlock);
2881484543d1Sopenharmony_ciint ffrt_rwlock_rdlock(ffrt_rwlock_t* rwlock);
2882484543d1Sopenharmony_ciint ffrt_rwlock_tryrdlock(ffrt_rwlock_t* rwlock);
2883484543d1Sopenharmony_ciint ffrt_rwlock_unlock(ffrt_rwlock_t* rwlock);
2884484543d1Sopenharmony_ciint ffrt_rwlock_destroy(ffrt_rwlock_t* rwlock);
2885484543d1Sopenharmony_ci```
2886484543d1Sopenharmony_ci
2887484543d1Sopenharmony_ci#### 参数
2888484543d1Sopenharmony_ci
2889484543d1Sopenharmony_ci`attr`
2890484543d1Sopenharmony_ci
2891484543d1Sopenharmony_ci* 当前FFRT只支持基础类型的rwlock,因此attr必须为空指针
2892484543d1Sopenharmony_ci
2893484543d1Sopenharmony_ci`rwlock`
2894484543d1Sopenharmony_ci
2895484543d1Sopenharmony_ci* 指向所操作的读写锁的指针
2896484543d1Sopenharmony_ci
2897484543d1Sopenharmony_ci#### 返回值
2898484543d1Sopenharmony_ci
2899484543d1Sopenharmony_ci* 若成功则为 ffrt_success ,否则发生错误
2900484543d1Sopenharmony_ci
2901484543d1Sopenharmony_ci#### 描述
2902484543d1Sopenharmony_ci* 该接口只能在FFRT task 内部调用,在FFRT task 外部调用存在未定义的行为
2903484543d1Sopenharmony_ci* 该功能能够避免pthread传统的pthread_rwlock_t 在抢不到锁时陷入内核的问题,在使用得当的条件下将会有更好的性能
2904484543d1Sopenharmony_ci* **注意:目前暂不支持递归和定时功能**
2905484543d1Sopenharmony_ci* **注意:C API中的ffrt_rwlock_t需要用户调用`ffrt_rwlock_init`和`ffrt_rwlock_destroy`显式创建和销毁,而C++ API无需该操作**
2906484543d1Sopenharmony_ci* **注意:C API中的ffrt_rwlock_t对象的置空和销毁由用户完成,对同一个ffrt_rwlock_t仅能调用一次`ffrt_rwlock_destroy`,重复对同一个ffrt_rwlock_t调用`ffrt_rwlock_destroy`,其行为是未定义的**
2907484543d1Sopenharmony_ci* **注意:在`ffrt_rwlock_destroy`之后再对ffrt_rwlock_t进行访问,其行为是未定义的**
2908484543d1Sopenharmony_ci
2909484543d1Sopenharmony_ci#### 样例
2910484543d1Sopenharmony_ci
2911484543d1Sopenharmony_ci```{.c}
2912484543d1Sopenharmony_ci#include <stdio.h>
2913484543d1Sopenharmony_ci#include "ffrt_inner.h"
2914484543d1Sopenharmony_ci
2915484543d1Sopenharmony_citypedef struct {
2916484543d1Sopenharmony_ci    int* sum;
2917484543d1Sopenharmony_ci    ffrt_rwlock_t* mtx;
2918484543d1Sopenharmony_ci} tuple;
2919484543d1Sopenharmony_ci
2920484543d1Sopenharmony_civoid func1(void* arg)
2921484543d1Sopenharmony_ci{
2922484543d1Sopenharmony_ci    tuple* t = (tuple*)arg;
2923484543d1Sopenharmony_ci
2924484543d1Sopenharmony_ci    int ret = ffrt_rwlock_wrlock(t->mtx);
2925484543d1Sopenharmony_ci    if (ret != ffrt_success) {
2926484543d1Sopenharmony_ci        printf("error\n");
2927484543d1Sopenharmony_ci    }
2928484543d1Sopenharmony_ci    (*t->sum)++;
2929484543d1Sopenharmony_ci    ret = ffrt_rwlock_unlock(t->mtx);
2930484543d1Sopenharmony_ci    if (ret != ffrt_success) {
2931484543d1Sopenharmony_ci        printf("error\n");
2932484543d1Sopenharmony_ci    }
2933484543d1Sopenharmony_ci}
2934484543d1Sopenharmony_ci
2935484543d1Sopenharmony_civoid func2(void* arg)
2936484543d1Sopenharmony_ci{
2937484543d1Sopenharmony_ci    tuple* t = (tuple*)arg;
2938484543d1Sopenharmony_ci
2939484543d1Sopenharmony_ci    int ret = ffrt_rwlock_rdlock(t->mtx);
2940484543d1Sopenharmony_ci    if (ret != ffrt_success) {
2941484543d1Sopenharmony_ci        printf("error\n");
2942484543d1Sopenharmony_ci    }
2943484543d1Sopenharmony_ci    printf("sum is %d\n", *t->sum);
2944484543d1Sopenharmony_ci    ret = ffrt_rwlock_unlock(t->mtx);
2945484543d1Sopenharmony_ci    if (ret != ffrt_success) {
2946484543d1Sopenharmony_ci        printf("error\n");
2947484543d1Sopenharmony_ci    }
2948484543d1Sopenharmony_ci}
2949484543d1Sopenharmony_ci
2950484543d1Sopenharmony_citypedef struct {
2951484543d1Sopenharmony_ci    ffrt_function_header_t header;
2952484543d1Sopenharmony_ci    ffrt_function_t func;
2953484543d1Sopenharmony_ci    ffrt_function_t after_func;
2954484543d1Sopenharmony_ci    void* arg;
2955484543d1Sopenharmony_ci} c_function;
2956484543d1Sopenharmony_ci
2957484543d1Sopenharmony_cistatic void ffrt_exec_function_wrapper(void* t)
2958484543d1Sopenharmony_ci{
2959484543d1Sopenharmony_ci    c_function* f = (c_function*)t;
2960484543d1Sopenharmony_ci    if (f->func) {
2961484543d1Sopenharmony_ci        f->func(f->arg);
2962484543d1Sopenharmony_ci    }
2963484543d1Sopenharmony_ci}
2964484543d1Sopenharmony_ci
2965484543d1Sopenharmony_cistatic void ffrt_destroy_function_wrapper(void* t)
2966484543d1Sopenharmony_ci{
2967484543d1Sopenharmony_ci    c_function* f = (c_function*)t;
2968484543d1Sopenharmony_ci    if (f->after_func) {
2969484543d1Sopenharmony_ci        f->after_func(f->arg);
2970484543d1Sopenharmony_ci    }
2971484543d1Sopenharmony_ci}
2972484543d1Sopenharmony_ci
2973484543d1Sopenharmony_ci#define FFRT_STATIC_ASSERT(cond, msg) int x(int static_assertion_##msg[(cond) ? 1 : -1])
2974484543d1Sopenharmony_cistatic inline ffrt_function_header_t* ffrt_create_function_wrapper(const ffrt_function_t func,
2975484543d1Sopenharmony_ci    const ffrt_function_t after_func, void* arg)
2976484543d1Sopenharmony_ci{
2977484543d1Sopenharmony_ci    FFRT_STATIC_ASSERT(sizeof(c_function) <= ffrt_auto_managed_function_storage_size,
2978484543d1Sopenharmony_ci        size_of_function_must_be_less_than_ffrt_auto_managed_function_storage_size);
2979484543d1Sopenharmony_ci    c_function* f = (c_function*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
2980484543d1Sopenharmony_ci    f->header.exec = ffrt_exec_function_wrapper;
2981484543d1Sopenharmony_ci    f->header.destroy = ffrt_destroy_function_wrapper;
2982484543d1Sopenharmony_ci    f->func = func;
2983484543d1Sopenharmony_ci    f->after_func = after_func;
2984484543d1Sopenharmony_ci    f->arg = arg;
2985484543d1Sopenharmony_ci    return (ffrt_function_header_t*)f;
2986484543d1Sopenharmony_ci}
2987484543d1Sopenharmony_ci
2988484543d1Sopenharmony_cistatic inline void ffrt_submit_c(ffrt_function_t func, const ffrt_function_t after_func,
2989484543d1Sopenharmony_ci    void* arg, const ffrt_deps_t* in_deps, const ffrt_deps_t* out_deps, const ffrt_task_attr_t* attr)
2990484543d1Sopenharmony_ci{
2991484543d1Sopenharmony_ci    ffrt_submit_base(ffrt_create_function_wrapper(func, after_func, arg), in_deps, out_deps, attr);
2992484543d1Sopenharmony_ci}
2993484543d1Sopenharmony_ci
2994484543d1Sopenharmony_civoid ffrt_rwlock_task(void* arg)
2995484543d1Sopenharmony_ci{
2996484543d1Sopenharmony_ci    int sum = 0;
2997484543d1Sopenharmony_ci    ffrt_rwlock_t mtx;
2998484543d1Sopenharmony_ci    tuple t = {&sum, &mtx};
2999484543d1Sopenharmony_ci    int ret = ffrt_rwlock_init(&mtx, NULL);
3000484543d1Sopenharmony_ci    if (ret != ffrt_success) {
3001484543d1Sopenharmony_ci        printf("error\n");
3002484543d1Sopenharmony_ci    }
3003484543d1Sopenharmony_ci    for (int i = 0; i < 10; i++) {
3004484543d1Sopenharmony_ci        ffrt_submit_c(func1, NULL, &t, NULL, NULL, NULL);
3005484543d1Sopenharmony_ci        for (int j = 0; j < 5; j++) {
3006484543d1Sopenharmony_ci            ffrt_submit_c(func2, NULL, &t, NULL, NULL, NULL);
3007484543d1Sopenharmony_ci        }
3008484543d1Sopenharmony_ci    }
3009484543d1Sopenharmony_ci    ffrt_rwlock_destroy(&mtx);
3010484543d1Sopenharmony_ci    ffrt_wait();
3011484543d1Sopenharmony_ci    printf("sum = %d", sum);
3012484543d1Sopenharmony_ci}
3013484543d1Sopenharmony_ci
3014484543d1Sopenharmony_ciint main(int narg, char** argv)
3015484543d1Sopenharmony_ci{
3016484543d1Sopenharmony_ci    int r;
3017484543d1Sopenharmony_ci    ffrt_submit_c(ffrt_rwlock_task, NULL, NULL, NULL, NULL, NULL);
3018484543d1Sopenharmony_ci    ffrt_wait();
3019484543d1Sopenharmony_ci    return 0;
3020484543d1Sopenharmony_ci}
3021484543d1Sopenharmony_ci```
3022484543d1Sopenharmony_ci
3023484543d1Sopenharmony_ci预期输出为
3024484543d1Sopenharmony_ci
3025484543d1Sopenharmony_ci```
3026484543d1Sopenharmony_cisum is 1
3027484543d1Sopenharmony_cisum is 2
3028484543d1Sopenharmony_cisum is 3
3029484543d1Sopenharmony_cisum is 4
3030484543d1Sopenharmony_cisum is 5
3031484543d1Sopenharmony_cisum is 6
3032484543d1Sopenharmony_cisum is 7
3033484543d1Sopenharmony_cisum is 8
3034484543d1Sopenharmony_cisum is 9
3035484543d1Sopenharmony_cisum is 10
3036484543d1Sopenharmony_ci每种各5次
3037484543d1Sopenharmony_ci
3038484543d1Sopenharmony_ci```
3039484543d1Sopenharmony_ci
3040484543d1Sopenharmony_ci* 该例子为功能示例,实际中并不鼓励这样使用
3041484543d1Sopenharmony_ci
3042484543d1Sopenharmony_ci
3043484543d1Sopenharmony_ci### ffrt_cond_t
3044484543d1Sopenharmony_ci<hr/>
3045484543d1Sopenharmony_ci
3046484543d1Sopenharmony_ci* FFRT提供的类似pthread 信号量的性能实现
3047484543d1Sopenharmony_ci
3048484543d1Sopenharmony_ci#### 声明
3049484543d1Sopenharmony_ci
3050484543d1Sopenharmony_ci```{.c}
3051484543d1Sopenharmony_citypedef enum {
3052484543d1Sopenharmony_ci    ffrt_error = -1,
3053484543d1Sopenharmony_ci    ffrt_success = 0,
3054484543d1Sopenharmony_ci    ffrt_error_nomem = ENOMEM,
3055484543d1Sopenharmony_ci    ffrt_error_timedout = ETIMEDOUT,
3056484543d1Sopenharmony_ci    ffrt_error_busy = EBUSY,
3057484543d1Sopenharmony_ci    ffrt_error_inval = EINVAL
3058484543d1Sopenharmony_ci} ffrt_error_t;
3059484543d1Sopenharmony_ci
3060484543d1Sopenharmony_citypedef struct {
3061484543d1Sopenharmony_ci    uint32_t storage[(ffrt_cond_storage_size + sizeof(uint32_t) - 1) / sizeof(uint32_t)];
3062484543d1Sopenharmony_ci} ffrt_cond_t;
3063484543d1Sopenharmony_ci
3064484543d1Sopenharmony_ciint ffrt_cond_init(ffrt_cond_t* cond, const ffrt_condattr_t* attr);
3065484543d1Sopenharmony_ciint ffrt_cond_signal(ffrt_cond_t* cond);
3066484543d1Sopenharmony_ciint ffrt_cond_broadcast(ffrt_cond_t* cond);
3067484543d1Sopenharmony_ciint ffrt_cond_wait(ffrt_cond_t*cond, ffrt_mutex_t* mutex);
3068484543d1Sopenharmony_ciint ffrt_cond_timedwait(ffrt_cond_t* cond, ffrt_mutex_t* mutex, const struct timespec* time_point);
3069484543d1Sopenharmony_ciint ffrt_cond_destroy(ffrt_cond_t* cond);
3070484543d1Sopenharmony_ci```
3071484543d1Sopenharmony_ci
3072484543d1Sopenharmony_ci#### 参数
3073484543d1Sopenharmony_ci
3074484543d1Sopenharmony_ci`cond`
3075484543d1Sopenharmony_ci
3076484543d1Sopenharmony_ci* 指向所操作的信号量的指针
3077484543d1Sopenharmony_ci
3078484543d1Sopenharmony_ci`attr`
3079484543d1Sopenharmony_ci
3080484543d1Sopenharmony_ci* 属性设定,空指针表示使用默认属性
3081484543d1Sopenharmony_ci
3082484543d1Sopenharmony_ci`mutex`
3083484543d1Sopenharmony_ci
3084484543d1Sopenharmony_ci* 指向要在阻塞期间解锁的互斥锁的指针
3085484543d1Sopenharmony_ci
3086484543d1Sopenharmony_ci`time_point`
3087484543d1Sopenharmony_ci
3088484543d1Sopenharmony_ci* 指向指定等待时限时间的对象的指针
3089484543d1Sopenharmony_ci
3090484543d1Sopenharmony_ci
3091484543d1Sopenharmony_ci#### 返回值
3092484543d1Sopenharmony_ci
3093484543d1Sopenharmony_ci* 若成功则为 ffrt_success,若在锁定互斥前抵达时限则为 ffrt_error_timedout
3094484543d1Sopenharmony_ci
3095484543d1Sopenharmony_ci#### 描述
3096484543d1Sopenharmony_ci* 该接口支持在FFRT task 内部调用,也支持在FFRT task 外部调用
3097484543d1Sopenharmony_ci* 该功能能够避免传统的pthread_cond_t在条件不满足时陷入内核的问题,在使用得当的条件下将会有更好的性能
3098484543d1Sopenharmony_ci* **注意:C API中的ffrt_cond_t需要用户调用`ffrt_cond_init`和`ffrt_cond_destroy`显式创建和销毁,而C++ API中依赖构造和析构自动完成**
3099484543d1Sopenharmony_ci* **注意:C API中的ffrt_cond_t对象的置空和销毁由用户完成,对同一个ffrt_cond_t仅能调用一次`ffrt_cond_destroy`,重复对同一个ffrt_cond_t调用`ffrt_cond_destroy`,其行为是未定义的**
3100484543d1Sopenharmony_ci* **注意:在`ffrt_cond_destroy`之后再对ffrt_cond_t进行访问,其行为是未定义的**
3101484543d1Sopenharmony_ci
3102484543d1Sopenharmony_ci#### 样例
3103484543d1Sopenharmony_ci
3104484543d1Sopenharmony_ci```{.c}
3105484543d1Sopenharmony_ci#include <stdio.h>
3106484543d1Sopenharmony_ci#include "ffrt.h"
3107484543d1Sopenharmony_ci
3108484543d1Sopenharmony_citypedef struct {
3109484543d1Sopenharmony_ci    ffrt_cond_t* cond;
3110484543d1Sopenharmony_ci    int* a;
3111484543d1Sopenharmony_ci    ffrt_mutex_t* lock_;
3112484543d1Sopenharmony_ci} tuple;
3113484543d1Sopenharmony_ci
3114484543d1Sopenharmony_civoid func1(void* arg)
3115484543d1Sopenharmony_ci{
3116484543d1Sopenharmony_ci    tuple* t = (tuple*)arg;
3117484543d1Sopenharmony_ci    int ret = ffrt_mutex_lock(t->lock_);
3118484543d1Sopenharmony_ci    if (ret != ffrt_success) {
3119484543d1Sopenharmony_ci        printf("error\n");
3120484543d1Sopenharmony_ci    }
3121484543d1Sopenharmony_ci    while (*t->a != 1) {
3122484543d1Sopenharmony_ci        ret = ffrt_cond_wait(t->cond, t->lock_);
3123484543d1Sopenharmony_ci        if (ret != ffrt_success) {
3124484543d1Sopenharmony_ci            printf("error\n");
3125484543d1Sopenharmony_ci        }
3126484543d1Sopenharmony_ci    }
3127484543d1Sopenharmony_ci    ret = ffrt_mutex_unlock(t->lock_);
3128484543d1Sopenharmony_ci    if (ret != ffrt_success) {
3129484543d1Sopenharmony_ci        printf("error\n");
3130484543d1Sopenharmony_ci    }
3131484543d1Sopenharmony_ci    printf("a = %d", *(t->a));
3132484543d1Sopenharmony_ci}
3133484543d1Sopenharmony_ci
3134484543d1Sopenharmony_civoid func2(void* arg)
3135484543d1Sopenharmony_ci{
3136484543d1Sopenharmony_ci    tuple* t = (tuple*)arg;
3137484543d1Sopenharmony_ci    int ret = ffrt_mutex_lock(t->lock_);
3138484543d1Sopenharmony_ci    if (ret != ffrt_success) {
3139484543d1Sopenharmony_ci        printf("error\n");
3140484543d1Sopenharmony_ci    }
3141484543d1Sopenharmony_ci    *(t->a) = 1;
3142484543d1Sopenharmony_ci    ret = ffrt_cond_signal(t->cond);
3143484543d1Sopenharmony_ci    if (ret != ffrt_success) {
3144484543d1Sopenharmony_ci        printf("error\n");
3145484543d1Sopenharmony_ci    }
3146484543d1Sopenharmony_ci    ret = ffrt_mutex_unlock(t->lock_);
3147484543d1Sopenharmony_ci    if (ret != ffrt_success) {
3148484543d1Sopenharmony_ci        printf("error\n");
3149484543d1Sopenharmony_ci    }
3150484543d1Sopenharmony_ci}
3151484543d1Sopenharmony_ci
3152484543d1Sopenharmony_citypedef struct {
3153484543d1Sopenharmony_ci    ffrt_function_header_t header;
3154484543d1Sopenharmony_ci    ffrt_function_t func;
3155484543d1Sopenharmony_ci    ffrt_function_t after_func;
3156484543d1Sopenharmony_ci    void* arg;
3157484543d1Sopenharmony_ci} c_function;
3158484543d1Sopenharmony_ci
3159484543d1Sopenharmony_cistatic void ffrt_exec_function_wrapper(void* t)
3160484543d1Sopenharmony_ci{
3161484543d1Sopenharmony_ci    c_function* f = (c_function*)t;
3162484543d1Sopenharmony_ci    if (f->func) {
3163484543d1Sopenharmony_ci        f->func(f->arg);
3164484543d1Sopenharmony_ci    }
3165484543d1Sopenharmony_ci}
3166484543d1Sopenharmony_ci
3167484543d1Sopenharmony_cistatic void ffrt_destroy_function_wrapper(void* t)
3168484543d1Sopenharmony_ci{
3169484543d1Sopenharmony_ci    c_function* f = (c_function*)t;
3170484543d1Sopenharmony_ci    if (f->after_func) {
3171484543d1Sopenharmony_ci        f->after_func(f->arg);
3172484543d1Sopenharmony_ci    }
3173484543d1Sopenharmony_ci}
3174484543d1Sopenharmony_ci
3175484543d1Sopenharmony_ci#define FFRT_STATIC_ASSERT(cond, msg) int x(int static_assertion_##msg[(cond) ? 1 : -1])
3176484543d1Sopenharmony_cistatic inline ffrt_function_header_t* ffrt_create_function_wrapper(const ffrt_function_t func,
3177484543d1Sopenharmony_ci    const ffrt_function_t after_func, void* arg)
3178484543d1Sopenharmony_ci{
3179484543d1Sopenharmony_ci    FFRT_STATIC_ASSERT(sizeof(c_function) <= ffrt_auto_managed_function_storage_size,
3180484543d1Sopenharmony_ci        size_of_function_must_be_less_than_ffrt_auto_managed_function_storage_size);
3181484543d1Sopenharmony_ci    c_function* f = (c_function*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
3182484543d1Sopenharmony_ci    f->header.exec = ffrt_exec_function_wrapper;
3183484543d1Sopenharmony_ci    f->header.destroy = ffrt_destroy_function_wrapper;
3184484543d1Sopenharmony_ci    f->func = func;
3185484543d1Sopenharmony_ci    f->after_func = after_func;
3186484543d1Sopenharmony_ci    f->arg = arg;
3187484543d1Sopenharmony_ci    return (ffrt_function_header_t*)f;
3188484543d1Sopenharmony_ci}
3189484543d1Sopenharmony_ci
3190484543d1Sopenharmony_cistatic inline void ffrt_submit_c(ffrt_function_t func, const ffrt_function_t after_func,
3191484543d1Sopenharmony_ci    void* arg, const ffrt_deps_t* in_deps, const ffrt_deps_t* out_deps, const ffrt_task_attr_t* attr)
3192484543d1Sopenharmony_ci{
3193484543d1Sopenharmony_ci    ffrt_submit_base(ffrt_create_function_wrapper(func, after_func, arg), in_deps, out_deps, attr);
3194484543d1Sopenharmony_ci}
3195484543d1Sopenharmony_ci
3196484543d1Sopenharmony_civoid ffrt_cv_task(void*)
3197484543d1Sopenharmony_ci{
3198484543d1Sopenharmony_ci    ffrt_cond_t cond;
3199484543d1Sopenharmony_ci    int ret = ffrt_cond_init(&cond, NULL);
3200484543d1Sopenharmony_ci    if (ret != ffrt_success) {
3201484543d1Sopenharmony_ci        printf("error\n");
3202484543d1Sopenharmony_ci    }
3203484543d1Sopenharmony_ci    int a = 0;
3204484543d1Sopenharmony_ci    ffrt_mutex_t lock_;
3205484543d1Sopenharmony_ci    tuple t = {&cond, &a, &lock_};
3206484543d1Sopenharmony_ci    ret = ffrt_mutex_init(&lock_, NULL);
3207484543d1Sopenharmony_ci    if (ret != ffrt_success) {
3208484543d1Sopenharmony_ci        printf("error\n");
3209484543d1Sopenharmony_ci    }
3210484543d1Sopenharmony_ci    ffrt_submit_c(func1, NULL, &t, NULL, NULL, NULL);
3211484543d1Sopenharmony_ci    ffrt_submit_c(func2, NULL, &t, NULL, NULL, NULL);
3212484543d1Sopenharmony_ci    ffrt_wait();
3213484543d1Sopenharmony_ci    ffrt_cond_destroy(&cond);
3214484543d1Sopenharmony_ci    ffrt_mutex_destroy(&lock_);
3215484543d1Sopenharmony_ci}
3216484543d1Sopenharmony_ci
3217484543d1Sopenharmony_ciint main(int narg, char** argv)
3218484543d1Sopenharmony_ci{
3219484543d1Sopenharmony_ci    ffrt_submit_c(ffrt_cv_task, NULL, NULL, NULL, NULL, NULL);
3220484543d1Sopenharmony_ci    ffrt_wait();
3221484543d1Sopenharmony_ci    return 0;
3222484543d1Sopenharmony_ci}
3223484543d1Sopenharmony_ci```
3224484543d1Sopenharmony_ci
3225484543d1Sopenharmony_ci预期输出为:
3226484543d1Sopenharmony_ci
3227484543d1Sopenharmony_ci```
3228484543d1Sopenharmony_cia=1
3229484543d1Sopenharmony_ci```
3230484543d1Sopenharmony_ci
3231484543d1Sopenharmony_ci* 该例子为功能示例,实际中并不鼓励这样使用
3232484543d1Sopenharmony_ci
3233484543d1Sopenharmony_ci## 杂项
3234484543d1Sopenharmony_ci
3235484543d1Sopenharmony_ci### ffrt_usleep
3236484543d1Sopenharmony_ci
3237484543d1Sopenharmony_ci<hr/>
3238484543d1Sopenharmony_ci
3239484543d1Sopenharmony_ci* FFRT提供的类似C11 sleep和linux usleep的性能实现
3240484543d1Sopenharmony_ci
3241484543d1Sopenharmony_ci#### 声明
3242484543d1Sopenharmony_ci
3243484543d1Sopenharmony_ci```{.c}
3244484543d1Sopenharmony_ciint ffrt_usleep(uint64_t usec);
3245484543d1Sopenharmony_ci```
3246484543d1Sopenharmony_ci
3247484543d1Sopenharmony_ci#### 参数
3248484543d1Sopenharmony_ci
3249484543d1Sopenharmony_ci`usec`
3250484543d1Sopenharmony_ci
3251484543d1Sopenharmony_ci* 睡眠的us数
3252484543d1Sopenharmony_ci
3253484543d1Sopenharmony_ci#### 返回值
3254484543d1Sopenharmony_ci
3255484543d1Sopenharmony_ci* 不涉及
3256484543d1Sopenharmony_ci
3257484543d1Sopenharmony_ci#### 描述
3258484543d1Sopenharmony_ci* 该接口只能在FFRT task 内部调用,在FFRT task 外部调用存在未定义的行为
3259484543d1Sopenharmony_ci* 该功能能够避免传统的sleep 睡眠时陷入内核的问题,在使用得当的条件下将会有更好的性能
3260484543d1Sopenharmony_ci
3261484543d1Sopenharmony_ci#### 样例
3262484543d1Sopenharmony_ci
3263484543d1Sopenharmony_ci```{.c}
3264484543d1Sopenharmony_ci#include <stdio.h>
3265484543d1Sopenharmony_ci#include "ffrt.h"
3266484543d1Sopenharmony_ci
3267484543d1Sopenharmony_civoid func(void* arg)
3268484543d1Sopenharmony_ci{
3269484543d1Sopenharmony_ci    time_t current_time = time(NULL);
3270484543d1Sopenharmony_ci    printf("Time: %s", ctime(&current_time));
3271484543d1Sopenharmony_ci    ffrt_usleep(2000000); // 睡眠 2 秒
3272484543d1Sopenharmony_ci    current_time = time(NULL);
3273484543d1Sopenharmony_ci    printf("Time: %s", ctime(&current_time));
3274484543d1Sopenharmony_ci}
3275484543d1Sopenharmony_ci
3276484543d1Sopenharmony_citypedef struct {
3277484543d1Sopenharmony_ci    ffrt_function_header_t header;
3278484543d1Sopenharmony_ci    ffrt_function_t func;
3279484543d1Sopenharmony_ci    ffrt_function_t after_func;
3280484543d1Sopenharmony_ci    void* arg;
3281484543d1Sopenharmony_ci} c_function;
3282484543d1Sopenharmony_ci
3283484543d1Sopenharmony_cistatic void ffrt_exec_function_wrapper(void* t)
3284484543d1Sopenharmony_ci{
3285484543d1Sopenharmony_ci    c_function* f = (c_function*)t;
3286484543d1Sopenharmony_ci    if (f->func) {
3287484543d1Sopenharmony_ci        f->func(f->arg);
3288484543d1Sopenharmony_ci    }
3289484543d1Sopenharmony_ci}
3290484543d1Sopenharmony_ci
3291484543d1Sopenharmony_cistatic void ffrt_destroy_function_wrapper(void* t)
3292484543d1Sopenharmony_ci{
3293484543d1Sopenharmony_ci    c_function* f = (c_function*)t;
3294484543d1Sopenharmony_ci    if (f->after_func) {
3295484543d1Sopenharmony_ci        f->after_func(f->arg);
3296484543d1Sopenharmony_ci    }
3297484543d1Sopenharmony_ci}
3298484543d1Sopenharmony_ci
3299484543d1Sopenharmony_ci#define FFRT_STATIC_ASSERT(cond, msg) int x(int static_assertion_##msg[(cond) ? 1 : -1])
3300484543d1Sopenharmony_cistatic inline ffrt_function_header_t* ffrt_create_function_wrapper(const ffrt_function_t func,
3301484543d1Sopenharmony_ci    const ffrt_function_t after_func, void* arg)
3302484543d1Sopenharmony_ci{
3303484543d1Sopenharmony_ci    FFRT_STATIC_ASSERT(sizeof(c_function) <= ffrt_auto_managed_function_storage_size,
3304484543d1Sopenharmony_ci        size_of_function_must_be_less_than_ffrt_auto_managed_function_storage_size);
3305484543d1Sopenharmony_ci    c_function* f = (c_function*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
3306484543d1Sopenharmony_ci    f->header.exec = ffrt_exec_function_wrapper;
3307484543d1Sopenharmony_ci    f->header.destroy = ffrt_destroy_function_wrapper;
3308484543d1Sopenharmony_ci    f->func = func;
3309484543d1Sopenharmony_ci    f->after_func = after_func;
3310484543d1Sopenharmony_ci    f->arg = arg;
3311484543d1Sopenharmony_ci    return (ffrt_function_header_t*)f;
3312484543d1Sopenharmony_ci}
3313484543d1Sopenharmony_ci
3314484543d1Sopenharmony_cistatic inline void ffrt_submit_c(ffrt_function_t func, const ffrt_function_t after_func,
3315484543d1Sopenharmony_ci    void* arg, const ffrt_deps_t* in_deps, const ffrt_deps_t* out_deps, const ffrt_task_attr_t* attr)
3316484543d1Sopenharmony_ci{
3317484543d1Sopenharmony_ci    ffrt_submit_base(ffrt_create_function_wrapper(func, after_func, arg), in_deps, out_deps, attr);
3318484543d1Sopenharmony_ci}
3319484543d1Sopenharmony_ci
3320484543d1Sopenharmony_ciint main(int narg, char** argv)
3321484543d1Sopenharmony_ci{
3322484543d1Sopenharmony_ci    ffrt_submit_c(func, NULL, NULL, NULL, NULL, NULL);
3323484543d1Sopenharmony_ci    ffrt_wait();
3324484543d1Sopenharmony_ci    return 0;
3325484543d1Sopenharmony_ci}
3326484543d1Sopenharmony_ci```
3327484543d1Sopenharmony_ci
3328484543d1Sopenharmony_ci预期输出为
3329484543d1Sopenharmony_ci
3330484543d1Sopenharmony_ci```
3331484543d1Sopenharmony_ciTime: Tue Aug 13 11:34:40 2024
3332484543d1Sopenharmony_ciTime: Tue Aug 13 11:34:42 2024
3333484543d1Sopenharmony_ci```
3334484543d1Sopenharmony_ci
3335484543d1Sopenharmony_ci### ffrt_yield
3336484543d1Sopenharmony_ci<hr/>
3337484543d1Sopenharmony_ci
3338484543d1Sopenharmony_ci* 当前task 主动让出CPU 执行资源,让其他可以被执行的task 先执行,如果没有其他可被执行的task,yield 无效
3339484543d1Sopenharmony_ci
3340484543d1Sopenharmony_ci#### 声明
3341484543d1Sopenharmony_ci
3342484543d1Sopenharmony_ci```{.cpp}
3343484543d1Sopenharmony_civoid ffrt_yield();
3344484543d1Sopenharmony_ci```
3345484543d1Sopenharmony_ci
3346484543d1Sopenharmony_ci#### 参数
3347484543d1Sopenharmony_ci
3348484543d1Sopenharmony_ci* 不涉及
3349484543d1Sopenharmony_ci
3350484543d1Sopenharmony_ci#### 返回值
3351484543d1Sopenharmony_ci
3352484543d1Sopenharmony_ci* 不涉及
3353484543d1Sopenharmony_ci
3354484543d1Sopenharmony_ci#### 描述
3355484543d1Sopenharmony_ci* 该接口只能在FFRT task 内部调用,在FFRT task 外部调用存在未定义的行为
3356484543d1Sopenharmony_ci* 此函数的确切行为取决于实现,特别是使用中的FFRT 调度程序的机制和系统状态
3357484543d1Sopenharmony_ci
3358484543d1Sopenharmony_ci#### 样例
3359484543d1Sopenharmony_ci
3360484543d1Sopenharmony_ci* 省略
3361484543d1Sopenharmony_ci
3362484543d1Sopenharmony_ci## 维测
3363484543d1Sopenharmony_ci
3364484543d1Sopenharmony_ci### 长耗时任务监测
3365484543d1Sopenharmony_ci
3366484543d1Sopenharmony_ci#### 描述
3367484543d1Sopenharmony_ci* 长耗时任务打印机制  
3368484543d1Sopenharmony_ci  当任务执行时间超过一秒时,会触发一次堆栈打印,后续该任务堆栈打印频率调整为一分钟。连续打印十次后,打印频率调整为十分钟。再触发十次打印后,打印频率固定为三十分钟。
3369484543d1Sopenharmony_ci* 该机制的堆栈打印调用的是DFX的 `GetBacktraceStringByTid` 接口,该接口会向阻塞线程发送抓栈信号,触发中断并抓取调用栈返回。  
3370484543d1Sopenharmony_ci
3371484543d1Sopenharmony_ci#### 样例  
3372484543d1Sopenharmony_ci在对应进程日志中搜索 `RecordSymbolAndBacktrace` 关键字,对应的日志示例如下:
3373484543d1Sopenharmony_ci
3374484543d1Sopenharmony_ci```
3375484543d1Sopenharmony_ciW C01719/ffrt: 60500:RecordSymbolAndBacktrace:159 Tid[16579] function occupies worker for more than [1]s.
3376484543d1Sopenharmony_ciW C01719/ffrt: 60501:RecordSymbolAndBacktrace:164 Backtrace:
3377484543d1Sopenharmony_ciW C01719/ffrt: #00 pc 00000000000075f0 /system/lib64/module/file/libhash.z.so
3378484543d1Sopenharmony_ciW C01719/ffrt: #01 pc 0000000000008758 /system/lib64/module/file/libhash.z.so
3379484543d1Sopenharmony_ciW C01719/ffrt: #02 pc 0000000000012b98 /system/lib64/module/file/libhash.z.so
3380484543d1Sopenharmony_ciW C01719/ffrt: #03 pc 000000000002aaa0 /system/lib64/platformsdk/libfilemgmt_libn.z.so
3381484543d1Sopenharmony_ciW C01719/ffrt: #04 pc 0000000000054b2c /system/lib64/platformsdk/libace_napi.z.so
3382484543d1Sopenharmony_ciW C01719/ffrt: #05 pc 00000000000133a8 /system/lib64/platformsdk/libuv.so
3383484543d1Sopenharmony_ciW C01719/ffrt: #06 pc 00000000000461a0 /system/lib64/chipset-sdk/libffrt.so
3384484543d1Sopenharmony_ciW C01719/ffrt: #07 pc 0000000000046d44 /system/lib64/chipset-sdk/libffrt.so
3385484543d1Sopenharmony_ciW C01719/ffrt: #08 pc 0000000000046a6c /system/lib64/chipset-sdk/libffrt.so
3386484543d1Sopenharmony_ciW C01719/ffrt: #09 pc 00000000000467b0 /system/lib64/chipset-sdk/libffrt.so
3387484543d1Sopenharmony_ci```
3388484543d1Sopenharmony_ci该维测会打印出worker上执行时间超过阈值的任务堆栈、worker线程号、执行时间,请自行根据堆栈找对应组件确认阻塞原因。
3389484543d1Sopenharmony_ci
3390484543d1Sopenharmony_ci
3391484543d1Sopenharmony_ci#### 注意事项
3392484543d1Sopenharmony_ci如果代码中存在 `sleep` 等会被中断唤醒的阻塞,用户需主动接收该阻塞的返回值,并重新调用。  
3393484543d1Sopenharmony_ci示例如下:
3394484543d1Sopenharmony_ci```
3395484543d1Sopenharmony_ciunsigned int leftTime = sleep(10);
3396484543d1Sopenharmony_ciwhile (leftTime != 0) {
3397484543d1Sopenharmony_ci    leftTime = sleep(leftTime);
3398484543d1Sopenharmony_ci}
3399484543d1Sopenharmony_ci```
3400484543d1Sopenharmony_ci
3401484543d1Sopenharmony_ci# 部署
3402484543d1Sopenharmony_ci
3403484543d1Sopenharmony_ci## 部署方式
3404484543d1Sopenharmony_ci<img src="images/image-20230120153923679.png" alt="image-20230120153923679" style="zoom:67%;" />
3405484543d1Sopenharmony_ci
3406484543d1Sopenharmony_ci* FFRT的部署依赖FFRT动态库libffrt.so和一组header头文件
3407484543d1Sopenharmony_ci
3408484543d1Sopenharmony_ci* FFRT的头文件为`ffrt.h`,内部包含了C++ API,C API和C base API
3409484543d1Sopenharmony_ci  * ffrt.h 定义为:
3410484543d1Sopenharmony_ci  ```{.cpp}
3411484543d1Sopenharmony_ci  #ifndef FFRT_API_FFRT_H
3412484543d1Sopenharmony_ci  #define FFRT_API_FFRT_H
3413484543d1Sopenharmony_ci  #ifdef __cplusplus
3414484543d1Sopenharmony_ci  #include "cpp/task.h"
3415484543d1Sopenharmony_ci  #include "cpp/deadline.h"
3416484543d1Sopenharmony_ci  #include "cpp/sys_event.h"
3417484543d1Sopenharmony_ci  #include "cpp/mutex.h"
3418484543d1Sopenharmony_ci  #include "cpp/condition_variable.h"
3419484543d1Sopenharmony_ci  #include "cpp/sleep.h"
3420484543d1Sopenharmony_ci  #include "cpp/thread.h"
3421484543d1Sopenharmony_ci  #include "cpp/config.h"
3422484543d1Sopenharmony_ci  #include "cpp/future.h"
3423484543d1Sopenharmony_ci  #else
3424484543d1Sopenharmony_ci  #include "c/task.h"
3425484543d1Sopenharmony_ci  #include "c/deadline.h"
3426484543d1Sopenharmony_ci  #include "c/sys_event.h"
3427484543d1Sopenharmony_ci  #include "c/mutex.h"
3428484543d1Sopenharmony_ci  #include "c/condition_variable.h"
3429484543d1Sopenharmony_ci  #include "c/sleep.h"
3430484543d1Sopenharmony_ci  #include "c/thread.h"
3431484543d1Sopenharmony_ci  #include "c/config.h"
3432484543d1Sopenharmony_ci  #endif
3433484543d1Sopenharmony_ci  #endif
3434484543d1Sopenharmony_ci  ```
3435484543d1Sopenharmony_ci  * C base API定义示例:
3436484543d1Sopenharmony_ci  ```{.cpp}
3437484543d1Sopenharmony_ci  void ffrt_submit_base(ffrt_function_header_t* func, ...);
3438484543d1Sopenharmony_ci  int ffrt_mutex_init(...);
3439484543d1Sopenharmony_ci  ```
3440484543d1Sopenharmony_ci  * C API定义示例:
3441484543d1Sopenharmony_ci  ```{.cpp}
3442484543d1Sopenharmony_ci  static inline void ffrt_submit(ffrt_function_t func, void* arg, ...)
3443484543d1Sopenharmony_ci  {
3444484543d1Sopenharmony_ci      ffrt_submit_base(ffrt_create_function_wrapper(func, arg), ...);
3445484543d1Sopenharmony_ci  }
3446484543d1Sopenharmony_ci  ```
3447484543d1Sopenharmony_ci  * C++ API定义示例:
3448484543d1Sopenharmony_ci  ```{.cpp}
3449484543d1Sopenharmony_ci  namespace ffrt {
3450484543d1Sopenharmony_ci  static inline void submit(std::function& func, ...)
3451484543d1Sopenharmony_ci  {
3452484543d1Sopenharmony_ci      ffrt_submit_base(ffrt_create_function_wrapper(func), ...);
3453484543d1Sopenharmony_ci  }
3454484543d1Sopenharmony_ci  struct mutex {
3455484543d1Sopenharmony_ci      mutex() {
3456484543d1Sopenharmony_ci          ffrt_mutex_init(...);
3457484543d1Sopenharmony_ci          ...
3458484543d1Sopenharmony_ci      };
3459484543d1Sopenharmony_ci  }
3460484543d1Sopenharmony_ci  ```
3461484543d1Sopenharmony_ci  
3462484543d1Sopenharmony_ci* **出于易用性方面的考虑,除非必要,强烈建议你使用C++ API,调用C API将会使你的代码非常臃肿或者更容易产生资源未释放问题**
3463484543d1Sopenharmony_ci
3464484543d1Sopenharmony_ci| 需求列表                                                     |
3465484543d1Sopenharmony_ci| ------------------------------------------------------------ |
3466484543d1Sopenharmony_ci| 需求1:ABI兼容性,在NDK场景中由于用户的编译环境与FFRT的编译环境不同,使用C++接口可能存在ABI兼容性问题,要有解决方案 |
3467484543d1Sopenharmony_ci| 需求2:用户的编译环境为纯C编译环境,不想因为引入FFRT而引入C++元素的场景,要有解决方案 |
3468484543d1Sopenharmony_ci| 需求3:易用性,尽可能让接口简单易用,用户少出错              |
3469484543d1Sopenharmony_ci
3470484543d1Sopenharmony_ci* 对于需求1,通过在用户调用的C++接口和FFRT的实现之间增加一个C base API层,并基于头文件方式将API中的C++的元素编译到用户的so,从而解决ABI兼容的问题
3471484543d1Sopenharmony_ci* 对于需求2,可以通过C Base API解决
3472484543d1Sopenharmony_ci* 对于需求3,建议用户尽可能使用C++ API,以避免C API固有的资源未初始化/释放、参数冗长等问题,对于不得不使用C API的场景,FFRT仍然支持用户使用C API和C base API
3473484543d1Sopenharmony_ci
3474484543d1Sopenharmony_ci
3475484543d1Sopenharmony_ci
3476484543d1Sopenharmony_ci<br/>
3477484543d1Sopenharmony_ci<br/>
3478484543d1Sopenharmony_ci
3479484543d1Sopenharmony_ci<hr/>
3480484543d1Sopenharmony_ci# 实战指南
3481484543d1Sopenharmony_ci
3482484543d1Sopenharmony_ci## 步骤1: 分析应用
3483484543d1Sopenharmony_ci
3484484543d1Sopenharmony_ci使用 FFRT 并行编程的第一步便是您需要了解你的应用。
3485484543d1Sopenharmony_ci
3486484543d1Sopenharmony_ci【建议1】:使用 Task 梳理应用的流程。
3487484543d1Sopenharmony_ci
3488484543d1Sopenharmony_ci使用 Task 梳理应用的流程,并且尽可能使用数据来表达 Task 之间的依赖。当然如果两个 Task 之间如无数据依赖,仅存在控制依赖,您也可以创建一个虚拟的(或者逻辑上的)数据依赖。
3489484543d1Sopenharmony_ci
3490484543d1Sopenharmony_ci<img src="images/image-20220926152831526.png" style="zoom:70%" />
3491484543d1Sopenharmony_ci
3492484543d1Sopenharmony_ci<center>AIRAW 的数据流图</center>
3493484543d1Sopenharmony_ci
3494484543d1Sopenharmony_ci基于数据流图,可以很容易判定出哪些 Task 是可以并发的,比如,Slice0 的 NPU Task 和 Slice1 的 GPU Pre Task 是可以并发的,因为它们没有任何依赖。
3495484543d1Sopenharmony_ci
3496484543d1Sopenharmony_ci反过来,如果并发的效果不理想,也可以通过调整数据流图来优化并发。例如,假如上图中GPU Pre Task 执行时间有很大波动,但平均耗时略小于 NPU Task,会出现某些时刻 GPU Pre Task 拖慢整个执行时间。此时,如果将 GPU Pre Task 的输出 Buffer 改成3个(或者更多)的 Buffer ,可以增加 GPU Pre Task 和 NPU Task 的并发机会,将降低波动对总执行时间的影响。
3497484543d1Sopenharmony_ci
3498484543d1Sopenharmony_ci 
3499484543d1Sopenharmony_ci
3500484543d1Sopenharmony_ci【建议2】:这里不用太担心 Task 大或小的问题,因为 FFRT 允许你在 Task 内部继续拆分 SubTask,可以逐步细化。
3501484543d1Sopenharmony_ci
3502484543d1Sopenharmony_ci下图中,第一次画数据流图时,可以不将 FaceDirection 和 UpdateExistFaceImageInfo 两个 Task 展开,可以逐步细化。
3503484543d1Sopenharmony_ci
3504484543d1Sopenharmony_ci<img src="images/image-20220926153003884.png" style="zoom:70%" />
3505484543d1Sopenharmony_ci
3506484543d1Sopenharmony_ci<center>某拍照业务的数据流图</center>
3507484543d1Sopenharmony_ci
3508484543d1Sopenharmony_ci【建议3】:上述流程图或者数据流图不要求是静态图(即 Task 数量和 Task 依赖关系是固定的)
3509484543d1Sopenharmony_ci
3510484543d1Sopenharmony_ciFFRT 允许动态提交 Task ,在编程界面上不体现图的概念,FFRT 内部会根据Task 之间的依赖关系动态调整数据流图的节点。
3511484543d1Sopenharmony_ci
3512484543d1Sopenharmony_ci
3513484543d1Sopenharmony_ci【建议4】:尽可能对应用做热点分析
3514484543d1Sopenharmony_ci
3515484543d1Sopenharmony_ci如果是对存量代码的 FFRT 化改造,那么,使用 System Trace 这类工具能帮助您聚焦在性能热点上,比如下图可以很容易知道当前的性能Bound,在分析数据流图时,可以重点关注这些热点任务。
3516484543d1Sopenharmony_ci
3517484543d1Sopenharmony_ci<img src="images/image-20220926153030993.png" style="zoom:70%" />
3518484543d1Sopenharmony_ci
3519484543d1Sopenharmony_ci<center>某业务的System Trace</center>
3520484543d1Sopenharmony_ci
3521484543d1Sopenharmony_ci## 步骤2: 并行化应用
3522484543d1Sopenharmony_ci
3523484543d1Sopenharmony_ci【建议1】:不要直接使用线程,使用 FFRT 提交Task。
3524484543d1Sopenharmony_ci
3525484543d1Sopenharmony_ci如果应用中有明显的数据依赖关系,那么 FFRT 将会非常适合;最差的情况是应用没有数据依赖或难以并行(如果真的存在),您仍然可以把 FFRT 当做一个高效的进程级线程池、或者协程库去使用它,但非常不建议你继续创建线程。
3526484543d1Sopenharmony_ci
3527484543d1Sopenharmony_ci 
3528484543d1Sopenharmony_ci
3529484543d1Sopenharmony_ci【建议2】:Task 最好被建模为纯函数。
3530484543d1Sopenharmony_ci
3531484543d1Sopenharmony_ci纯函数是指其执行没有副作用,例如更新全局数据结构。每个任务都依赖于其输入/输出签名来连接到其他任务。
3532484543d1Sopenharmony_ci
3533484543d1Sopenharmony_ci请注意,即使 Task 不是"纯"的,FFRT 仍然适用。只要任务使用的数据依赖或者锁足以保证正确执行,FFRT 就能正常工作。
3534484543d1Sopenharmony_ci
3535484543d1Sopenharmony_ci 
3536484543d1Sopenharmony_ci
3537484543d1Sopenharmony_ci【建议3】:尽可能尝试通过 inDeps/outDeps 表达依赖,而不是使用 ffrt::wait()。
3538484543d1Sopenharmony_ci
3539484543d1Sopenharmony_ci这是因为 FFRT 跟踪和处理 inDeps/outDeps 比调用显式 ffrt::wait() 函数更自然、更便宜。
3540484543d1Sopenharmony_ci
3541484543d1Sopenharmony_ci 
3542484543d1Sopenharmony_ci
3543484543d1Sopenharmony_ci【建议4】:注意 Task 粒度
3544484543d1Sopenharmony_ci
3545484543d1Sopenharmony_ci以适当的粒度提交任务至关重要:目前每个任务的调度开销约为 10 us。如果 Task 的粒度非常小,那么开销的百分比将会很高。FFRT 会继续基于软硬件的方式优化调度开销。
3546484543d1Sopenharmony_ci
3547484543d1Sopenharmony_ci 
3548484543d1Sopenharmony_ci
3549484543d1Sopenharmony_ci【建议5】:尽可能使用 FFRT 原语
3550484543d1Sopenharmony_ci
3551484543d1Sopenharmony_ci如果需要mutex、sleep、异步 I/O,请使用 FFRT 原语,而不是使用OS 提供的版本。因为这些 FFRT 提供的实现在与 FFRT 配合时开销将会更小。
3552484543d1Sopenharmony_ci
3553484543d1Sopenharmony_ci 
3554484543d1Sopenharmony_ci
3555484543d1Sopenharmony_ci【建议6】:在需要时,使用 ffrt::wait() 确保栈变量的生命周期。
3556484543d1Sopenharmony_ci
3557484543d1Sopenharmony_ci如果子任务使用驻留在父任务栈上的数据,则父任务应避免在子任务执行完成前返回。在父任务的末尾添加 ffrt::wait() 可以解决这个问题。
3558484543d1Sopenharmony_ci
3559484543d1Sopenharmony_ci 
3560484543d1Sopenharmony_ci
3561484543d1Sopenharmony_ci## 步骤3: 优化应用
3562484543d1Sopenharmony_ci
3563484543d1Sopenharmony_ci【建议1】:基于System Trace,分析并行是否符合预期
3564484543d1Sopenharmony_ci
3565484543d1Sopenharmony_ciFFRT 已经内置 SysTrace 支持,默认以txx.xx表示,非常有利于分析 Task 粒度和并发度。未来,在性能分析和维测方面将继续增强。
3566484543d1Sopenharmony_ci
3567484543d1Sopenharmony_ci<img src="images/image-20220926153209875.png" style="zoom:70%" />
3568484543d1Sopenharmony_ci
3569484543d1Sopenharmony_ci【建议2】:对于耗时的 Task,尝试提交 SubTask,提升应用的并行度
3570484543d1Sopenharmony_ci
3571484543d1Sopenharmony_ci
3572484543d1Sopenharmony_ci【建议3】:在合适的场景,使用 Deadline 调度,实现能效和性能的平衡
3573484543d1Sopenharmony_ci
3574484543d1Sopenharmony_ci方案正在验证中,待更新。
3575484543d1Sopenharmony_ci
3576484543d1Sopenharmony_ci 
3577484543d1Sopenharmony_ci
3578484543d1Sopenharmony_ci## 样例: CameraHal QuickThumb
3579484543d1Sopenharmony_ci
3580484543d1Sopenharmony_ci### 步骤1: 分析应用
3581484543d1Sopenharmony_ci
3582484543d1Sopenharmony_ci<img src="images/image-20220926153255824.png" style="zoom:70%" />
3583484543d1Sopenharmony_ci
3584484543d1Sopenharmony_ci1)   QuickThumb 是 CameraHal 中实现的对一张图片进行缩小的功能,整体运行时间约30 us;
3585484543d1Sopenharmony_ci
3586484543d1Sopenharmony_ci2)   在实现上分为两层循环,外层的一次循环输出1行,内层的1次循环输出该行的m列;
3587484543d1Sopenharmony_ci
3588484543d1Sopenharmony_ci3)   在划分 Task 时,一种简单的做法是1行的处理就是1个Task。
3589484543d1Sopenharmony_ci
3590484543d1Sopenharmony_ci### 步骤2: 并行化应用
3591484543d1Sopenharmony_ci<img src="images/image-20220926153509205.png" style="zoom:100%" />
3592484543d1Sopenharmony_ci
3593484543d1Sopenharmony_ci 1)   根据纯函数的定义,该 Task 的输入输出的数据是非常之多的,因此,这个场景下使用更宽泛的纯函数的定义,只需要考虑在 Task 内部会被写,但是却被定义在 Task 外部的变量即可;
3594484543d1Sopenharmony_ci
3595484543d1Sopenharmony_ci2)   按照上面的原则,将 py/puv 的定义移到 Task 内部可避免多个 Task 同时写 py/puv 的问题;
3596484543d1Sopenharmony_ci
3597484543d1Sopenharmony_ci3)   s32r 的处理可以有两种方式,都能得到正确的功能:a. 保持定义在Task 外部,但作为Task 的输出依赖;b. 将s32r定义在Task 内部,作为Task的私有变量。显然,b 方案能够获得更好的性能
3598484543d1Sopenharmony_ci
3599484543d1Sopenharmony_ci 
3600484543d1Sopenharmony_ci
3601484543d1Sopenharmony_ci### 步骤3: 优化应用
3602484543d1Sopenharmony_ci
3603484543d1Sopenharmony_ci通过System Trace,会发现上述改造方案的Task 粒度较小,大约单个Task 耗时在5us左右,因此,扩大Task的粒度为32行处理,得到最终的并行结果,下图为使用4小核和3中核的结果。
3604484543d1Sopenharmony_ci
3605484543d1Sopenharmony_ci<img src="images/image-20220926153603572.png" style="zoom:100%" />
3606484543d1Sopenharmony_ci
3607484543d1Sopenharmony_ci
3608484543d1Sopenharmony_ci
3609484543d1Sopenharmony_ci## 样例: Camera AIRAW
3610484543d1Sopenharmony_ci
3611484543d1Sopenharmony_ci### 步骤1: 分析应用
3612484543d1Sopenharmony_ci<img src="images/image-20220926153611121.png" style="zoom:70%" />
3613484543d1Sopenharmony_ci
3614484543d1Sopenharmony_ciAIRAW 的处理包括了3个处理步骤,在数据面上,可以按slice 进行切分,在不考虑pre_outbuf和npu_outbuf 在slice间复用的情况下,数据流图如上图所示。
3615484543d1Sopenharmony_ci
3616484543d1Sopenharmony_ci<img src="images/image-20220926152831526.png" style="zoom:70%" />
3617484543d1Sopenharmony_ci
3618484543d1Sopenharmony_ci为了节省运行过程中的内存占用,但不影响整体性能,可以只保留2个pre_outbuf和2个npu_outbuf。
3619484543d1Sopenharmony_ci
3620484543d1Sopenharmony_ci`为此付出的代价是:Buffer 的复用产生了slice3 的GPU Pre Task 依赖slice1 的NPU Task 完成,俗称反压,又称生产者依赖关系。但是,如果您使用 FFRT 来实现,将会是非常自然而高效的`
3621484543d1Sopenharmony_ci
3622484543d1Sopenharmony_ci### 步骤2: 并行化应用
3623484543d1Sopenharmony_ci
3624484543d1Sopenharmony_ci```{.cpp}
3625484543d1Sopenharmony_ciconstexpr uint32_t SLICE_NUM = 24;
3626484543d1Sopenharmony_ciconstexpr uint32_t BUFFER_NUM = 2;
3627484543d1Sopenharmony_ci
3628484543d1Sopenharmony_ciint input[SLICE_NUM]; // input is split into SLICE_NUM slices
3629484543d1Sopenharmony_ciint pre_outbuf[BUFFER_NUM]; // gpu pre task output buffers
3630484543d1Sopenharmony_ciint npu_outbuf[BUFFER_NUM]; // npu output buffers
3631484543d1Sopenharmony_ciint output[SLICE_NUM]; // output is split into SLICE_NUM slices
3632484543d1Sopenharmony_ci
3633484543d1Sopenharmony_cifor (uint32_t i = 0; i < SLICE_NUM; i++) {
3634484543d1Sopenharmony_ci  uint32_t buf_id = i % BUFFER_NUM;
3635484543d1Sopenharmony_ci  ffrt::submit(gpuPreTask, {input + i}, {pre_outbuf + buf_id});
3636484543d1Sopenharmony_ci  ffrt::submit(npuTask, {pre_outbuf + buf_id}, {npu_outbuf + buf_id});
3637484543d1Sopenharmony_ci  ffrt::submit(gpuPostTask, {npu_outbuf + buf_id}, {output + i});
3638484543d1Sopenharmony_ci}
3639484543d1Sopenharmony_ci
3640484543d1Sopenharmony_ciffrt::wait();
3641484543d1Sopenharmony_ci```
3642484543d1Sopenharmony_ci
3643484543d1Sopenharmony_ci### 步骤3: 优化应用
3644484543d1Sopenharmony_ci
3645484543d1Sopenharmony_ci<img src="images/image-20220926153825527.png" style="zoom:100%" />
3646484543d1Sopenharmony_ci
3647484543d1Sopenharmony_ci基于以上实现,从上面的Trace中我们看到,NPU 的硬件时间被完全用满,系统端到端性能达到最优,而付出的开发代价将会比GCD 或多线程小的多。
3648484543d1Sopenharmony_ci
3649484543d1Sopenharmony_ci 
3650484543d1Sopenharmony_ci
3651484543d1Sopenharmony_ci## 样例: Camera FaceStory
3652484543d1Sopenharmony_ci
3653484543d1Sopenharmony_ci### 步骤1: 分析应用
3654484543d1Sopenharmony_ci
3655484543d1Sopenharmony_ci<img src="images/image-20220926153003884.png" style="zoom:70%" />
3656484543d1Sopenharmony_ci
3657484543d1Sopenharmony_ci 
3658484543d1Sopenharmony_ci
3659484543d1Sopenharmony_ci### 步骤2: 并行化应用
3660484543d1Sopenharmony_ci
3661484543d1Sopenharmony_ci<img src="images/image-20220926153906692.png" style="zoom:100%" />
3662484543d1Sopenharmony_ci
3663484543d1Sopenharmony_ci代码改造样例
3664484543d1Sopenharmony_ci
3665484543d1Sopenharmony_ci1)     该场景输出存量代码迁移,只需将原先串行的代码以Task的方式提交即可;
3666484543d1Sopenharmony_ci
3667484543d1Sopenharmony_ci2)     过程中需要考虑Data Race和数据生命周期;
3668484543d1Sopenharmony_ci
3669484543d1Sopenharmony_ci3)     先提交大的Task,根据需要逐步拆分SubTask。
3670484543d1Sopenharmony_ci
3671484543d1Sopenharmony_ci 
3672484543d1Sopenharmony_ci
3673484543d1Sopenharmony_ci### 步骤3: 优化应用
3674484543d1Sopenharmony_ci
3675484543d1Sopenharmony_ci<img src="images/image-20220926153030993.png" style="zoom:100%" />
3676484543d1Sopenharmony_ci
3677484543d1Sopenharmony_ci<center>原始System Trace</center>
3678484543d1Sopenharmony_ci
3679484543d1Sopenharmony_ci<img src="images/image-20220926153925963.png" style="zoom:100%" />
3680484543d1Sopenharmony_ci
3681484543d1Sopenharmony_ci
3682484543d1Sopenharmony_ci
3683484543d1Sopenharmony_ci
3684484543d1Sopenharmony_ci<center>改造后System Trace</center>
3685484543d1Sopenharmony_ci
3686484543d1Sopenharmony_ci并行化的收益来自于:
3687484543d1Sopenharmony_ci
3688484543d1Sopenharmony_ci1)    多分支或循环并发,实现CPU前后处理和NPU的并发
3689484543d1Sopenharmony_ci
3690484543d1Sopenharmony_ci2)    子任务拆分,进一步提升并行度
3691484543d1Sopenharmony_ci
3692484543d1Sopenharmony_ci3)    基于数据流图优化CPU L2 Cache Flush频次
3693484543d1Sopenharmony_ci
3694484543d1Sopenharmony_ci4)    NPU Worker Thread实时优先级调整,后续FFRT中考虑独立出XPU调度Worker来保证实时性
3695484543d1Sopenharmony_ci
3696484543d1Sopenharmony_ci5)    在未来,模型加载使用FFRT submit,模型加载内部也可以使用submit来继续拆分,能够优化整个业务的启动耗时。
3697484543d1Sopenharmony_ci
3698484543d1Sopenharmony_ci<br/>
3699484543d1Sopenharmony_ci<br/>
3700484543d1Sopenharmony_ci<hr/>
3701484543d1Sopenharmony_ci
3702484543d1Sopenharmony_ci
3703484543d1Sopenharmony_ci
3704484543d1Sopenharmony_ci# 使用建议
3705484543d1Sopenharmony_ci
3706484543d1Sopenharmony_ci## 建议1: 函数化
3707484543d1Sopenharmony_ci
3708484543d1Sopenharmony_ci**基本思想:计算过程函数化**
3709484543d1Sopenharmony_ci
3710484543d1Sopenharmony_ci* 程序过程各步骤以函数封装表达,函数满足类纯函数特性
3711484543d1Sopenharmony_ci* 无全局数据访问
3712484543d1Sopenharmony_ci* 无内部状态保留
3713484543d1Sopenharmony_ci* 通过ffrt::submit()接口以异步任务方式提交函数执行
3714484543d1Sopenharmony_ci* 将函数访问的数据对象以及访问方式在ffrt::submit()接口中的in_deps/out_deps参数表达
3715484543d1Sopenharmony_ci* 程序员通过inDeps/outDeps参数表达任务间依赖关系以保证程序执行的正确性
3716484543d1Sopenharmony_ci
3717484543d1Sopenharmony_ci> 做到纯函数的好处在于:1. 能够最大化挖掘并行度,2.避免DataRace和锁的问题
3718484543d1Sopenharmony_ci
3719484543d1Sopenharmony_ci
3720484543d1Sopenharmony_ci
3721484543d1Sopenharmony_ci**在实际中,可以根据场景放松纯函数的约束,但前提是:**
3722484543d1Sopenharmony_ci
3723484543d1Sopenharmony_ci* 确定添加的in_deps/out_deps可确保程序正确执行
3724484543d1Sopenharmony_ci* 通过FFRT提供的锁机制保护对全局变量的访问
3725484543d1Sopenharmony_ci
3726484543d1Sopenharmony_ci
3727484543d1Sopenharmony_ci
3728484543d1Sopenharmony_ci## 建议2: 注意任务粒度
3729484543d1Sopenharmony_ci
3730484543d1Sopenharmony_ci* FFRT管理和调度异步任务执行有调度开销,任务粒度(执行时间)需匹配调度开销
3731484543d1Sopenharmony_ci* 大量小粒度任务造成FFRT调度开销占比增加,性能下降,解决方法:
3732484543d1Sopenharmony_ci  * 将多个小粒度任务聚合为大粒度任务一次发送给FFRT异步执行
3733484543d1Sopenharmony_ci  * 同步方式执行小粒度任务,不发送给FFRT异步执行。需注意和异步任务之间的数据同步问题,在需要同步的地方插入ffrt::wait()
3734484543d1Sopenharmony_ci  * 下面的例子中,fib_ffrt2会比fib_ffrt1拥有更好的性能
3735484543d1Sopenharmony_ci
3736484543d1Sopenharmony_ci  ```{.cpp}
3737484543d1Sopenharmony_ci  #include "ffrt.h"
3738484543d1Sopenharmony_ci  void fib_ffrt1(int x, int& y)
3739484543d1Sopenharmony_ci  {
3740484543d1Sopenharmony_ci      if (x <= 1) {
3741484543d1Sopenharmony_ci          y = x;
3742484543d1Sopenharmony_ci      } else {
3743484543d1Sopenharmony_ci          int y1, y2;
3744484543d1Sopenharmony_ci          ffrt::submit([&] {fib_ffrt1(x - 1, y1);}, {&x}, {&y1} );
3745484543d1Sopenharmony_ci          ffrt::submit([&] {fib_ffrt1(x - 2, y2);}, {&x}, {&y2} );
3746484543d1Sopenharmony_ci          ffrt::submit([&] {y = y1 + y2;}, {&y1, &y2}, {} );
3747484543d1Sopenharmony_ci          ffrt::wait();
3748484543d1Sopenharmony_ci      }
3749484543d1Sopenharmony_ci  }
3750484543d1Sopenharmony_ci
3751484543d1Sopenharmony_ci  void fib_ffrt2(int x, int& y)
3752484543d1Sopenharmony_ci  {
3753484543d1Sopenharmony_ci      if (x <= 1) {
3754484543d1Sopenharmony_ci          y = x;
3755484543d1Sopenharmony_ci      } else {
3756484543d1Sopenharmony_ci          int y1, y2;
3757484543d1Sopenharmony_ci          ffrt::submit([&] {fib_ffrt2(x - 1, y1);}, {&x}, {&y1} );
3758484543d1Sopenharmony_ci          ffrt::submit([&] {fib_ffrt2(x - 2, y2);}, {&x}, {&y2} );
3759484543d1Sopenharmony_ci          ffrt::wait({&y1, &y2});
3760484543d1Sopenharmony_ci          y = y1 + y2;
3761484543d1Sopenharmony_ci      }
3762484543d1Sopenharmony_ci  }
3763484543d1Sopenharmony_ci  ```
3764484543d1Sopenharmony_ci
3765484543d1Sopenharmony_ci
3766484543d1Sopenharmony_ci
3767484543d1Sopenharmony_ci## 建议3: 数据生命周期
3768484543d1Sopenharmony_ci
3769484543d1Sopenharmony_ci* FFRT的任务提交和执行是异步的,因此需要确保任务执行时,对任务中涉及的数据的访问是有效的
3770484543d1Sopenharmony_ci* 常见问题:子任务使用父任务栈数据,当父任务先于子任务执行完成时释放栈数据,子任务产生数据访问错误
3771484543d1Sopenharmony_ci* 解决方法1:父任务中增加ffrt::wait()等待子任务完成
3772484543d1Sopenharmony_ci
3773484543d1Sopenharmony_ci```{.cpp}
3774484543d1Sopenharmony_ci#include "ffrt.h"
3775484543d1Sopenharmony_civoid fib_ffrt(int x, int& y)
3776484543d1Sopenharmony_ci{
3777484543d1Sopenharmony_ci    if (x <= 1) {
3778484543d1Sopenharmony_ci        y = x;
3779484543d1Sopenharmony_ci    } else {
3780484543d1Sopenharmony_ci        int y1, y2;
3781484543d1Sopenharmony_ci        ffrt::submit([&] {fib_ffrt(x - 1, y1);}, {&x}, {&y1} );
3782484543d1Sopenharmony_ci        ffrt::submit([&] {fib_ffrt(x - 2, y2);}, {&x}, {&y2} );
3783484543d1Sopenharmony_ci        ffrt::submit([&] {y = y1 + y2;}, {&y1, &y2}, {} );
3784484543d1Sopenharmony_ci        ffrt::wait(); // 用于保证y1 y2的生命周期
3785484543d1Sopenharmony_ci    }
3786484543d1Sopenharmony_ci}
3787484543d1Sopenharmony_ci```
3788484543d1Sopenharmony_ci
3789484543d1Sopenharmony_ci* 解决方法2:将数据由栈移到堆,手动管理生命周期
3790484543d1Sopenharmony_ci
3791484543d1Sopenharmony_ci```{.cpp}
3792484543d1Sopenharmony_ci#include "ffrt.h"
3793484543d1Sopenharmony_civoid fib_ffrt(int x, int* y)
3794484543d1Sopenharmony_ci{
3795484543d1Sopenharmony_ci    if (x <= 1) {
3796484543d1Sopenharmony_ci        *y = x;
3797484543d1Sopenharmony_ci    } else {
3798484543d1Sopenharmony_ci        int *y1 = (int*)malloc(sizeof(int));
3799484543d1Sopenharmony_ci        int *y2 = (int*)malloc(sizeof(int));
3800484543d1Sopenharmony_ci		
3801484543d1Sopenharmony_ci        ffrt::submit([=] {fib_ffrt(x - 1, y1);}, {}, {y1} );
3802484543d1Sopenharmony_ci        ffrt::submit([=] {fib_ffrt(x - 2, y2);}, {}, {y2} );
3803484543d1Sopenharmony_ci        ffrt::submit([=] {*y = *y1 + *y2; }, {y1, y2}, {} );
3804484543d1Sopenharmony_ci		ffrt::wait();
3805484543d1Sopenharmony_ci    }
3806484543d1Sopenharmony_ci}
3807484543d1Sopenharmony_ci```
3808484543d1Sopenharmony_ci
3809484543d1Sopenharmony_ci
3810484543d1Sopenharmony_ci
3811484543d1Sopenharmony_ci## 建议4: 使用FFRT提供的替代API
3812484543d1Sopenharmony_ci
3813484543d1Sopenharmony_ci* 禁止在FFRT任务中使用系统线程库API创建线程,使用submit提交任务
3814484543d1Sopenharmony_ci* 使用FFRT提供的锁,条件变量,睡眠,IO等API代替系统线程库API
3815484543d1Sopenharmony_ci  * 使用系统线程库API可能造成工作线程阻塞,引起额外性能开销
3816484543d1Sopenharmony_ci
3817484543d1Sopenharmony_ci
3818484543d1Sopenharmony_ci
3819484543d1Sopenharmony_ci## 建议5: Deadline机制
3820484543d1Sopenharmony_ci
3821484543d1Sopenharmony_ci* **必须用于具备周期/重复执行特征的处理流程**
3822484543d1Sopenharmony_ci* 在有明确时间约束和性能关键的处理流程中使用,避免滥用
3823484543d1Sopenharmony_ci* 在相对大颗粒度的处理流程中使用,例如具有16.6ms时间约束的帧处理流程
3824484543d1Sopenharmony_ci
3825484543d1Sopenharmony_ci
3826484543d1Sopenharmony_ci
3827484543d1Sopenharmony_ci## 建议6: 从线程模型迁移
3828484543d1Sopenharmony_ci
3829484543d1Sopenharmony_ci* 创建线程替代为创建FFRT任务
3830484543d1Sopenharmony_ci  * 线程从逻辑上类似无in_deps的任务
3831484543d1Sopenharmony_ci* 识别线程间的依赖关系,并将其表达在任务的依赖关系in_deps/out_deps3832484543d1Sopenharmony_ci* 线程内计算过程分解为异步任务调用
3833484543d1Sopenharmony_ci* 通过任务依赖关系和锁机制避免并发任务数据竞争问题
3834484543d1Sopenharmony_ci
3835484543d1Sopenharmony_ci
3836484543d1Sopenharmony_ci
3837484543d1Sopenharmony_ci# 已知限制
3838484543d1Sopenharmony_ci
3839484543d1Sopenharmony_ci## thread local使用约束
3840484543d1Sopenharmony_ci* FFRT Task中使用thread local存在风险,说明如下:
3841484543d1Sopenharmony_ci* thread local变量包括C/C++语言提供的thread_local定义的变量,使用pthread_key_create创建的变量
3842484543d1Sopenharmony_ci* FFRT支持Task调度,Task调度到哪个线程是随机的,使用thread local是有风险的,这一点和所有支持Task并发调度的框架一样
3843484543d1Sopenharmony_ci* FFRT的Task默认以协程的方式运行,Task执行过程中可能发生协程退出,恢复执行时,执行该任务的线程可能发生变更
3844484543d1Sopenharmony_ci
3845484543d1Sopenharmony_ci## thread绑定类使用约束
3846484543d1Sopenharmony_ci* FFRT支持Task调度,Task调度到哪个线程是随机的,thread_idx/线程优先级/线程亲和性等与thread绑定的行为禁止在task中使用
3847484543d1Sopenharmony_ci
3848484543d1Sopenharmony_ci## recursive mutex使用约束
3849484543d1Sopenharmony_ci* FFRT Task中使用标准库的recursive mutex可能发生死锁,需要更换为FFRT提供的recursive mutex,说明如下:
3850484543d1Sopenharmony_ci* recursive mutex在lock()成功时记录调用者"执行栈"作为锁的owner,在后续lock()时会判断调用者是否为当前执行栈,如果是则返回成功,以支持在同一个执行栈中嵌套获取锁。在标准库的实现中,"执行栈"以线程标识表示。
3851484543d1Sopenharmony_ci* 在FFRT Task中使用标准库的recursive mutex,如果在外层和内层lock()之间,发生Task(协程)退出,Task恢复执行时在不同于首次调用lock()的FFRT Worker上,则判断当前线程不是owner,lock()失败,FFRT Worker挂起,后面的unlock()不会被执行,从而出现死锁。
3852484543d1Sopenharmony_ci
3853484543d1Sopenharmony_ci## FFRT对使用fork()场景的支持说明
3854484543d1Sopenharmony_ci
3855484543d1Sopenharmony_ci* 在未使用FFRT的进程中,创建子进程,支持在该子进程中使用FFRT(调用submit,timer,epoll等任务类操作)。
3856484543d1Sopenharmony_ci* 在已经使用FFRT的进程中,以fork()(无exec())方式创建子进程,不支持在该子进程中使用FFRT。
3857484543d1Sopenharmony_ci* 在已经使用FFRT的进程中,以fork()+exec()方式创建子进程,支持在子进程中使用FFRT。
3858484543d1Sopenharmony_ci
3859484543d1Sopenharmony_ci## 以动态库方式部署FFRT
3860484543d1Sopenharmony_ci
3861484543d1Sopenharmony_ci* 只能以动态库方式部署FFRT,静态库部署可能有多实例问题,例如:当多个被同一进程加载的so都以静态库的方式使用FFRT时,FFRT会被实例化成多份,其行为是未知的,这也不是FFRT设计的初衷
3862484543d1Sopenharmony_ci
3863484543d1Sopenharmony_ci## C API中初始化ffrt对象后,对象的置空与销毁由用户负责
3864484543d1Sopenharmony_ci
3865484543d1Sopenharmony_ci* 为保证较高的性能,ffrt的C API中内部不包含对对象的销毁状态的标记,用户需要合理地进行资源的释放,重复调用各个对象的destroy操作,其结果是未定义的
3866484543d1Sopenharmony_ci* 错误示例1,重复调用destroy可能造成不可预知的数据损坏
3867484543d1Sopenharmony_ci
3868484543d1Sopenharmony_ci```{.cpp}
3869484543d1Sopenharmony_ci#include "ffrt.h"
3870484543d1Sopenharmony_civoid abnormal_case_1()
3871484543d1Sopenharmony_ci{
3872484543d1Sopenharmony_ci    ffrt_task_handle_t h = ffrt_submit_h([](){printf("Test task running...\n");}, NULL, NULL, NULL, NULL, NULL);
3873484543d1Sopenharmony_ci    ...
3874484543d1Sopenharmony_ci    ffrt_task_handle_destroy(h);
3875484543d1Sopenharmony_ci    ffrt_task_handle_destroy(h); // double free
3876484543d1Sopenharmony_ci}
3877484543d1Sopenharmony_ci```
3878484543d1Sopenharmony_ci
3879484543d1Sopenharmony_ci* 错误示例2,未调用destroy会造成内存泄漏
3880484543d1Sopenharmony_ci
3881484543d1Sopenharmony_ci```{.cpp}
3882484543d1Sopenharmony_ci#include "ffrt.h"
3883484543d1Sopenharmony_civoid abnormal_case_2()
3884484543d1Sopenharmony_ci{
3885484543d1Sopenharmony_ci    ffrt_task_handle_t h = ffrt_submit_h([](){printf("Test task running...\n");}, NULL, NULL, NULL, NULL, NULL);
3886484543d1Sopenharmony_ci    ...
3887484543d1Sopenharmony_ci    // memory leak
3888484543d1Sopenharmony_ci}
3889484543d1Sopenharmony_ci```
3890484543d1Sopenharmony_ci
3891484543d1Sopenharmony_ci* 建议示例,仅调用一次destroy,如有必要可进行置空
3892484543d1Sopenharmony_ci
3893484543d1Sopenharmony_ci```{.cpp}
3894484543d1Sopenharmony_ci#include "ffrt.h"
3895484543d1Sopenharmony_civoid normal_case()
3896484543d1Sopenharmony_ci{
3897484543d1Sopenharmony_ci    ffrt_task_handle_t h = ffrt_submit_h([](){printf("Test task running...\n");}, NULL, NULL, NULL, NULL, NULL);
3898484543d1Sopenharmony_ci    ...
3899484543d1Sopenharmony_ci    ffrt_task_handle_destroy(h);
3900484543d1Sopenharmony_ci    h = nullptr; // if necessary
3901484543d1Sopenharmony_ci}
3902484543d1Sopenharmony_ci```
3903484543d1Sopenharmony_ci
3904484543d1Sopenharmony_ci## 输入输出依赖数量的限制
3905484543d1Sopenharmony_ci
3906484543d1Sopenharmony_ci* 使用submit接口进行任务提交时,每个任务的输入依赖和输出依赖的数量之和不能超过8个。
3907484543d1Sopenharmony_ci* 使用submit_h接口进行任务提交时,每个任务的输入依赖和输出依赖的数量之和不能超过7个。
3908484543d1Sopenharmony_ci* 参数既作为输入依赖又作为输出依赖的时候,统计依赖数量时只统计一次,如输入依赖是{&x},输出依赖也是{&x},实际依赖的数量是1。
3909