• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Function Flow Runtime C API
2
3## 任务管理
4
5### ffrt_deps_t
6
7#### 声明
8
9```c
10typedef enum {
11    ffrt_dependence_data,
12    ffrt_dependence_task,
13} ffrt_dependence_type_t;
14
15typedef struct {
16    ffrt_dependence_type_t type;
17    const void* ptr;
18} ffrt_dependence_t;
19
20typedef struct {
21    uint32_t len;
22    const ffrt_dependence_t* items;
23} ffrt_deps_t;
24```
25
26#### 参数
27
28- `len`:数据依赖个数。
29- `items`:数据依赖数组,数据长度等于`len`。
30- `ptr`:数据地址。
31- `type`:区分数据和`task_handle`。
32
33#### 描述
34
35`ffrt_dependence_t`作用等同C++的`dependence`,`ffrt_deps_t`作用等同C++的`std::vector<dependence>`。
36
37#### 样例
38
39```c
40// 创建数据依赖
41int x = 0;
42ffrt_dependence_t dependence[1];
43dependence[0].type = ffrt_dependence_data;
44dependence[0].ptr = &x;
45ffrt_deps_t deps;
46deps.len = 1;
47deps.items = dependence;
48
49// 创建任务依赖
50ffrt_task_handle_t task = ffrt_submit_h_base(user_function_header, NULL, NULL, &attr);
51ffrt_dependence_t dependence[1];
52dependence[0].type = ffrt_dependence_task;
53dependence[0].ptr = task;
54ffrt_deps_t deps;
55deps.len = 1;
56deps.items = dependence;
57```
58
59### ffrt_task_attr_t
60
61#### 声明
62
63```c
64typedef struct {
65    uint32_t storage[(ffrt_task_attr_storage_size + sizeof(uint32_t) - 1) / sizeof(uint32_t)];
66} ffrt_task_attr_t;
67```
68
69#### 描述
70
71任务的属性描述,在提交普通任务或者队列任务时,可以通过`ffrt_task_attr_t`来配置其属性。
72
73#### 方法
74
75##### ffrt_task_attr_init
76
77```c
78FFRT_C_API int ffrt_task_attr_init(ffrt_task_attr_t* attr);
79```
80
81参数
82
83- `attr`:`ffrt_task_attr_t`对象指针。
84
85返回值
86
87- 0表示成功,-1表示失败。
88
89描述
90
91- 初始化一个`ffrt_task_attr_t`对象。
92
93##### ffrt_task_attr_destroy
94
95```c
96FFRT_C_API void ffrt_task_attr_destroy(ffrt_task_attr_t* attr);
97```
98
99参数
100
101- `attr`:`ffrt_task_attr_t`对象指针。
102
103描述
104
105- 去初始化一个`ffrt_task_attr_t`对象。
106
107##### ffrt_task_attr_set_name
108
109```c
110FFRT_C_API void ffrt_task_attr_set_name(ffrt_task_attr_t* attr, const char* name);
111```
112
113参数
114
115- `attr`:`ffrt_task_attr_t`对象指针。
116- `name`:任务的名称。
117
118描述
119
120- 设置任务的名称,名称是用于维测信息打印的一种有效信息。
121
122##### ffrt_task_attr_get_name
123
124```c
125FFRT_C_API const char* ffrt_task_attr_get_name(const ffrt_task_attr_t* attr);
126```
127
128参数
129
130- `attr`:`ffrt_task_attr_t`对象指针。
131
132返回值
133
134- 任务的名称。
135
136描述
137
138- 获取设置的任务名称。
139
140##### ffrt_task_attr_set_qos
141
142```c
143FFRT_C_API void ffrt_task_attr_set_qos(ffrt_task_attr_t* attr, ffrt_qos_t qos);
144```
145
146参数
147
148- `attr`:`ffrt_task_attr_t`对象指针。
149- `qos`:QoS等级。
150
151描述
152
153- 设置任务的QoS等级,QoS等级影响任务执行时的系统资源供给。不设置QoS的情况下,队列任务默认继承队列的QoS等级,普通任务默认设置为`ffrt_qos_default`。
154
155##### ffrt_task_attr_get_qos
156
157```c
158FFRT_C_API ffrt_qos_t ffrt_task_attr_get_qos(const ffrt_task_attr_t* attr);
159```
160
161参数
162
163- `attr`:`ffrt_task_attr_t`对象指针。
164
165返回值
166
167- QoS等级。
168
169描述
170
171- 获取设置的QoS等级。
172
173##### ffrt_task_attr_set_delay
174
175```c
176FFRT_C_API void ffrt_task_attr_set_delay(ffrt_task_attr_t* attr, uint64_t delay_us);
177```
178
179参数
180
181- `attr`:`ffrt_task_attr_t`对象指针。
182- `delay_us`:调度时延,单位为微秒。
183
184描述
185
186- 设置任务的调度时延,任务会在时延间隔之后才调度执行。不设置的情况下,默认时延为零。
187
188##### ffrt_task_attr_get_delay
189
190```c
191FFRT_C_API uint64_t ffrt_task_attr_get_delay(const ffrt_task_attr_t* attr);
192```
193
194参数
195
196- `attr`:`ffrt_task_attr_t`对象指针。
197
198返回值
199
200- 调度时延。
201
202描述
203
204- 获取设置的调度时延。
205
206##### ffrt_task_attr_set_queue_priority
207
208```c
209FFRT_C_API void ffrt_task_attr_set_queue_priority(ffrt_task_attr_t* attr, ffrt_queue_priority_t priority);
210```
211
212参数
213
214- `attr`:`ffrt_task_attr_t`对象指针。
215- `priority`:任务优先级。
216
217描述
218
219- 设置任务的优先级,目前仅并发队列任务支持优先级功能,同一个并发队列中按照优先级顺序来调度任务。不设置的情况下,任务默认优先级`ffrt_queue_priority_low`。
220
221##### ffrt_task_attr_get_queue_priority
222
223```c
224FFRT_C_API ffrt_queue_priority_t ffrt_task_attr_get_queue_priority(const ffrt_task_attr_t* attr);
225```
226
227参数
228
229- `attr`:`ffrt_task_attr_t`对象指针。
230
231返回值
232
233- 任务优先级。
234
235描述
236
237- 获取设置的优先级。
238
239##### ffrt_task_attr_set_stack_size
240
241```c
242FFRT_C_API void ffrt_task_attr_set_stack_size(ffrt_task_attr_t* attr, uint64_t size);
243```
244
245参数
246
247- `attr`:`ffrt_task_attr_t`对象指针。
248- `size`:协程栈大小,单位为字节。
249
250描述
251
252- 设置任务的协程栈大小,影响任务执行过程中最大的调用栈使用空间上限。在不设置的情况下,默认的协程栈大小为1MB。
253
254##### ffrt_task_attr_get_stack_size
255
256```c
257FFRT_C_API uint64_t ffrt_task_attr_get_stack_size(const ffrt_task_attr_t* attr);
258```
259
260参数
261
262- `attr`:`ffrt_task_attr_t`对象指针。
263
264返回值
265
266- 协程栈大小。
267
268描述
269
270- 获取设置的协程栈大小。
271
272#### 样例
273
274```c
275// 提交一个普通任务,其名称为"sample_task",QoS等级为background,调度时延为1ms,协程栈大小为2MB
276ffrt_task_attr_t attr;
277ffrt_task_attr_init(&attr);
278ffrt_task_attr_set_name(&attr, "sample_task");
279ffrt_task_attr_set_qos(&attr, ffrt_qos_background);
280ffrt_task_attr_set_delay(&attr, 1000);
281ffrt_task_attr_set_stack_size(&attr, 2 * 1024 * 1024);
282ffrt_submit_base(user_function_header, NULL, NULL, &attr);
283ffrt_task_attr_destroy(&attr);
284```
285
286### ffrt_alloc_auto_managed_function_storage_base
287
288#### 声明
289
290```c
291typedef enum {
292    ffrt_function_kind_general,
293    ffrt_function_kind_queue,
294} ffrt_function_kind_t;
295
296typedef void(*ffrt_function_t)(void*);
297typedef struct {
298    ffrt_function_t exec;
299    ffrt_function_t destroy;
300    uint64_t reserve[2];
301} ffrt_function_header_t;
302
303FFRT_C_API void *ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_t kind);
304```
305
306#### 参数
307
308- `kind`:提交普通任务选择`ffrt_function_kind_general`,提交队列任务选择`ffrt_function_kind_queue`。
309- `exec`:任务实际执行调用的函数指针。
310- `destroy`:任务完成后调用的函数指针,可用于资源清理等用途。
311- `reserve`:内部预留空间,用户请勿使用该成员。
312
313#### 返回值
314
315- 返回存储用户任务执行体的指针。
316
317#### 描述
318
319分配了一块内存空间,内存空间头部为`ffrt_function_header_t`结构体(返回指针可转换为`ffrt_function_header_t*`指针使用)。头部后留有64字节的可用空间,用户可自定义使用该空间,通常用于入参或返回值的存储。
320
321#### 样例
322
323- 样例1:生成一个不带参数和返回值的任务执行体:
324
325    ```c
326    void foo(void* data)
327    {
328        printf("foo\n");
329    }
330
331    void after_foo(void* data)
332    {
333        printf("after_foo\n");
334    }
335
336    int main()
337    {
338        ffrt_function_header_t* func = (ffrt_function_header_t*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
339
340        func->exec = foo;
341        func->destroy = after_foo;
342
343        ffrt_submit_base(func, NULL, NULL, NULL);
344        ffrt_wait();
345
346        return 0;
347    }
348    ```
349
350- 样例2:生成一个带参数和返回值的任务执行体:
351
352    ```c
353    int foo(int x, int y)
354    {
355        printf("foo: x = %d, y = %d\n", x, y);
356        return x + y;
357    }
358
359    void after_foo(void* data)
360    {
361        printf("after_foo\n");
362    }
363
364    // 用户自定义任务执行体,可携带参数和返回值
365    struct user_defined_function {
366        ffrt_function_header_t header; // 头部内存为ffrt_function_header_t
367        int arg1; // 参数1
368        int arg2; // 参数2
369        int ret; // 返回值
370    };
371
372    // 将foo包装成void(*)(void*)的exec函数类型
373    void exec_func_wrapper(void* header)
374    {
375        user_defined_function* func = (user_defined_function*)header;
376        func->ret = foo(func->arg1, func->arg2); // 内部展开真正的foo函数,传递参数,获取返回值
377    }
378
379    int main()
380    {
381        user_defined_function* func = (user_defined_function*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
382
383        func->header.exec = exec_func_wrapper;
384        func->header.destroy = after_foo;
385        func->arg1 = 1;
386        func->arg2 = 2;
387
388        ffrt_submit_base((ffrt_function_header_t*)func, NULL, NULL, NULL);
389        ffrt_wait();
390
391        printf("ret = %d\n", func->ret);
392        return 0;
393    }
394    ```
395
396### ffrt_submit_base
397
398#### 声明
399
400```c
401FFRT_C_API void ffrt_submit_base(ffrt_function_header_t* f, const ffrt_deps_t* in_deps, const ffrt_deps_t* out_deps, const ffrt_task_attr_t* attr);
402```
403
404#### 参数
405
406- `f`:用户的任务执行体,可以是原生的`ffrt_function_header_t`类型,也可以基于`ffrt_function_header_t`自定义拓展类型。
407- `in_deps`:任务的输入数据依赖。输入数据依赖通常以实际数据的地址表达,也支持`ffrt_task_handle_t`作为一种特殊输入依赖。
408- `out_deps`:任务的输出数据依赖。输出数据依赖通常以实际数据的地址表达,不支持`ffrt_task_handle_t`。
409- `attr`:任务的属性设置。
410
411#### 描述
412
413提交一个普通任务,任务支持相关属性设置,在输入依赖解除后任务可调度执行,任务执行完成后解除输出依赖。
414
415#### 样例
416
417- 样例1:提交带属性的任务:
418
419    ```c
420    void foo(void* data)
421    {
422        printf("foo\n");
423    }
424
425    void after_foo(void* data)
426    {
427        printf("after_foo\n");
428    }
429
430    // 提交一个任务
431    ffrt_function_header_t* func = (ffrt_function_header_t*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
432    func->exec = foo;
433    func->destroy = after_foo;
434    ffrt_submit_base(func, NULL, NULL, NULL);
435
436    // 提交一个带属性的任务
437    ffrt_task_attr_t attr;
438    ffrt_task_attr_init(&attr);
439    ffrt_task_attr_set_name(&attr, "sample_task");
440    ffrt_task_attr_set_qos(&attr, ffrt_qos_background);
441    ffrt_submit_base(func, NULL, NULL, &attr);
442    ```
443
444- 样例2:提交带数据依赖的任务:
445
446    ```c
447    // 提交两个带数据依赖的任务,任务间存在Read-After-Write依赖关系
448    #include "math.h"
449    #include "ffrt.h"
450
451    void cos_func(float* x, float* y)
452    {
453        *y = std::cos(*x);
454    }
455
456    void tan_func(float* y, float* z)
457    {
458        *z = std::tan(*y);
459    }
460
461    struct user_defined_function {
462        ffrt_function_header_t header;
463        float* arg1; // 参数1
464        float* arg2; // 参数2
465    };
466
467    void cos_func_wrapper(void* header)
468    {
469        user_defined_function* func = (user_defined_function*)header;
470        cos_func(func->arg1, func->arg2);
471    }
472
473    void tan_func_wrapper(void* header)
474    {
475        user_defined_function* func = (user_defined_function*)header;
476        tan_func(func->arg1, func->arg2);
477    }
478
479    void destroy(void* header) {}
480
481    int main()
482    {
483        float x = 0.5f, y, z;
484
485        user_defined_function* func1 = (user_defined_function*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
486        func1->header.exec = cos_func_wrapper;
487        func1->header.destroy = destroy;
488        func1->arg1 = &x;
489        func1->arg2 = &y;
490
491        user_defined_function* func2 = (user_defined_function*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
492        func2->header.exec = tan_func_wrapper;
493        func2->header.destroy = destroy;
494        func2->arg1 = &y;
495        func2->arg2 = &z;
496
497        ffrt_dependence_t dependence_x[1];
498        dependence_x[0].type = ffrt_dependence_data;
499        dependence_x[0].ptr = &x;
500        ffrt_deps_t deps_x;
501        deps_x.len = 1;
502        deps_x.items = dependence_x;
503        ffrt_dependence_t dependence_y[1];
504        dependence_y[0].type = ffrt_dependence_data;
505        dependence_y[0].ptr = &y;
506        ffrt_deps_t deps_y;
507        deps_y.len = 1;
508        deps_y.items = dependence_y;
509        ffrt_dependence_t dependence_z[1];
510        dependence_z[0].type = ffrt_dependence_data;
511        dependence_z[0].ptr = &z;
512        ffrt_deps_t deps_z;
513        deps_z.len = 1;
514        deps_z.items = dependence_z;
515
516        ffrt_submit_base((ffrt_function_header_t*)func1, &deps_x, &deps_y, NULL);
517        ffrt_submit_base((ffrt_function_header_t*)func2, &deps_y, &deps_z, NULL);
518
519        ffrt_wait();
520        printf("x = %f, y = %f, z = %f\n", x, y, z);
521        return 0;
522    }
523    ```
524
525### ffrt_submit_h_base
526
527#### 声明
528
529```c
530typedef void* ffrt_task_handle_t;
531
532FFRT_C_API ffrt_task_handle_t ffrt_submit_h_base(ffrt_function_header_t* f, const ffrt_deps_t* in_deps, const ffrt_deps_t* out_deps, const ffrt_task_attr_t* attr);
533```
534
535#### 参数
536
537- `f`:用户的任务执行体,可以是原生的`ffrt_function_header_t`类型,也可以基于`ffrt_function_header_t`自定义拓展类型。
538- `in_deps`:任务的输入数据依赖。输入数据依赖通常以实际数据的地址表达,也支持`ffrt_task_handle_t`作为一种特殊输入依赖。
539- `out_deps`:任务的输出数据依赖。输出数据依赖通常以实际数据的地址表达,不支持`ffrt_task_handle_t`。
540- `attr`:任务的属性设置。
541
542#### 返回值
543
544- `ffrt_task_handle_t`任务的句柄。
545
546#### 描述
547
548相比于`ffrt_submit_base`接口,增加了任务句柄的返回值。
549
550#### 样例
551
552```c
553// 提交一个任务,获取任务句柄
554ffrt_function_header_t* func = (ffrt_function_header_t*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
555func->exec = foo;
556func->destroy = after_foo;
557ffrt_task_handle_t t = ffrt_submit_h_base(func, NULL, NULL, NULL);
558// 注意C API的ffrt_task_handle_t需要用户调用ffrt_task_handle_destroy显式销毁
559ffrt_task_handle_destroy(t);
560```
561
562### ffrt_task_handle_inc_ref
563
564#### 声明
565
566```c
567FFRT_C_API uint32_t ffrt_task_handle_inc_ref(ffrt_task_handle_t handle);
568```
569
570#### 参数
571
572- `handle`:任务句柄。
573
574#### 返回值
575
576- 任务的引用计数。
577
578#### 描述
579
580通过任务句柄增加对应任务的引用计数,每次调用引用计数加一。用于控制任务的生命周期使用,当引用计数不为零时,对应的任务资源不会被释放。注意`ffrt_submit_h_base`返回的`ffrt_task_handle_t`默认已有一个引用计数。通过`ffrt_task_handle_destroy`销毁`ffrt_task_handle_t`时默认减去一个引用计数。
581
582### ffrt_task_handle_dec_ref
583
584#### 声明
585
586```c
587FFRT_C_API uint32_t ffrt_task_handle_dec_ref(ffrt_task_handle_t handle);
588```
589
590#### 参数
591
592- `handle`:任务句柄。
593
594#### 返回值
595
596- 任务的引用计数。
597
598#### 描述
599
600通过任务句柄减去对应任务的引用计数,每次调用引用计数减一。
601
602### ffrt_task_handle_destroy
603
604#### 声明
605
606```c
607FFRT_C_API void ffrt_task_handle_destroy(ffrt_task_handle_t handle);
608```
609
610#### 参数
611
612- `handle`:任务句柄。
613
614#### 描述
615
616销毁任务句柄,同时默认减去一个任务引用计数。
617
618### ffrt_wait
619
620#### 声明
621
622```c
623FFRT_C_API void ffrt_wait(void);
624```
625
626#### 描述
627
628同步等待所有前序提交的同级任务完成。
629
630#### 样例
631
632```c
633// 同步三个任务完成
634ffrt_submit_base(func1, NULL, NULL, NULL);
635ffrt_submit_base(func2, NULL, NULL, NULL);
636ffrt_submit_base(func3, NULL, NULL, NULL);
637ffrt_wait();
638```
639
640### ffrt_wait_deps
641
642#### 声明
643
644```c
645FFRT_C_API void ffrt_wait_deps(const ffrt_deps_t* deps);
646```
647
648#### 参数
649
650- `deps`:需要同步的数据依赖。
651
652#### 描述
653
654同步对应的数据依赖解除。
655
656#### 样例
657
658```c
659// 构建x的数据依赖
660int x = 0;
661ffrt_dependence_t dependence[1];
662dependence[0].type = ffrt_dependence_data;
663dependence[0].ptr = &x;
664ffrt_deps_t deps;
665deps.len = 1;
666deps.items = dependence;
667
668// 提交一个写任务
669ffrt_submit_base(func, NULL, &deps, NULL);
670
671// 同步写任务解除数据依赖
672ffrt_wait_deps(&deps);
673```
674
675### ffrt_this_task_update_qos
676
677#### 声明
678
679```c
680FFRT_C_API int ffrt_this_task_update_qos(ffrt_qos_t qos);
681```
682
683#### 参数
684
685- `qos`:QoS等级。
686
687#### 返回值
688
689- 0表示成功,1表示失败。
690
691#### 描述
692
693在任务执行过程中,动态修改任务的QoS等级。注意该接口在任务的函数闭包内使用,修改的是当前正在执行的任务的QoS等级,接口调用会使任务先挂起一次再恢复执行。
694
695#### 样例
696
697```c
698// 一个qos_background的任务执行过程中动态修改QoS等级
699ffrt::submit([]() {
700    ...
701    int ret = ffrt_this_task_update_qos(ffrt_qos_user_initiated);
702    ...
703}, ffrt::task_attr().qos(ffrt::qos_background));
704```
705
706### ffrt_this_task_get_qos
707
708#### 声明
709
710```c
711FFRT_C_API ffrt_qos_t ffrt_this_task_get_qos(void);
712```
713
714#### 返回值
715
716- QoS等级。
717
718#### 描述
719
720获取当前正在执行任务的QoS等级。
721
722#### 样例
723
724```c
725// 一个任务执行过程中动态获取其QoS等级
726ffrt::submit([]() {
727    ...
728    // 获取的qos等于ffrt_qos_background
729    ffrt_qos_t qos = ffrt_this_task_get_qos();
730    ...
731}, ffrt::task_attr().qos(ffrt::qos_background));
732```
733
734### ffrt_this_task_get_id
735
736#### 声明
737
738```c
739FFRT_C_API uint64_t ffrt_this_task_get_id(void);
740```
741
742#### 返回值
743
744- 任务的id。
745
746#### 描述
747
748获取当前正在执行任务的id。
749
750#### 样例
751
752```c
753// 一个任务执行过程中动态获取其任务id
754ffrt::submit([]() {
755    ...
756    // 获取的唯一任务id
757    uint64_t task_id = ffrt_this_task_get_id();
758    ...
759}, ffrt::task_attr().qos(ffrt::qos_background));
760```
761
762## 任务队列
763
764### ffrt_queue_attr_t
765
766#### 声明
767
768```c
769typedef struct {
770    uint32_t storage[(ffrt_queue_attr_storage_size + sizeof(uint32_t) - 1) / sizeof(uint32_t)];
771} ffrt_queue_attr_t;
772```
773
774#### 描述
775
776用于配置队列的属性,如 QoS、超时时间、回调函数和最大并发数。
777
778#### 方法
779
780##### ffrt_queue_attr_init
781
782```c
783int ffrt_queue_attr_init(ffrt_queue_attr_t* attr)
784```
785
786参数
787
788- `attr`:队列属性指针。
789
790返回值
791
792- 返回0表示成功,其他值表示失败。
793
794描述
795
796- 初始化队列属性对象。
797
798##### ffrt_queue_attr_destroy
799
800```c
801void ffrt_queue_attr_destroy(ffrt_queue_attr_t* attr)
802```
803
804参数
805
806- `attr`:队列属性指针。
807
808描述
809
810- 销毁队列属性对象。
811
812##### ffrt_queue_attr_set_qos
813
814```c
815void ffrt_queue_attr_set_qos(ffrt_queue_attr_t* attr, ffrt_qos_t qos)
816```
817
818参数
819
820- `attr`:队列属性指针。
821- `qos`:QoS等级。
822
823描述
824
825- 设置队列的QoS等级。
826
827##### ffrt_queue_attr_get_qos
828
829```c
830ffrt_qos_t ffrt_queue_attr_get_qos(const ffrt_queue_attr_t* attr)
831```
832
833参数
834
835- `attr`:队列属性指针。
836
837返回值
838
839- 返回当前QoS等级。
840
841描述
842
843- 获取当前属性中设置的QoS等级。
844
845##### ffrt_queue_attr_set_timeout
846
847```c
848void ffrt_queue_attr_set_timeout(ffrt_queue_attr_t* attr, uint64_t timeout_us)
849```
850
851参数
852
853- `attr`:队列属性指针。
854- `timeout_us`:超时时间(微秒)。
855
856描述
857
858- 设置队列的超时时间(以微秒为单位)。
859
860##### ffrt_queue_attr_get_timeout
861
862```c
863uint64_t ffrt_queue_attr_get_timeout(const ffrt_queue_attr_t* attr)
864```
865
866参数
867
868- `attr`:队列属性指针。
869
870返回值
871
872- 返回当前超时阈值(微秒)。
873
874描述
875
876- 获取当前属性中设置的超时时间。
877
878##### ffrt_queue_attr_set_callback
879
880```c
881void ffrt_queue_attr_set_callback(ffrt_queue_attr_t* attr, ffrt_function_header_t* f)
882```
883
884参数
885
886- `attr`:队列属性指针。
887- `f`:是任务执行器的指针,描述了该CPU任务如何执行和销毁。
888
889描述
890
891- 设置检测到队列任务超时后执行的回调函数。
892
893##### ffrt_queue_attr_get_callback
894
895```c
896ffrt_function_header_t* ffrt_queue_attr_get_callback(const ffrt_queue_attr_t* attr)
897```
898
899参数
900
901- `attr`:队列属性指针。
902
903返回值
904
905- 返回任务执行器的指针,描述了该CPU任务如何执行和销毁。
906
907描述
908
909- 获取当前属性中设置的超时回调函数。
910
911##### ffrt_queue_attr_set_max_concurrency
912
913```c
914void ffrt_queue_attr_set_max_concurrency(ffrt_queue_attr_t* attr, const int max_concurrency)
915```
916
917参数
918
919- `attr`:队列属性指针。
920- `max_concurrency`:最大并发数。
921
922描述
923
924- 设置队列的最大并发数(仅支持并发队列)。
925
926##### ffrt_queue_attr_get_max_concurrency
927
928```c
929int ffrt_queue_attr_get_max_concurrency(const ffrt_queue_attr_t* attr)
930```
931
932参数
933
934- `attr`:队列属性指针。
935
936返回值
937
938- 返回当前最大并发数。
939
940描述
941
942- 获取当前属性中设置的最大并发数(仅支持并发队列)。
943
944#### 样例
945
946```c
947#include <stdio.h>
948#include "ffrt.h"
949
950using namespace ffrt;
951using namespace std;
952
953int main(int narg, char** argv)
954{
955    ffrt_queue_attr_t queue_attr;
956    // 初始化队列属性,必需
957    int result = ffrt_queue_attr_init(&queue_attr);
958
959    ffrt_queue_attr_set_qos(&queue_attr, static_cast<int>(ffrt_qos_utility));
960
961    ffrt_queue_attr_set_timeout(&queue_attr, 10000);
962
963    ffrt_queue_attr_set_callback(&queue_attr, ffrt::create_function_wrapper(basicFunc, ffrt_function_kind_queue));
964
965    int x = 0;
966    std::function<void()>&& basicFunc = [&x]() { x += 1; };
967    ffrt_function_header_t* func = ffrt_queue_attr_get_callback(&queue_attr);
968
969    // 销毁队列属性,必需
970    ffrt_queue_attr_destroy(&queue_attr);
971}
972```
973
974### ffrt_queue_t
975
976#### 声明
977
978```c
979typedef void* ffrt_queue_t;
980```
981
982#### 描述
983
984队列指针,提供一系列C接口支持队列任务的提交、取消、等待和排队任务数量查询。
985
986#### 方法
987
988##### ffrt_queue_create
989
990```c
991ffrt_queue_t ffrt_queue_create(ffrt_queue_type_t type, const char* name, const ffrt_queue_attr_t* attr)
992```
993
994参数
995
996- `type`:队列类型(如`ffrt_queue_serial`或`ffrt_queue_concurrent`)。
997- `name`:队列名称。
998- `attr`:队列属性。
999
1000返回值
1001
1002- `ffrt_queue_t`:成功则返回一个非空的队列句柄;否则返回空指针。
1003
1004描述
1005
1006- 创建指定类型和名称的队列。
1007
1008##### ffrt_queue_destroy
1009
1010```c
1011void ffrt_queue_destroy(ffrt_queue_t queue)
1012```
1013
1014参数
1015
1016- `queue`:队列的句柄。
1017
1018描述
1019
1020- 销毁一个队列。
1021
1022##### ffrt_queue_submit
1023
1024```c
1025void ffrt_queue_submit(ffrt_queue_t queue, ffrt_function_header_t* f, const ffrt_task_attr_t* attr)
1026```
1027
1028参数
1029
1030- `queue`:队列的句柄。
1031- `f`:任务执行器的指针,描述了该CPU任务如何执行和销毁。
1032- `attr`:任务属性。
1033
1034描述
1035
1036- 提交任务到队列中。
1037
1038##### ffrt_queue_submit_h
1039
1040```c
1041ffrt_task_handle_t ffrt_queue_submit_h(ffrt_queue_t queue, ffrt_function_header_t* f, const ffrt_task_attr_t* attr)
1042```
1043
1044参数
1045
1046- `queue`:队列的句柄。
1047- `f`:任务执行器的指针,描述了该CPU任务如何执行和销毁。
1048- `attr`:任务属性。
1049
1050返回值
1051
1052- `ffrt_task_handle_t`:成功则返回一个非空的任务句柄;否则返回空指针。
1053
1054描述
1055
1056- 提交任务到队列中,并返回任务句柄。
1057
1058##### ffrt_queue_wait
1059
1060```c
1061void ffrt_queue_wait(ffrt_task_handle_t handle)
1062```
1063
1064参数
1065
1066- `ffrt_task_handle_t`:任务句柄。
1067
1068描述
1069
1070- 等待一个队列任务完成。
1071
1072##### ffrt_queue_cancel
1073
1074```c
1075int ffrt_queue_cancel(ffrt_task_handle_t handle)
1076```
1077
1078参数
1079
1080- `ffrt_task_handle_t`:任务句柄。
1081
1082返回值
1083
1084- 返回0表示成功,其他值表示失败。
1085
1086描述
1087
1088- 取消一个队列任务。
1089
1090##### ffrt_get_main_queue
1091
1092```c
1093ffrt_queue_t ffrt_get_main_queue();
1094```
1095
1096返回值
1097
1098- 主线程队列。
1099
1100描述
1101
1102- 获取主线程队列,用于FFRT线程与主线程通信。
1103
1104##### ffrt_get_current_queue
1105
1106```c
1107ffrt_queue_t ffrt_get_current_queue();
1108```
1109
1110返回值
1111
1112- ArkTS Worker线程任务队列。
1113
1114描述
1115
1116- 此接口已于API 15版本后废弃,不建议继续使用。
1117- 获取ArkTS Worker线程队列,用于FFRT线程与ArkTS Worker线程通信。
1118
1119#### 样例
1120
1121```c
1122#include <stdio.h>
1123#include "ffrt.h"
1124
1125using namespace ffrt;
1126using namespace std;
1127
1128int main()
1129{
1130    ffrt_queue_attr_t queue_attr;
1131    // 1、初始化队列属性,必需
1132    (void)ffrt_queue_attr_init(&queue_attr);
1133
1134    // 2、创建串行队列,并返回队列句柄 queue_handle
1135    ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
1136
1137    int result = 0;
1138    std::function<void()>&& basicFunc = [&result]() { result += 1; };
1139
1140    // 3、提交串行任务
1141    ffrt_queue_submit(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), nullptr);
1142
1143    // 4、提交串行任务,并返回任务句柄
1144    ffrt_task_handle_t t1 = ffrt_queue_submit_h(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), nullptr);
1145    // 5、等待指定任务执行完成
1146    ffrt_queue_wait(t1);
1147
1148    ffrt_task_handle_t t2 = ffrt_queue_submit_h(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), nullptr);
1149    // 6、取消句柄为 t2 的任务
1150    int ret = ffrt_queue_cancel(t2);
1151
1152    // 7、销毁提交给串行队列任务的句柄 t1 和 t2,必需
1153    ffrt_task_handle_destroy(t1);
1154    ffrt_task_handle_destroy(t2);
1155    // 8、销毁队列属性,必需
1156    ffrt_queue_attr_destroy(&queue_attr);
1157    // 9、销毁队列句柄,必需
1158    ffrt_queue_destroy(queue_handle);
1159}
1160```
1161
1162## 同步原语
1163
1164### ffrt_mutexattr_t
1165
1166#### 声明
1167
1168```c
1169typedef enum {
1170    ffrt_error = -1,
1171    ffrt_success = 0,
1172    ffrt_error_nomem = ENOMEM,
1173    ffrt_error_timedout = ETIMEDOUT,
1174    ffrt_error_busy = EBUSY,
1175    ffrt_error_inval = EINVAL
1176} ffrt_error_t;
1177
1178typedef enum {
1179    ffrt_mutex_normal = 0,
1180    ffrt_mutex_recursive = 2,
1181    ffrt_mutex_default = ffrt_mutex_normal
1182} ffrt_mutex_type;
1183
1184struct ffrt_mutexattr_t;
1185
1186int ffrt_mutexattr_init(ffrt_mutexattr_t* attr);
1187int ffrt_mutexattr_settype(ffrt_mutexattr_t* attr, int type);
1188int ffrt_mutexattr_gettype(ffrt_mutexattr_t* attr, int* type);
1189int ffrt_mutexattr_destroy(ffrt_mutexattr_t* attr);
1190```
1191
1192#### 描述
1193
1194- FFRT提供的类似pthread mutexattr的性能实现。
1195
1196#### 方法
1197
1198##### ffrt_mutexattr_init
1199
1200```c
1201FFRT_C_API int ffrt_mutexattr_init(ffrt_mutexattr_t* attr);
1202```
1203
1204参数
1205
1206- `attr`:FFRT锁属性。
1207
1208返回值
1209
1210- `attr`不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。
1211
1212描述
1213
1214- 初始化`mutexattr`。
1215
1216##### ffrt_mutexattr_destroy
1217
1218```c
1219FFRT_C_API int ffrt_mutexattr_destroy(ffrt_mutexattr_t* attr);
1220```
1221
1222参数
1223
1224- `attr`:FFRT锁属性。
1225
1226返回值
1227
1228- `attr`不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。
1229
1230描述
1231
1232- 销毁mutexattr。
1233
1234##### ffrt_mutexattr_settype
1235
1236```c
1237FFRT_C_API int ffrt_mutexattr_settype(ffrt_mutexattr_t* attr, int type);
1238```
1239
1240参数
1241
1242- `attr`:FFRT锁属性。
1243- `type`:FFRT锁类型,当前仅支持互斥锁`ffrt_mutex_normal`和递归锁`ffrt_mutex_recursive`。
1244
1245返回值
1246
1247- `attr`不为空且`type`有效返回`ffrt_success`,否则返回`ffrt_error_inval`。
1248
1249描述
1250
1251- 设置FFRT锁属性。
1252
1253##### ffrt_mutexattr_gettype
1254
1255```c
1256FFRT_C_API int ffrt_mutexattr_gettype(ffrt_mutexattr_t* attr, int* type);
1257```
1258
1259参数
1260
1261- `attr`:FFRT锁属性。
1262- `type`:FFRT锁类型指针。
1263
1264返回值
1265
1266- `attr`和`type`均不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。
1267
1268描述
1269
1270- 获取FFRT锁属性。
1271
1272#### 样例
1273
1274```c
1275#include "ffrt.h"
1276
1277void ffrt_c_mutexattr_test()
1278{
1279    ffrt_mutexattr_t attr;
1280    ffrt_mutex_t recursive_mtx;
1281    EXPECT_EQ(ffrt_mutexattr_init(nullptr), ffrt_error_inval);
1282    EXPECT_EQ(ffrt_mutexattr_settype(nullptr, -1), ffrt_error_inval);
1283    EXPECT_EQ(ffrt_mutexattr_gettype(nullptr, nullptr), ffrt_error_inval);
1284    EXPECT_EQ(ffrt_mutexattr_destroy(nullptr), ffrt_error_inval);
1285}
1286```
1287
1288### ffrt_mutex_t
1289
1290- FFRT 提供的类似pthread mutex的性能实现,但不支持类似`PTHREAD_MUTEX_INITIALIZER`的初始化。
1291
1292#### 声明
1293
1294```c
1295typedef enum {
1296    ffrt_error = -1,
1297    ffrt_success = 0,
1298    ffrt_error_nomem = ENOMEM,
1299    ffrt_error_timedout = ETIMEDOUT,
1300    ffrt_error_busy = EBUSY,
1301    ffrt_error_inval = EINVAL
1302} ffrt_error_t;
1303
1304struct ffrt_mutex_t;
1305
1306struct ffrt_mutexattr_t;
1307
1308int ffrt_mutex_init(ffrt_mutex_t* mutex, const ffrt_mutexattr_t* attr);
1309int ffrt_mutex_lock(ffrt_mutex_t* mutex);
1310int ffrt_mutex_unlock(ffrt_mutex_t* mutex);
1311int ffrt_mutex_trylock(ffrt_mutex_t* mutex);
1312int ffrt_mutex_destroy(ffrt_mutex_t* mutex);
1313```
1314
1315#### 描述
1316
1317- 该接口支持在FFRT任务内部调用,也支持在FFRT任务外部调用。
1318- 该接口能够避免pthread传统的`pthread_mutex_t`在抢不到锁时陷入内核态的问题,在使用得当的条件下将会有更好的性能。
1319- C API 中的`ffrt_mutexattr_t`需要用户调用`ffrt_mutexattr_init`和`ffrt_mutexattr_destroy`显示创建和销毁,否则其行为是未定义的。
1320- C API 中的`ffrt_mutex_t`需要用户调用`ffrt_mutex_init`和`ffrt_mutex_destroy`显式创建和销毁,否则其行为是未定义的。
1321- C API 中的`ffrt_mutex_t`对象的置空和销毁由用户完成,对同一个`ffrt_mutex_t`仅能调用一次`ffrt_mutex_destroy`,重复对同一个 ffrt_mutex_t 调用`ffrt_mutex_destroy`,其行为是未定义的。
1322- C API 中的同一个`ffrt_mutexattr_t`只能调用一次`ffrt_mutexattr_init`和`ffrt_mutexattr_destroy`,重复调用其行为是未定义的。
1323- 用户需要在调用`ffrt_mutex_init`之后和调用`ffrt_mutex_destroy`之前显示调用`ffrt_mutexattr_destroy`。
1324- 在`ffrt_mutex_destroy`之后再对`ffrt_mutex_t`进行访问,其行为是未定义的。
1325
1326#### 方法
1327
1328##### ffrt_mutex_init
1329
1330```c
1331FFRT_C_API int ffrt_mutex_init(ffrt_mutex_t* mutex, const ffrt_mutexattr_t* attr);
1332```
1333
1334参数
1335
1336- `mutex`:指向所操作的锁指针。
1337- `attr`:FFRT锁属性,attr的有效值范围是:空指针或等于`ffrt_mutex_normal`代表互斥锁,`ffrt_mutex_recursive`代表递归锁。
1338
1339返回值
1340
1341- 如果`mutex`不为空且`attr`在有效值范围内返回`ffrt_success`,否则返回`ffrt_error_inval`。
1342
1343描述
1344
1345- 初始化FFRT锁。
1346
1347##### ffrt_mutex_destroy
1348
1349```c
1350FFRT_C_API int ffrt_mutex_destroy(ffrt_mutex_t* mutex);
1351```
1352
1353参数
1354
1355- `mutex`:指向所操作的锁指针。
1356
1357返回值
1358
1359- `mutex`不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。
1360
1361描述
1362
1363- 对指定的互斥锁/递归锁进行销毁操作。
1364
1365##### ffrt_mutex_lock
1366
1367```c
1368FFRT_C_API int ffrt_mutex_lock(ffrt_mutex_t* mutex);
1369```
1370
1371参数
1372
1373- `mutex`:指向所操作的锁指针。
1374
1375返回值
1376
1377- `mutex`不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。
1378
1379描述
1380
1381- 对指定的互斥锁/递归锁进行加锁操作,该方法会阻塞当前任务直到能成功获得锁。
1382
1383##### ffrt_mutex_unlock
1384
1385```c
1386FFRT_C_API int ffrt_mutex_unlock(ffrt_mutex_t* mutex);
1387```
1388
1389参数
1390
1391- `mutex`:指向所操作的锁指针。
1392
1393返回值
1394
1395- `mutex`不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。
1396
1397描述
1398
1399- 对指定的互斥锁/递归锁进行解锁操作。
1400
1401##### ffrt_mutex_trylock
1402
1403```c
1404FFRT_C_API int ffrt_mutex_trylock(ffrt_mutex_t* mutex);
1405```
1406
1407参数
1408
1409- `mutex`:指向所操作的锁指针。
1410
1411返回值
1412
1413- `mutex`为空返回ffrt_error_inval,`mutex`不为空且持锁成功返回`ffrt_success`,`mutex`不为空且持锁失败返回`ffrt_error_busy`。
1414
1415描述
1416
1417- 对指定的互斥锁/递归锁进行尝试加锁操作。
1418
1419#### 样例
1420
1421```c
1422#include "ffrt.h"
1423
1424void ffrt_c_mutex_test()
1425{
1426    ffrt_mutexattr_t attr;
1427    ffrt_mutex_t lock;
1428    int ret = 0;
1429    int sum = 0;
1430    int type = ffrt_mutex_default;
1431    ret = ffrt_mutexattr_init(&attr);
1432    EXPECT_EQ(ret, ffrt_success);
1433    ret = ffrt_mutexattr_settype(&attr, ffrt_mutex_recursive);
1434    EXPECT_EQ(ret, ffrt_success);
1435    ret = ffrt_mutexattr_gettype(&attr, &type);
1436    EXPECT_EQ(ret, ffrt_success);
1437    ret = ffrt_mutex_init(&lock, &attr);
1438    EXPECT_EQ(type, ffrt_mutex_recursive);
1439    ffrt::submit([&]() {
1440        ffrt_mutex_lock(&lock);
1441        EXPECT_EQ(ffrt_mutex_trylock(&lock), ffrt_success);
1442        sum++;
1443        ffrt_mutex_lock(&lock);
1444        EXPECT_EQ(ffrt_mutex_trylock(&lock), ffrt_success);
1445        sum++;
1446        ffrt_mutex_unlock(&lock);
1447        ffrt_mutex_unlock(&lock);
1448        ffrt_mutex_unlock(&lock);
1449        ffrt_mutex_unlock(&lock);
1450        }, {}, {});
1451
1452    ffrt::wait();
1453
1454    ffrt_mutexattr_destroy(&attr);
1455    ffrt_mutex_destroy(&lock);
1456}
1457```
1458
1459### ffrt_cond_t
1460
1461- FFRT提供的类似pthread信号量的性能实现,但不支持类似`PTHREAD_COND_INITIALIZER`的初始化。
1462
1463#### 声明
1464
1465```c
1466typedef enum {
1467    ffrt_error = -1,
1468    ffrt_success = 0,
1469    ffrt_error_nomem = ENOMEM,
1470    ffrt_error_timedout = ETIMEDOUT,
1471    ffrt_error_busy = EBUSY,
1472    ffrt_error_inval = EINVAL
1473} ffrt_error_t;
1474
1475typedef struct {
1476    uint32_t storage[(ffrt_cond_storage_size + sizeof(uint32_t) - 1) / sizeof(uint32_t)];
1477} ffrt_cond_t;
1478
1479int ffrt_cond_init(ffrt_cond_t* cond, const ffrt_condattr_t* attr);
1480int ffrt_cond_signal(ffrt_cond_t* cond);
1481int ffrt_cond_broadcast(ffrt_cond_t* cond);
1482int ffrt_cond_wait(ffrt_cond_t*cond, ffrt_mutex_t* mutex);
1483int ffrt_cond_timedwait(ffrt_cond_t* cond, ffrt_mutex_t* mutex, const struct timespec* time_point);
1484int ffrt_cond_destroy(ffrt_cond_t* cond);
1485```
1486
1487#### 描述
1488
1489- 该接口支持在FFRT任务内部调用,也支持在FFRT任务外部调用。
1490- 该功能能够避免传统的`pthread_cond_t`在条件不满足时陷入内核的问题,在使用得当的条件下将会有更好的性能。
1491- 注意:C API 中的`ffrt_cond_t`需要用户调用`ffrt_cond_init`和`ffrt_cond_destroy`显式创建和销毁,而C++ API 中依赖构造和析构自动完成。
1492- 注意:C API 中的`ffrt_cond_t`对象的置空和销毁由用户完成,对同一个`ffrt_cond_t`仅能调用一次`ffrt_cond_destroy`,重复对同一个`ffrt_cond_t`调用`ffrt_cond_destroy`,其行为是未定义的。
1493- 注意:在`ffrt_cond_destroy`之后再对`ffrt_cond_t`进行访问,其行为是未定义的。
1494
1495#### 方法
1496
1497##### ffrt_cond_init
1498
1499```c
1500FFRT_C_API int ffrt_cond_init(ffrt_cond_t* cond, const ffrt_condattr_t* attr);
1501```
1502
1503参数
1504
1505- `cond`:指向所操作的信号量的指针。
1506- `attr`:属性设定,空指针表示使用默认属性。
1507
1508返回值
1509
1510- `cond`不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。
1511
1512描述
1513
1514- 初始化FFRT条件变量。
1515
1516##### ffrt_cond_destroy
1517
1518```c
1519FFRT_C_API int ffrt_cond_destroy(ffrt_cond_t* cond);
1520```
1521
1522参数
1523
1524- `cond`:指向所操作的信号量的指针。
1525
1526返回值
1527
1528- `cond`不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。
1529
1530描述
1531
1532- 销毁FFRT条件变量。
1533
1534##### ffrt_cond_signal
1535
1536```c
1537FFRT_C_API int ffrt_cond_signal(ffrt_cond_t* cond);
1538```
1539
1540参数
1541
1542- `cond`:指向所操作的信号量的指针。
1543
1544返回值
1545
1546- `cond`不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。
1547
1548描述
1549
1550- 该方法用于唤醒一个等待条件变量的任务。
1551
1552##### ffrt_cond_broadcast
1553
1554```c
1555FFRT_C_API int ffrt_cond_broadcast(ffrt_cond_t* cond);
1556```
1557
1558参数
1559
1560- `cond`:指向所操作的信号量的指针。
1561
1562返回值
1563
1564- `cond`不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。
1565
1566描述
1567
1568- 该方法用于唤醒所有等待条件变量的任务。
1569
1570##### ffrt_cond_wait
1571
1572```c
1573FFRT_C_API int ffrt_cond_wait(ffrt_cond_t* cond, ffrt_mutex_t* mutex);
1574```
1575
1576参数
1577
1578- `cond`:指向所操作的信号量的指针。
1579- `mutex`:指向要在阻塞期间解锁的互斥锁的指针。
1580
1581返回值
1582
1583- `cond`和`mutex`均不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。
1584
1585描述
1586
1587- 方法用于在条件变量上等待。任务在调用该方法时会释放传入的互斥量,并进入等待状态,直到另一个任务通知条件变量,才会重新获取互斥量并继续执行。
1588- 此方法通常与`ffrt_mutex_lock`或`ffrt_mutex_trylock`一起使用,确保在进入等待状态之前已经持有互斥量。
1589
1590##### ffrt_cond_timedwait
1591
1592```c
1593FFRT_C_API int ffrt_cond_timedwait(ffrt_cond_t* cond, ffrt_mutex_t* mutex, const struct timespec* time_point);
1594```
1595
1596参数
1597
1598- `cond`:指向所操作的信号量的指针。
1599- `mutex`:指向要在阻塞期间解锁的互斥锁的指针。
1600- `time_point`:指向指定等待时限时间的对象的指针。
1601
1602返回值
1603
1604- `cond`和`mutex`和`time_point`均不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。
1605
1606描述
1607
1608- 该方法用于在条件变量上等待,直到指定的超时时间到达。
1609- 与`ffrt_cond_wait`不同,`ffrt_cond_timedwait`方法允许任务在条件变量上等待一段时间,如果在指定时间内没有收到通知,任务将被唤醒该函数返回。
1610
1611#### 样例
1612
1613```c
1614#include "ffrt.h"
1615
1616void ffrt_c_cond_test()
1617{
1618    int a = 0;
1619    ffrt_cond_t cond;
1620    ffrt_mutex_t lock_;
1621    ffrt_cond_init(&cond, nullptr);
1622    ffrt_mutex_init(&lock_, nullptr);
1623
1624    for (int i = 0; i < 3; i++) {
1625        ffrt::submit([&]() {
1626            int timeout = 2000;
1627            struct timespec tm = timeoutms_to_tm(timeout);
1628            ffrt_mutex_lock(&lock_);
1629            auto start = std::chrono::high_resolution_clock::now();
1630            int ret = ffrt_cond_timedwait(&cond, &lock_, &tm);
1631            auto end = std::chrono::high_resolution_clock::now();
1632            a = 123;
1633            ffrt_mutex_unlock(&lock_);
1634            std::chrono::duration<double, std::milli> elapsed = end-start;
1635            double t = elapsed.count();
1636            std::cout << "ffrt_cond_timedwait " << t << " ms\n";
1637            EXPECT_EQ(ret, ffrt_success);
1638            }, {}, {});
1639    }
1640
1641    ffrt::submit([&]() {
1642        ffrt_usleep(1000 * 1000);
1643        ffrt_mutex_lock(&lock_);
1644        a = 5;
1645        ffrt_cond_broadcast(&cond);
1646        ffrt_mutex_unlock(&lock_);
1647        }, {}, {});
1648    ffrt::wait();
1649    ffrt_cond_destroy(&cond);
1650    ffrt_mutex_destroy(&lock_);
1651    EXPECT_EQ(a, 123);
1652}
1653```
1654
1655## 阻塞原语
1656
1657### ffrt_usleep
1658
1659#### 声明
1660
1661```c
1662FFRT_C_API int ffrt_usleep(uint64_t usec);
1663```
1664
1665#### 参数
1666
1667- `usec`:睡眠的微秒数。
1668
1669#### 描述
1670
1671- FFRT提供的类似C11 sleep和Linux usleep的性能实现。
1672- 该接口只能在FFRT任务内部调用,在FFRT任务外部调用存在未定义的行为。
1673- 该接口睡眠精度为微秒。
1674- 该功能能够避免传统的`sleep`睡眠时陷入内核的问题,在使用得当的条件下将会有更好的性能。
1675
1676#### 样例
1677
1678```c
1679#include "ffrt.h"
1680
1681void ffrt_c_usleep_test()
1682{
1683    ffrt::submit([=]() { ffrt_usleep(10); }, {}, {});
1684    ffrt::wait();
1685}
1686```
1687
1688## 协同原语
1689
1690### ffrt_yield
1691
1692#### 声明
1693
1694```c
1695FFRT_C_API void ffrt_yield();
1696```
1697
1698#### 描述
1699
1700- 当前任务主动让出CPU执行资源,允许其他可执行的任务运行,如果没有其他可执行的任务,`yield`无效。
1701- 该接口只能在 FFRT任务内部调用,在FFRT任务外部调用存在未定义的行为。
1702- 此函数的确切行为取决于实现,特别是使用中的FFRT调度程序的机制和系统状态。
1703
1704#### 样例
1705
1706```c
1707#include "ffrt.h"
1708
1709void ffrt_c_yield_test()
1710{
1711    int count = 12;
1712    for (int i = 0; i < count; i++) {
1713        ffrt::submit(
1714            [&]() {
1715            ffrt_usleep(100);
1716            printf("test");
1717            ffrt_yield();
1718        },
1719            {}, {});
1720    }
1721    ffrt::wait();
1722}
1723```
1724
1725## 定时器
1726
1727### ffrt_timer_t
1728
1729#### 声明
1730
1731```c
1732typedef int ffrt_timer_t;
1733typedef void (*ffrt_timer_cb)(void* data);
1734```
1735
1736#### 描述
1737
1738提供定时器相关的功能。
1739
1740#### 方法
1741
1742##### ffrt_timer_start
1743
1744声明
1745
1746```c
1747FFRT_C_API ffrt_timer_t ffrt_timer_start(ffrt_qos_t qos, uint64_t timeout, void* data, ffrt_timer_cb cb, bool repeat);
1748```
1749
1750参数
1751
1752- `qos`:QoS等级。
1753- `timeout`:定时器时间,单位是毫秒。
1754- `cb`:到期后的回调函数。
1755- `data`:回调函数的输入参数。
1756- `repeat`:是否循环定时器。
1757
1758返回值
1759
1760- `ffrt_timer_t`定时器句柄。
1761
1762描述
1763
1764- 启动一个定时器,定时器到期且未被取消的话,执行回调函数。如果设置`repeat`为`true`,定时器到期后会重复设置。
1765
1766##### ffrt_timer_stop
1767
1768声明
1769
1770```c
1771FFRT_C_API int ffrt_timer_stop(ffrt_qos_t qos, ffrt_timer_t handle);
1772```
1773
1774参数
1775
1776- `qos`:QoS等级。
1777- `handle`:定时器句柄。
1778
1779返回值
1780
1781- 0表示成功,-1表示失败。
1782
1783描述
1784
1785- 取消一个定时器,和`ffrt_timer_start`配对使用。
1786
1787#### 样例
1788
1789- 样例1:使用单次定时器:
1790
1791    ```c
1792    #include <stdint.h>
1793    #include <unistd.h>
1794    #include "ffrt.h"
1795
1796    static void test_fun(void *data)
1797    {
1798        *(int *)data += 1;
1799    }
1800
1801    void (*cb)(void *) = test_fun;
1802
1803    int main(int narg, char** argv)
1804    {
1805        static int x = 0;
1806        void *data = &x;
1807        uint64_t timeout = 200;
1808        // 启动定时器,在200ms后执行回调函数
1809        int handle = ffrt_timer_start(ffrt_qos_default, timeout, data, cb, false);
1810        usleep(300000);
1811        // 定时器已经执行,取消无效
1812        ffrt_timer_stop(ffrt_qos_default, handle);
1813        printf("data: %d\n", x); // x值变成1
1814        return 0;
1815    }
1816    ```
1817
1818- 样例2:使用循环定时器:
1819
1820    ```c
1821    #include <stdint.h>
1822    #include <unistd.h>
1823    #include "ffrt.h"
1824
1825    static void test_fun(void *data)
1826    {
1827        *(int *)data += 1;
1828    }
1829
1830    void (*cb)(void *) = test_fun;
1831
1832    int main(int narg, char** argv)
1833    {
1834        static int x = 0;
1835        void *data = &x;
1836        uint64_t timeout = 200;
1837        // 启动循环定时器,每间隔200ms执行回调函数
1838        int handle = ffrt_timer_start(ffrt_qos_default, timeout, data, cb, true);
1839        usleep(500000);
1840        // 取消循环定时器
1841        ffrt_timer_stop(ffrt_qos_default, handle);
1842        printf("data: %d\n", x); // x的值变成2
1843        return 0;
1844    }
1845    ```
1846
1847## 循环
1848
1849### ffrt_loop_t
1850
1851#### 声明
1852
1853```c
1854typedef void* ffrt_loop_t;
1855```
1856
1857#### 描述
1858
1859提供循环相关的功能。
1860
1861#### 方法
1862
1863##### ffrt_loop_create
1864
1865声明
1866
1867```c
1868FFRT_C_API ffrt_loop_t ffrt_loop_create(ffrt_queue_t queue);
1869```
1870
1871参数
1872
1873- `queue`:loop需要绑定一个FFRT并发队列使用。
1874
1875返回值
1876
1877- `ffrt_loop_t`对象。
1878
1879描述
1880
1881- 创建一个loop,需要绑定一个并发队列存储任务,用户可以向队列中提交任务使其在loop中执行。
1882
1883##### ffrt_loop_destroy
1884
1885声明
1886
1887```c
1888FFRT_C_API int ffrt_loop_destroy(ffrt_loop_t loop);
1889```
1890
1891参数
1892
1893- `loop`:loop对象。
1894
1895返回值
1896
1897- 0表示成功,-1表示失败。
1898
1899描述
1900
1901- 销毁一个loop,同时和队列解除绑定。
1902
1903##### ffrt_loop_run
1904
1905声明
1906
1907```c
1908FFRT_C_API int ffrt_loop_run(ffrt_loop_t loop);
1909```
1910
1911参数
1912
1913- `loop`:loop对象。
1914
1915返回值
1916
1917- 0表示成功,-1表示失败。
1918
1919描述
1920
1921- 启动一个loop,调用此方法的线程会同步执行loop,在loop中会执行队列的任务、监听poller事件触发、监听timer定时器触发。
1922
1923##### ffrt_loop_stop
1924
1925声明
1926
1927```c
1928FFRT_C_API void ffrt_loop_stop(ffrt_loop_t loop);
1929```
1930
1931参数
1932
1933- `loop`:loop对象。
1934
1935描述
1936
1937- 停止一个loop,调用此方法使执行loop的线程退出循环。
1938
1939##### ffrt_loop_epoll_ctl
1940
1941声明
1942
1943```c
1944int ffrt_loop_epoll_ctl(ffrt_loop_t loop, int op, int fd, uint32_t events, void *data, ffrt_poller_cb cb)
1945```
1946
1947参数
1948
1949- `loop`:loop对象。
1950- `op`:fd操作符,参考epoll_ctl的操作类型。
1951- `fd`:事件描述符。
1952- `events`:事件,参考epoll_ctl的事件类型。
1953- `data`:回调函数的入参。
1954- `cb`:回调函数。
1955
1956返回值
1957
1958- 0表示成功,-1表示失败。
1959
1960描述
1961
1962- 管理loop上的监听fd事件,事件的监听和回调执行在loop线程上处理。
1963
1964##### ffrt_loop_timer_start
1965
1966声明
1967
1968```c
1969FFRT_C_API ffrt_timer_t ffrt_loop_timer_start(ffrt_loop_t loop, uint64_t timeout, void* data, ffrt_timer_cb cb, bool repeat);
1970```
1971
1972参数
1973
1974- `loop`:loop对象。
1975- `timeout`:定时器时间,单位是毫秒。
1976- `cb`:到期后的回调函数。
1977- `data`:回调函数的输入参数。
1978- `repeat`:是否循环定时器。
1979
1980返回值
1981
1982- `ffrt_timer_t`定时器句柄。
1983
1984描述
1985
1986- 在loop上启动一个定时器,用法和`ffrt_timer_start`一致,只是定时器的监听和回调执行在loop线程上处理。
1987
1988##### ffrt_loop_timer_stop
1989
1990声明
1991
1992```c
1993FFRT_C_API int ffrt_loop_timer_stop(ffrt_loop_t loop, ffrt_timer_t handle);
1994```
1995
1996参数
1997
1998- `loop`:loop对象。
1999- `handle`:定时器句柄。
2000
2001返回值
2002
2003- 0表示成功,-1表示失败。
2004
2005描述
2006
2007- 取消一个定时器,用法和`ffrt_timer_stop`一致。
2008
2009#### 样例
2010
2011- 样例1:循环与并发队列:
2012
2013    ```c
2014    #include <pthread.h>
2015    #include <unistd.h>
2016    #include <stdio.h>
2017    #include "c/loop.h"
2018
2019    void* ThreadFunc(void* p)
2020    {
2021        int ret = ffrt_loop_run(p);
2022        if (ret == 0) {
2023            printf("loop normal operation.");
2024        }
2025        return nullptr;
2026    }
2027
2028    int main(int narg, char** argv)
2029    {
2030        // 创建并发队列
2031        ffrt_queue_attr_t queue_attr;
2032        (void)ffrt_queue_attr_init(&queue_attr);
2033        ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_concurrent, "test_queue", &queue_attr);
2034
2035        // 创建loop
2036        auto loop = ffrt_loop_create(queue_handle);
2037
2038        // 启动独立线程来执行loop
2039        pthread_t thread;
2040        pthread_create(&thread, 0, ThreadFunc, loop);
2041
2042        // 终止并销毁loop
2043        ffrt_loop_stop(loop);
2044        int ret = ffrt_loop_destroy(loop);
2045
2046        // 销毁并发队列
2047        ffrt_queue_attr_destroy(&queue_attr);
2048        ffrt_queue_destroy(queue_handle);
2049        return 0;
2050    }
2051    ```
2052
2053- 样例2:循环、并发队列和定时器:
2054
2055    ```c
2056    #include <pthread.h>
2057    #include <unistd.h>
2058    #include <stdio.h>
2059    #include <functional>
2060    #include <sys/epoll.h>
2061    #include <sys/eventfd.h>
2062    #include "c/loop.h"
2063    #include "ffrt.h"
2064
2065    void* ThreadFunc(void* p)
2066    {
2067        int ret = ffrt_loop_run(p);
2068        return nullptr;
2069    }
2070
2071    static void test_fun(void* data)
2072    {
2073        *(int*)data += 1;
2074    }
2075
2076    static void (*cb)(void*) = test_fun;
2077
2078    void testCallBack(void *data, unsigned int events) {}
2079
2080    struct TestData {
2081        int fd;
2082        uint64_t expected;
2083    };
2084
2085    int main(int narg, char** argv)
2086    {
2087        // 创建并发队列
2088        ffrt_queue_attr_t queue_attr;
2089        (void)ffrt_queue_attr_init(&queue_attr);
2090        ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_concurrent, "test_queue", &queue_attr);
2091
2092        // 创建loop
2093        auto loop = ffrt_loop_create(queue_handle);
2094        int result1 = 0;
2095
2096        // 向loop队列提交一个任务
2097        std::function<void()> &&basicFunc1 = [&result1]() {result1 += 10;};
2098        ffrt_task_handle_t task1 = ffrt_queue_submit_h(queue_handle, ffrt::create_function_wrapper(basicFunc1, ffrt_function_kind_queue), nullptr);
2099
2100        // 启动独立线程来执行loop
2101        pthread_t thread;
2102        pthread_create(&thread, 0, ThreadFunc, loop);
2103
2104        static int x = 0;
2105        int* xf = &x;
2106        void* data = xf;
2107        uint64_t timeout1 = 20;
2108        uint64_t timeout2 = 10;
2109        uint64_t expected = 0xabacadae;
2110
2111        int testFd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
2112        struct TestData testData {.fd = testFd, .expected = expected};
2113
2114        // 向loop注册一个定时器
2115        ffrt_timer_t timeHandle = ffrt_loop_timer_start(loop, timeout1, data, cb, false);
2116
2117        // 向loop注册一个fd监听
2118        int ret = ffrt_loop_epoll_ctl(loop, EPOLL_CTL_ADD, testFd, EPOLLIN, (void*)(&testData), testCallBack);
2119        if (ret == 0) {
2120            printf("ffrt_loop_epoll_ctl执行成功。\n");
2121        }
2122        ssize_t n = write(testFd, &expected, sizeof(uint64_t));
2123        usleep(25000);
2124        // 删除fd监听
2125        ffrt_loop_epoll_ctl(loop, EPOLL_CTL_DEL, testFd, 0, nullptr, nullptr);
2126
2127        // 终止loop
2128        ffrt_loop_stop(loop);
2129        pthread_join(thread, nullptr);
2130
2131        // 删除定时器
2132        ffrt_loop_timer_stop(loop, timeHandle);
2133
2134        // 销毁loop
2135        ret = ffrt_loop_destroy(loop);
2136
2137        // 销毁并发队列
2138        ffrt_queue_attr_destroy(&queue_attr);
2139        ffrt_queue_destroy(queue_handle);
2140        return 0;
2141    }
2142    ```
2143