• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Function Flow Runtime C APIs
2
3<!--Kit: Function Flow Runtime Kit-->
4<!--Subsystem: Resourceschedule-->
5<!--Owner: @chuchihtung; @yanleo-->
6<!--Designer: @geoffrey_guo; @huangyouzhong-->
7<!--Tester: @lotsof; @sunxuhao-->
8<!--Adviser: @foryourself-->
9
10## Task Management
11
12### ffrt_deps_t
13
14**Declaration**
15
16```c
17typedef enum {
18    ffrt_dependence_data,
19    ffrt_dependence_task,
20} ffrt_dependence_type_t;
21
22typedef struct {
23    ffrt_dependence_type_t type;
24    const void* ptr;
25} ffrt_dependence_t;
26
27typedef struct {
28    uint32_t len;
29    const ffrt_dependence_t* items;
30} ffrt_deps_t;
31```
32
33**Parameters**
34
35- `len`: number of data dependencies.
36- `items`: data dependency array. The data length is equal to `len`.
37- `ptr`: data address.
38- `type`: data type. It is different from `task_handle`.
39
40**Description**
41
42The function of `ffrt_dependence_t` is the same as that of `dependence` in C++, and the function of `ffrt_deps_t` is the same as that of `std::vector<dependence>` in C++.
43
44**Example**
45
46```c
47// Create a data dependency.
48int x = 0;
49ffrt_dependence_t data_dependence[1];
50data_dependence[0].type = ffrt_dependence_data;
51data_dependence[0].ptr = &x;
52ffrt_deps_t data_deps;
53data_deps.len = 1;
54data_deps.items = data_dependence;
55
56// Create a task dependency.
57ffrt_task_handle_t task = ffrt_submit_h_base(user_function_header, NULL, NULL, &attr);
58ffrt_dependence_t task_dependence[1];
59task_dependence[0].type = ffrt_dependence_task;
60task_dependence[0].ptr = task;
61ffrt_deps_t task_deps;
62task_deps.len = 1;
63task_deps.items = task_dependence;
64```
65
66### ffrt_task_attr_t
67
68**Declaration**
69
70```c
71typedef struct {
72    uint32_t storage[(ffrt_task_attr_storage_size + sizeof(uint32_t) - 1) / sizeof(uint32_t)];
73} ffrt_task_attr_t;
74```
75
76**Description**
77
78Describes the task attribute, which can be configured using `ffrt_task_attr_t` when submitting a common task or queue task.
79
80**Methods**
81
82**ffrt_task_attr_init**
83
84```c
85FFRT_C_API int ffrt_task_attr_init(ffrt_task_attr_t* attr);
86```
87
88Parameters
89
90- `attr`: pointer to the `ffrt_task_attr_t` object.
91
92Return Values
93
94- The value **0** indicates success, and the value **-1** indicates failure.
95
96Description
97
98- Initializes an `ffrt_task_attr_t` object.
99
100**ffrt_task_attr_destroy**
101
102```c
103FFRT_C_API void ffrt_task_attr_destroy(ffrt_task_attr_t* attr);
104```
105
106Parameters
107
108- `attr`: pointer to the `ffrt_task_attr_t` object.
109
110Description
111
112- Destroys an `ffrt_task_attr_t` object.
113
114**ffrt_task_attr_set_name**
115
116```c
117FFRT_C_API void ffrt_task_attr_set_name(ffrt_task_attr_t* attr, const char* name);
118```
119
120Parameters
121
122- `attr`: pointer to the `ffrt_task_attr_t` object.
123- `name`: task name.
124
125Description
126
127- Sets the task name, which is valid for printing maintenance and test information.
128
129**ffrt_task_attr_get_name**
130
131```c
132FFRT_C_API const char* ffrt_task_attr_get_name(const ffrt_task_attr_t* attr);
133```
134
135Parameters
136
137- `attr`: pointer to the `ffrt_task_attr_t` object.
138
139Return Values
140
141- Task name.
142
143Description
144
145- Obtains the task name.
146
147**ffrt_task_attr_set_qos**
148
149```c
150FFRT_C_API void ffrt_task_attr_set_qos(ffrt_task_attr_t* attr, ffrt_qos_t qos);
151```
152
153Parameters
154
155- `attr`: pointer to the `ffrt_task_attr_t` object.
156- `qos`: QoS.
157
158Description
159
160- Sets the task QoS, which determines the system resource supply during task execution. If QoS is not set, the queue QoS is inherited by default. The default QoS of a common task is `ffrt_qos_default`.
161
162**ffrt_task_attr_get_qos**
163
164```c
165FFRT_C_API ffrt_qos_t ffrt_task_attr_get_qos(const ffrt_task_attr_t* attr);
166```
167
168Parameters
169
170- `attr`: pointer to the `ffrt_task_attr_t` object.
171
172Return Values
173
174- QoS.
175
176Description
177
178- Obtains the configured QoS.
179
180**ffrt_task_attr_set_delay**
181
182```c
183FFRT_C_API void ffrt_task_attr_set_delay(ffrt_task_attr_t* attr, uint64_t delay_us);
184```
185
186Parameters
187
188- `attr`: pointer to the `ffrt_task_attr_t` object.
189- `delay_us`: scheduling delay. The unit is μs.
190
191Description
192
193- Sets the scheduling delay of a task. The task is scheduled and executed after the delay interval. If delay is not set, the value is **0** by default.
194
195**ffrt_task_attr_get_delay**
196
197```c
198FFRT_C_API uint64_t ffrt_task_attr_get_delay(const ffrt_task_attr_t* attr);
199```
200
201Parameters
202
203- `attr`: pointer to the `ffrt_task_attr_t` object.
204
205Return Values
206
207- Scheduling delay.
208
209Description
210
211- Obtains the configured scheduling delay.
212
213**ffrt_task_attr_set_queue_priority**
214
215```c
216FFRT_C_API void ffrt_task_attr_set_queue_priority(ffrt_task_attr_t* attr, ffrt_queue_priority_t priority);
217```
218
219Parameters
220
221- `attr`: pointer to the `ffrt_task_attr_t` object.
222- `priority`: task priority.
223
224Description
225
226- Sets the task priority. Currently, only concurrent queue tasks support the priority function. Tasks in the same concurrent queue are scheduled based on their priorities. If the priority is not set, `ffrt_queue_priority_low` is used by default.
227
228**ffrt_task_attr_get_queue_priority**
229
230```c
231FFRT_C_API ffrt_queue_priority_t ffrt_task_attr_get_queue_priority(const ffrt_task_attr_t* attr);
232```
233
234Parameters
235
236- `attr`: pointer to the `ffrt_task_attr_t` object.
237
238Return Values
239
240- Task priority.
241
242Description
243
244- Obtains the configured priority.
245
246**ffrt_task_attr_set_stack_size**
247
248```c
249FFRT_C_API void ffrt_task_attr_set_stack_size(ffrt_task_attr_t* attr, uint64_t size);
250```
251
252Parameters
253
254- `attr`: pointer to the `ffrt_task_attr_t` object.
255- `size`: size of the coroutine stack, in bytes.
256
257Description
258
259- Sets the size of the coroutine stack, which affects the maximum space used by the call stack during task execution. If this parameter is not set, the default size of the coroutine stack is 1 MB.
260
261**ffrt_task_attr_get_stack_size**
262
263```c
264FFRT_C_API uint64_t ffrt_task_attr_get_stack_size(const ffrt_task_attr_t* attr);
265```
266
267Parameters
268
269- `attr`: pointer to the `ffrt_task_attr_t` object.
270
271Return Values
272
273- Size of the coroutine stack.
274
275Description
276
277- Obtains the size of the coroutine stack.
278
279**Example**
280
281```c
282// Submit a common task. The task name is sample_task, the QoS is background, the scheduling delay is 1 ms, and the coroutine stack size is 2 MB.
283ffrt_task_attr_t attr;
284ffrt_task_attr_init(&attr);
285ffrt_task_attr_set_name(&attr, "sample_task");
286ffrt_task_attr_set_qos(&attr, ffrt_qos_background);
287ffrt_task_attr_set_delay(&attr, 1000);
288ffrt_task_attr_set_stack_size(&attr, 2 * 1024 * 1024);
289ffrt_submit_base(user_function_header, NULL, NULL, &attr);
290ffrt_task_attr_destroy(&attr);
291```
292
293### ffrt_alloc_auto_managed_function_storage_base
294
295**Declaration**
296
297```c
298typedef enum {
299    ffrt_function_kind_general,
300    ffrt_function_kind_queue,
301} ffrt_function_kind_t;
302
303typedef void(*ffrt_function_t)(void*);
304typedef struct {
305    ffrt_function_t exec;
306    ffrt_function_t destroy;
307    uint64_t reserve[2];
308} ffrt_function_header_t;
309
310FFRT_C_API void *ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_t kind);
311```
312
313**Parameters**
314
315- `kind`: `ffrt_function_kind_general` for submitting a common task; `ffrt_function_kind_queue` for submitting a queue task.
316- `exec`: function pointer invoked during task execution.
317- `destroy`: function pointer invoked after a task is complete. It can be used to destroy resources.
318- `reserve`: internal reserved space. It cannot be used by users.
319
320**Return Values**
321
322- Pointer to the executor of the user task.
323
324**Description**
325
326Allocates memory space. The header of the memory space is in the `ffrt_function_header_t` structure. The return pointer can be converted into the `ffrt_function_header_t*` pointer. A 64-byte space is reserved after the header for customizing the space for storing input parameters or return values.
327
328**Example**
329
330- Example 1: Generate a task executor without parameters and return values.
331
332    ```c
333    #include <stdio.h>
334    #include "ffrt/task.h"
335
336    void foo(void* data)
337    {
338        printf("foo\n");
339    }
340
341    void after_foo(void* data)
342    {
343        printf("after_foo\n");
344    }
345
346    int main()
347    {
348        ffrt_function_header_t* func = (ffrt_function_header_t*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
349
350        func->exec = foo;
351        func->destroy = after_foo;
352
353        ffrt_submit_base(func, NULL, NULL, NULL);
354        ffrt_wait();
355
356        return 0;
357    }
358    ```
359
360- Example 2: Generate a task executor with parameters and return values.
361
362    ```c
363    #include <stdio.h>
364    #include "ffrt/task.h"
365
366    int foo(int x, int y)
367    {
368        printf("foo: x = %d, y = %d\n", x, y);
369        return x + y;
370    }
371
372    void after_foo(void* data)
373    {
374        printf("after_foo\n");
375    }
376
377    // Custom task executor, which can carry parameters and return values.
378    typedef struct {
379        ffrt_function_header_t header; // The header space is ffrt_function_header_t.
380        int arg1; // Argument 1
381        int arg2; // Argument 2
382        int ret; // Return value
383    } user_defined_function;
384
385    // Wrap foo into the exec function type of void(*)(void*).
386    void exec_func_wrapper(void* header)
387    {
388        user_defined_function* func = (user_defined_function*)header;
389        func->ret = foo(func->arg1, func->arg2); // Expand the foo function, pass arguments, and obtain the return value.
390    }
391
392    int main()
393    {
394        user_defined_function* func = (user_defined_function*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
395
396        func->header.exec = exec_func_wrapper;
397        func->header.destroy = after_foo;
398        func->arg1 = 1;
399        func->arg2 = 2;
400
401        ffrt_submit_base((ffrt_function_header_t*)func, NULL, NULL, NULL);
402        ffrt_wait();
403
404        printf("ret = %d\n", func->ret);
405        return 0;
406    }
407    ```
408
409### ffrt_submit_base
410
411**Declaration**
412
413```c
414FFRT_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);
415```
416
417**Parameters**
418
419- `f`: task executor of a user. The value can be of the native `ffrt_function_header_t` type or a custom extension type based on `ffrt_function_header_t`.
420- `in_deps`: input data dependency of a task. It is usually expressed as the actual data address. `ffrt_task_handle_t` can also be used as a special input dependency.
421- `out_deps`: output data dependency of a task. It is usually expressed as the actual data address. `ffrt_task_handle_t` is not supported.
422- `attr`: task attribute.
423
424**Description**
425
426Submits a common task that supports attribute settings. After the input dependency is removed, the task can be scheduled and executed. After the task is executed, the output dependency is removed.
427
428**Example**
429
430- Example 1: Submit a task with attributes.
431
432    ```c
433    #include <stdio.h>
434    #include "ffrt/task.h"
435
436    void foo(void* data)
437    {
438        printf("foo\n");
439    }
440
441    void after_foo(void* data)
442    {
443        printf("after_foo\n");
444    }
445
446    int main()
447    {
448        // Submit a task.
449        ffrt_function_header_t* func = (ffrt_function_header_t*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
450        func->exec = foo;
451        func->destroy = after_foo;
452        ffrt_submit_base(func, NULL, NULL, NULL);
453
454        // Submit a task with attributes.
455        ffrt_task_attr_t attr;
456        ffrt_task_attr_init(&attr);
457        ffrt_task_attr_set_name(&attr, "sample_task");
458        ffrt_task_attr_set_qos(&attr, ffrt_qos_background);
459        ffrt_submit_base(func, NULL, NULL, &attr);
460
461        return 0;
462    }
463    ```
464
465- Example 2: Submit a task with data dependency.
466
467    ```c
468    // Submit two tasks with data dependency. The Read-After-Write dependency exists between tasks.
469    #include <math.h>
470    #include <stdio.h>
471    #include "ffrt/task.h"
472
473    void cos_func(float* x, float* y)
474    {
475        *y = cos(*x);
476    }
477
478    void tan_func(float* y, float* z)
479    {
480        *z = tan(*y);
481    }
482
483    typedef struct {
484        ffrt_function_header_t header;
485        float* arg1; // Argument 1
486        float* arg2; // Argument 2
487    } user_defined_function;
488
489    void cos_func_wrapper(void* header)
490    {
491        user_defined_function* func = (user_defined_function*)header;
492        cos_func(func->arg1, func->arg2);
493    }
494
495    void tan_func_wrapper(void* header)
496    {
497        user_defined_function* func = (user_defined_function*)header;
498        tan_func(func->arg1, func->arg2);
499    }
500
501    void destroy(void* header) {}
502
503    int main()
504    {
505        float x = 0.5f, y, z;
506
507        user_defined_function* func1 = (user_defined_function*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
508        func1->header.exec = cos_func_wrapper;
509        func1->header.destroy = destroy;
510        func1->arg1 = &x;
511        func1->arg2 = &y;
512
513        user_defined_function* func2 = (user_defined_function*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
514        func2->header.exec = tan_func_wrapper;
515        func2->header.destroy = destroy;
516        func2->arg1 = &y;
517        func2->arg2 = &z;
518
519        ffrt_dependence_t dependence_x[1];
520        dependence_x[0].type = ffrt_dependence_data;
521        dependence_x[0].ptr = &x;
522        ffrt_deps_t deps_x;
523        deps_x.len = 1;
524        deps_x.items = dependence_x;
525        ffrt_dependence_t dependence_y[1];
526        dependence_y[0].type = ffrt_dependence_data;
527        dependence_y[0].ptr = &y;
528        ffrt_deps_t deps_y;
529        deps_y.len = 1;
530        deps_y.items = dependence_y;
531        ffrt_dependence_t dependence_z[1];
532        dependence_z[0].type = ffrt_dependence_data;
533        dependence_z[0].ptr = &z;
534        ffrt_deps_t deps_z;
535        deps_z.len = 1;
536        deps_z.items = dependence_z;
537
538        ffrt_submit_base((ffrt_function_header_t*)func1, &deps_x, &deps_y, NULL);
539        ffrt_submit_base((ffrt_function_header_t*)func2, &deps_y, &deps_z, NULL);
540
541        ffrt_wait();
542        printf("x = %f, y = %f, z = %f\n", x, y, z);
543        return 0;
544    }
545    ```
546
547### ffrt_submit_f
548
549**Declaration**
550
551```c
552FFRT_C_API void ffrt_submit_f(ffrt_function_t func, void* arg, const ffrt_deps_t* in_deps, const ffrt_deps_t* out_deps, const ffrt_task_attr_t* attr);
553```
554
555**Parameters**
556
557- `func`: specified task function.
558- `arg`: parameter passed to the task function.
559- `in_deps`: input data dependency of a task. It is usually expressed as the actual data address. `ffrt_task_handle_t` can also be used as a special input dependency.
560- `out_deps`: output data dependency of a task. It is usually expressed as the actual data address. `ffrt_task_handle_t` is not supported.
561- `attr`: task attribute.
562
563**Description**
564
565`ffrt_submit_f` is a simplified form of `ffrt_submit_base`. When the callback function does not need to be destroyed, the API packages the task function and its parameters into a common task structure. Then, `ffrt_submit_base` is called to submit the task.
566
567**Example**
568
569```cpp
570#include <stdio.h>
571#include "ffrt/task.h"
572
573// Function to be submitted for execution.
574void OnePlusForTest(void* arg)
575{
576    (*static_cast<int*>(arg)) += 1;
577}
578
579int main()
580{
581    int a = 0;
582    ffrt_submit_f(OnePlusForTest, &a, NULL, NULL, NULL);
583
584    ffrt_wait();
585
586    printf("a = %d\n", a);
587    return 0;
588}
589```
590
591### ffrt_submit_h_base
592
593**Declaration**
594
595```c
596typedef void* ffrt_task_handle_t;
597
598FFRT_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);
599```
600
601**Parameters**
602
603- `f`: task executor of a user. The value can be of the native `ffrt_function_header_t` type or a custom extension type based on `ffrt_function_header_t`.
604- `in_deps`: input data dependency of a task. It is usually expressed as the actual data address. `ffrt_task_handle_t` can also be used as a special input dependency.
605- `out_deps`: output data dependency of a task. It is usually expressed as the actual data address. `ffrt_task_handle_t` is not supported.
606- `attr`: task attribute.
607
608**Return Values**
609
610- `ffrt_task_handle_t` task handle.
611
612**Description**
613
614Compared with the `ffrt_submit_base` API, the return value of the task handle is added.
615
616**Example**
617
618```c
619// Submit a task and obtain the task handle.
620ffrt_function_header_t* func = (ffrt_function_header_t*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
621func->exec = foo;
622func->destroy = after_foo;
623ffrt_task_handle_t t = ffrt_submit_h_base(func, NULL, NULL, NULL);
624// Note that ffrt_task_handle_t of the C API needs to be explicitly destroyed by calling ffrt_task_handle_destroy.
625ffrt_task_handle_destroy(t);
626```
627
628### ffrt_submit_h_f
629
630**Declaration**
631
632```c
633typedef void* ffrt_task_handle_t;
634
635FFRT_C_API ffrt_task_handle_t ffrt_submit_h_f(ffrt_function_t func, void* arg, const ffrt_deps_t* in_deps, const ffrt_deps_t* out_deps, const ffrt_task_attr_t* attr);
636```
637
638**Parameters**
639
640- `func`: specified task function.
641- `arg`: parameter passed to the task function.
642- `in_deps`: input data dependency of a task. It is usually expressed as the actual data address. `ffrt_task_handle_t` can also be used as a special input dependency.
643- `out_deps`: output data dependency of a task. It is usually expressed as the actual data address. `ffrt_task_handle_t` is not supported.
644- `attr`: task attribute.
645
646**Return Values**
647
648- `ffrt_task_handle_t` task handle.
649
650**Description**
651
652Adds the return value of the task handle compared with `ffrt_submit_f`.
653
654**Example**
655
656```cpp
657#include <stdio.h>
658#include <vector>
659#include "ffrt/task.h"
660
661// Function to be submitted for execution.
662void OnePlusForTest(void* arg)
663{
664    (*static_cast<int*>(arg)) += 1;
665}
666
667int main()
668{
669    int a = 0;
670    ffrt_task_handle_t task = ffrt_submit_h_f(OnePlusForTest, &a, NULL, NULL, NULL);
671
672    const std::vector<ffrt_dependence_t> wait_deps = {{ffrt_dependence_task, task}};
673    ffrt_deps_t wait{static_cast<uint32_t>(wait_deps.size()), wait_deps.data()};
674    ffrt_wait_deps(&wait);
675
676    printf("a = %d\n", a);
677    return 0;
678}
679```
680
681### ffrt_task_handle_inc_ref
682
683**Declaration**
684
685```c
686FFRT_C_API uint32_t ffrt_task_handle_inc_ref(ffrt_task_handle_t handle);
687```
688
689**Parameters**
690
691- `handle`: task handle.
692
693**Return Values**
694
695- Reference count of a task.
696
697**Description**
698
699Increases the reference count of the task through the task handle by one each time the task handle is invoked. It is used to control the task lifecycle. When the reference count is not 0, the corresponding task resources are not released. Note that `ffrt_task_handle_t` returned by `ffrt_submit_h_base` has a reference count by default. By default, you can subtract a reference count when using `ffrt_task_handle_destroy` to destroy `ffrt_task_handle_t`.
700
701### ffrt_task_handle_dec_ref
702
703**Declaration**
704
705```c
706FFRT_C_API uint32_t ffrt_task_handle_dec_ref(ffrt_task_handle_t handle);
707```
708
709**Parameters**
710
711- `handle`: task handle.
712
713**Return Values**
714
715- Reference count of a task.
716
717**Description**
718
719Subtracts the reference count of the task through the task handle by one each time the task handle is invoked.
720
721### ffrt_task_handle_destroy
722
723**Declaration**
724
725```c
726FFRT_C_API void ffrt_task_handle_destroy(ffrt_task_handle_t handle);
727```
728
729**Parameters**
730
731- `handle`: task handle.
732
733**Description**
734
735Destroys a task handle and subtracts a task reference count by default.
736
737### ffrt_wait
738
739**Declaration**
740
741```c
742FFRT_C_API void ffrt_wait(void);
743```
744
745**Description**
746
747Waits until all tasks of the same level submitted earlier are complete.
748
749**Example**
750
751```c
752// Wait until three tasks are complete.
753ffrt_submit_base(func1, NULL, NULL, NULL);
754ffrt_submit_base(func2, NULL, NULL, NULL);
755ffrt_submit_base(func3, NULL, NULL, NULL);
756ffrt_wait();
757```
758
759### ffrt_wait_deps
760
761**Declaration**
762
763```c
764FFRT_C_API void ffrt_wait_deps(const ffrt_deps_t* deps);
765```
766
767**Parameters**
768
769- `deps`: data dependency to be synchronized.
770
771**Description**
772
773Waits until the data dependency is removed.
774
775**Example**
776
777```c
778// Build the data dependency of x.
779int x = 0;
780ffrt_dependence_t dependence[1];
781dependence[0].type = ffrt_dependence_data;
782dependence[0].ptr = &x;
783ffrt_deps_t deps;
784deps.len = 1;
785deps.items = dependence;
786
787// Submit a write task.
788ffrt_submit_base(func, NULL, &deps, NULL);
789
790// Wait until the data dependency of the write task is removed.
791ffrt_wait_deps(&deps);
792```
793
794### ffrt_this_task_update_qos
795
796**Declaration**
797
798```c
799FFRT_C_API int ffrt_this_task_update_qos(ffrt_qos_t qos);
800```
801
802**Parameters**
803
804- `qos`: QoS.
805
806**Return Values**
807
808- The value **0** indicates success, and the value **1** indicates failure.
809
810**Description**
811
812Updates the task QoS dynamically during task execution. Note that this API is used in the function closure of a task to update the QoS of the task that is being executed. If this API is invoked, the task is suspended and then resumed.
813
814**Example**
815
816```c
817// Dynamically update the QoS during the execution of a qos_background task.
818ffrt::submit([]() {
819    // ...
820    int ret = ffrt_this_task_update_qos(ffrt_qos_user_initiated);
821    // ...
822}, ffrt::task_attr().qos(ffrt::qos_background));
823```
824
825### ffrt_this_task_get_qos
826
827**Declaration**
828
829```c
830FFRT_C_API ffrt_qos_t ffrt_this_task_get_qos(void);
831```
832
833**Return Values**
834
835- QoS.
836
837**Description**
838
839Obtains the QoS of the task that is being executed.
840
841**Example**
842
843```c
844// Dynamically obtain the QoS during the execution of a task.
845ffrt::submit([]() {
846    // ...
847    // The obtained QoS is ffrt_qos_background.
848    ffrt_qos_t qos = ffrt_this_task_get_qos();
849    // ...
850}, ffrt::task_attr().qos(ffrt::qos_background));
851```
852
853### ffrt_this_task_get_id
854
855**Declaration**
856
857```c
858FFRT_C_API uint64_t ffrt_this_task_get_id(void);
859```
860
861**Return Values**
862
863- Task ID.
864
865**Description**
866
867Obtains the ID of the task that is being executed.
868
869**Example**
870
871```c
872// Dynamically obtain the task ID during task execution.
873ffrt::submit([]() {
874    // ...
875    // Obtain the unique task ID.
876    uint64_t task_id = ffrt_this_task_get_id();
877    // ...
878}, ffrt::task_attr().qos(ffrt::qos_background));
879```
880
881## Task Queue
882
883### ffrt_queue_attr_t
884
885**Declaration**
886
887```c
888typedef struct {
889    uint32_t storage[(ffrt_queue_attr_storage_size + sizeof(uint32_t) - 1) / sizeof(uint32_t)];
890} ffrt_queue_attr_t;
891```
892
893**Description**
894
895Configures queue attributes, such as the QoS, timeout, callback function, and maximum concurrency.
896
897**Methods**
898
899**ffrt_queue_attr_init**
900
901```c
902int ffrt_queue_attr_init(ffrt_queue_attr_t* attr);
903```
904
905Parameters
906
907- `attr`: pointer to the queue attribute.
908
909Return Values
910
911- The value **0** indicates success while other values indicate failure.
912
913Description
914
915- Initializes a queue attribute object.
916
917**ffrt_queue_attr_destroy**
918
919```c
920void ffrt_queue_attr_destroy(ffrt_queue_attr_t* attr);
921```
922
923Parameters
924
925- `attr`: pointer to the queue attribute.
926
927Description
928
929- Destroys a queue attribute object.
930
931**ffrt_queue_attr_set_qos**
932
933```c
934void ffrt_queue_attr_set_qos(ffrt_queue_attr_t* attr, ffrt_qos_t qos);
935```
936
937Parameters
938
939- `attr`: pointer to the queue attribute.
940- `qos`: QoS.
941
942Description
943
944- Sets the queue QoS.
945
946**ffrt_queue_attr_get_qos**
947
948```c
949ffrt_qos_t ffrt_queue_attr_get_qos(const ffrt_queue_attr_t* attr);
950```
951
952Parameters
953
954- `attr`: pointer to the queue attribute.
955
956Return Values
957
958- Current QoS.
959
960Description
961
962- Obtains the QoS set in the current attribute.
963
964**ffrt_queue_attr_set_timeout**
965
966```c
967void ffrt_queue_attr_set_timeout(ffrt_queue_attr_t* attr, uint64_t timeout_us);
968```
969
970Parameters
971
972- `attr`: pointer to the queue attribute.
973- `timeout_us`: timeout (μs).
974
975Description
976
977- Sets the queue timeout (unit: μs).
978
979**ffrt_queue_attr_get_timeout**
980
981```c
982uint64_t ffrt_queue_attr_get_timeout(const ffrt_queue_attr_t* attr);
983```
984
985Parameters
986
987- `attr`: pointer to the queue attribute.
988
989Return Values
990
991- Current timeout threshold (μs).
992
993Description
994
995- Obtains the timeout set in the current attribute.
996
997**ffrt_queue_attr_set_callback**
998
999```c
1000void ffrt_queue_attr_set_callback(ffrt_queue_attr_t* attr, ffrt_function_header_t* f);
1001```
1002
1003Parameters
1004
1005- `attr`: pointer to the queue attribute.
1006- `f`: pointer to the task executor, which describes how to execute and destroy the CPU task.
1007
1008Description
1009
1010- Sets the callback function to be executed after a queue task times out.
1011
1012**ffrt_queue_attr_get_callback**
1013
1014```c
1015ffrt_function_header_t* ffrt_queue_attr_get_callback(const ffrt_queue_attr_t* attr);
1016```
1017
1018Parameters
1019
1020- `attr`: pointer to the queue attribute.
1021
1022Return Values
1023
1024- Pointer to the task executor, which describes how to execute and destroy the CPU task.
1025
1026Description
1027
1028- Obtains the timeout callback function set in the current attribute.
1029
1030**ffrt_queue_attr_set_max_concurrency**
1031
1032```c
1033void ffrt_queue_attr_set_max_concurrency(ffrt_queue_attr_t* attr, const int max_concurrency);
1034```
1035
1036Parameters
1037
1038- `attr`: pointer to the queue attribute.
1039- `max_concurrency`: maximum concurrency.
1040
1041Description
1042
1043- Sets the maximum queue concurrency. (Only concurrent queues are supported.)
1044
1045**ffrt_queue_attr_get_max_concurrency**
1046
1047```c
1048int ffrt_queue_attr_get_max_concurrency(const ffrt_queue_attr_t* attr);
1049```
1050
1051Parameters
1052
1053- `attr`: pointer to the queue attribute.
1054
1055Return Values
1056
1057- Maximum concurrency.
1058
1059Description
1060
1061- Obtains the maximum concurrency set in the current attribute. (Only concurrent queues are supported).
1062
1063**ffrt_queue_attr_set_thread_mode**
1064
1065```c
1066void ffrt_queue_attr_set_thread_mode(ffrt_queue_attr_t* attr, bool mode);
1067```
1068
1069Parameters
1070
1071- `attr`: pointer to the queue attribute.
1072- `mode`: running mode of the queue task. The value `true` indicates the thread mode, and the value `false` indicates the coroutine mode.
1073
1074Description
1075
1076- Sets the running mode of tasks in the queue. By default, the coroutine mode is used.
1077
1078> **NOTE**
1079
1080> This API is supported since API version 20.
1081
1082**ffrt_queue_attr_get_thread_mode**
1083
1084```c
1085bool ffrt_queue_attr_get_thread_mode(const ffrt_queue_attr_t* attr);
1086```
1087
1088Parameters
1089
1090- `attr`: pointer to the queue attribute.
1091
1092Return Values
1093
1094- The value `true` indicates the thread mode, and the value `false` indicates the coroutine mode.
1095
1096Description
1097
1098- Obtains the running mode of tasks in the queue.
1099
1100> **NOTE**
1101
1102> This API is supported since API version 20.
1103
1104**Example**
1105
1106```cpp
1107#include <functional>
1108#include "ffrt/queue.h"
1109#include "ffrt/cpp/task.h"
1110
1111int main()
1112{
1113    ffrt_queue_attr_t queue_attr;
1114    // (Mandatory) Initialize the queue attribute.
1115    ffrt_queue_attr_init(&queue_attr);
1116
1117    ffrt_queue_attr_set_qos(&queue_attr, static_cast<int>(ffrt_qos_utility));
1118
1119    ffrt_queue_attr_set_timeout(&queue_attr, 10000);
1120
1121    int x = 0;
1122    std::function<void()>&& basicFunc = [&x]() { x += 1; };
1123    ffrt_function_header_t* func = ffrt_queue_attr_get_callback(&queue_attr);
1124
1125    ffrt_queue_attr_set_callback(&queue_attr, ffrt::create_function_wrapper(basicFunc, ffrt_function_kind_queue));
1126    // Destroy the queue attribute. This is mandatory.
1127    ffrt_queue_attr_destroy(&queue_attr);
1128    return 0;
1129}
1130```
1131
1132### ffrt_queue_t
1133
1134**Declaration**
1135
1136```c
1137typedef void* ffrt_queue_t;
1138```
1139
1140**Description**
1141
1142Pointer to queues. It provides a series of C APIs for submitting, canceling, and waiting queue tasks and querying the number of queuing tasks.
1143
1144**Methods**
1145
1146**ffrt_queue_create**
1147
1148```c
1149ffrt_queue_t ffrt_queue_create(ffrt_queue_type_t type, const char* name, const ffrt_queue_attr_t* attr);
1150```
1151
1152Parameters
1153
1154- `type`: queue type, for example, `ffrt_queue_serial` or `ffrt_queue_concurrent`.
1155- `name`: queue name.
1156- `attr`: pointer to the queue attribute.
1157
1158Return Values
1159
1160- `ffrt_queue_t`: If the function is called successfully, a non-null queue handle is returned. Otherwise, a null pointer is returned.
1161
1162Description
1163
1164- Creates a queue with a specified type and name.
1165
1166**ffrt_queue_destroy**
1167
1168```c
1169void ffrt_queue_destroy(ffrt_queue_t queue);
1170```
1171
1172Parameters
1173
1174- `queue`: queue handle.
1175
1176Description
1177
1178- Destroys a queue.
1179
1180**ffrt_queue_submit**
1181
1182```c
1183void ffrt_queue_submit(ffrt_queue_t queue, ffrt_function_header_t* f, const ffrt_task_attr_t* attr);
1184```
1185
1186Parameters
1187
1188- `queue`: queue handle.
1189- `f`: pointer to the task executor, which describes how to execute and destroy the CPU task.
1190- `attr`: task attribute.
1191
1192Description
1193
1194- Submits a task to a queue.
1195
1196**ffrt_queue_submit_f**
1197
1198```c
1199void ffrt_queue_submit_f(ffrt_queue_t queue, ffrt_function_t func, void* arg, const ffrt_task_attr_t* attr);
1200```
1201
1202Parameters
1203
1204- `queue`: queue handle.
1205- `func`: specified task function.
1206- `arg`: parameter passed to the task function.
1207- `attr`: task attribute.
1208
1209Description
1210
1211- Submits a task to the queue when the callback function does not need to be destroyed.
1212
1213**ffrt_queue_submit_h**
1214
1215```c
1216ffrt_task_handle_t ffrt_queue_submit_h(ffrt_queue_t queue, ffrt_function_header_t* f, const ffrt_task_attr_t* attr);
1217```
1218
1219Parameters
1220
1221- `queue`: queue handle.
1222- `f`: pointer to the task executor, which describes how to execute and destroy the CPU task.
1223- `attr`: task attribute.
1224
1225Return Values
1226
1227- `ffrt_task_handle_t`: If the function is called successfully, a non-null task handle is returned. Otherwise, a null pointer is returned.
1228
1229Description
1230
1231- Submits a task to a queue and returns a task handle.
1232
1233**ffrt_queue_submit_h_f**
1234
1235```c
1236ffrt_task_handle_t ffrt_queue_submit_h_f(ffrt_queue_t queue, ffrt_function_t func, void* arg, const ffrt_task_attr_t* attr);
1237```
1238
1239Parameters
1240
1241- `queue`: queue handle.
1242- `func`: specified task function.
1243- `arg`: parameter passed to the task function.
1244- `attr`: task attribute.
1245
1246Return Values
1247
1248- `ffrt_task_handle_t`: If the function is called successfully, a non-null task handle is returned. Otherwise, a null pointer is returned.
1249
1250Description
1251
1252- Submits a task to the queue and returns the task handle when the callback function does not need to be destroyed.
1253
1254**ffrt_queue_wait**
1255
1256```c
1257void ffrt_queue_wait(ffrt_task_handle_t handle);
1258```
1259
1260Parameters
1261
1262- `ffrt_task_handle_t`: task handle.
1263
1264Description
1265
1266- Waits for a queue task to complete.
1267
1268**ffrt_queue_cancel**
1269
1270```c
1271int ffrt_queue_cancel(ffrt_task_handle_t handle);
1272```
1273
1274Parameters
1275
1276- `ffrt_task_handle_t`: task handle.
1277
1278Return Values
1279
1280- The value **0** indicates success while other values indicate failure.
1281
1282Description
1283
1284- Cancels a queue task.
1285
1286**ffrt_get_main_queue**
1287
1288```c
1289ffrt_queue_t ffrt_get_main_queue();
1290```
1291
1292Return Values
1293
1294- Main thread queue.
1295
1296Description
1297
1298- Obtains the main thread queue for the FFRT thread to communicate with the main thread.
1299
1300**ffrt_get_current_queue**
1301
1302```c
1303ffrt_queue_t ffrt_get_current_queue();
1304```
1305
1306Return Values
1307
1308- ArkTS Worker thread queue.
1309
1310Description
1311
1312- This API has been deprecated since API version 18. You are not advised to use it.
1313- Obtains the ArkTS Worker thread queue for the FFRT thread to communicate with the ArkTS Worker thread.
1314
1315**Example**
1316
1317```cpp
1318#include "ffrt/queue.h"
1319#include "ffrt/cpp/task.h"
1320
1321int main()
1322{
1323    ffrt_queue_attr_t queue_attr;
1324    // 1. Initialize the queue attribute. This is mandatory.
1325    (void)ffrt_queue_attr_init(&queue_attr);
1326
1327    // 2. Create a serial queue and return queue_handle.
1328    ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
1329
1330    int result = 0;
1331    std::function<void()>&& basicFunc = [&result]() { result += 1; };
1332
1333    // 3. Submit a serial task.
1334    ffrt_queue_submit(queue_handle, ffrt::create_function_wrapper(basicFunc, ffrt_function_kind_queue), nullptr);
1335
1336    // 4. Submit the serial task and return the task handle.
1337    ffrt_task_handle_t t1 = ffrt_queue_submit_h(queue_handle, ffrt::create_function_wrapper(basicFunc, ffrt_function_kind_queue), nullptr);
1338    // 5. Wait until the specified task is complete.
1339    ffrt_queue_wait(t1);
1340
1341    ffrt_task_handle_t t2 = ffrt_queue_submit_h(queue_handle, ffrt::create_function_wrapper(basicFunc, ffrt_function_kind_queue), nullptr);
1342    // 6. Cancel the task with handle t2.
1343    ffrt_queue_cancel(t2);
1344
1345    // 7. Destroy the handles t1 and t2 submitted to the serial queue task. This is mandatory.
1346    ffrt_task_handle_destroy(t1);
1347    ffrt_task_handle_destroy(t2);
1348    // 8. Destroy the queue attribute. This is mandatory.
1349    ffrt_queue_attr_destroy(&queue_attr);
1350    // 9. Destroy the queue handle. This is mandatory.
1351    ffrt_queue_destroy(queue_handle);
1352    return 0;
1353}
1354```
1355
1356## Synchronization Primitive
1357
1358### ffrt_mutexattr_t
1359
1360**Declaration**
1361
1362```c
1363typedef enum {
1364    ffrt_error = -1,
1365    ffrt_success = 0,
1366    ffrt_error_nomem = ENOMEM,
1367    ffrt_error_timedout = ETIMEDOUT,
1368    ffrt_error_busy = EBUSY,
1369    ffrt_error_inval = EINVAL
1370} ffrt_error_t;
1371
1372typedef enum {
1373    ffrt_mutex_normal = 0,
1374    ffrt_mutex_recursive = 2,
1375    ffrt_mutex_default = ffrt_mutex_normal
1376} ffrt_mutex_type;
1377
1378struct ffrt_mutexattr_t;
1379
1380int ffrt_mutexattr_init(ffrt_mutexattr_t* attr);
1381int ffrt_mutexattr_settype(ffrt_mutexattr_t* attr, int type);
1382int ffrt_mutexattr_gettype(ffrt_mutexattr_t* attr, int* type);
1383int ffrt_mutexattr_destroy(ffrt_mutexattr_t* attr);
1384```
1385
1386**Description**
1387
1388- Provides performance implementation similar to pthread mutex.
1389
1390**Methods**
1391
1392**ffrt_mutexattr_init**
1393
1394```c
1395FFRT_C_API int ffrt_mutexattr_init(ffrt_mutexattr_t* attr);
1396```
1397
1398Parameters
1399
1400- `attr`: FFRT mutex attribute.
1401
1402Return Values
1403
1404- `ffrt_success` is returned if `attr` is not empty. Otherwise, `ffrt_error_inval` is returned.
1405
1406Description
1407
1408- Initializes `mutexattr`.
1409
1410**ffrt_mutexattr_destroy**
1411
1412```c
1413FFRT_C_API int ffrt_mutexattr_destroy(ffrt_mutexattr_t* attr);
1414```
1415
1416Parameters
1417
1418- `attr`: FFRT mutex attribute.
1419
1420Return Values
1421
1422- `ffrt_success` is returned if `attr` is not empty. Otherwise, `ffrt_error_inval` is returned.
1423
1424Description
1425
1426- Destroys `mutexattr`.
1427
1428**ffrt_mutexattr_settype**
1429
1430```c
1431FFRT_C_API int ffrt_mutexattr_settype(ffrt_mutexattr_t* attr, int type);
1432```
1433
1434Parameters
1435
1436- `attr`: FFRT mutex attribute.
1437- `type`: FFRT mutex type. Currently, only `ffrt_mutex_normal` and `ffrt_mutex_recursive` are supported.
1438
1439Return Values
1440
1441- `ffrt_success` is returned if `attr` is not empty and `type` is valid. Otherwise, `ffrt_error_inval` is returned.
1442
1443Description
1444
1445- Sets the FFRT mutex attribute.
1446
1447**ffrt_mutexattr_gettype**
1448
1449```c
1450FFRT_C_API int ffrt_mutexattr_gettype(ffrt_mutexattr_t* attr, int* type);
1451```
1452
1453Parameters
1454
1455- `attr`: FFRT mutex attribute.
1456- `type`: pointer to the FFRT mutex type.
1457
1458Return Values
1459
1460- `ffrt_success` is returned if neither `attr` nor `type` is empty. Otherwise, `ffrt_error_inval` is returned.
1461
1462Description
1463
1464- Obtains the FFRT mutex attribute.
1465
1466**Example**
1467
1468```c
1469ffrt_mutexattr_t attr;
1470// Initialize the mutex attribute.
1471ffrt_mutexattr_init(&attr);
1472// Set a mutex.
1473ffrt_mutexattr_settype(&attr, ffrt_mutex_normal);
1474// Set a recursive lock.
1475ffrt_mutexattr_settype(&attr, ffrt_mutex_recursive);
1476// Obtain the mutex type.
1477int type = ffrt_mutex_default;
1478ffrt_mutexattr_gettype(&attr, &type);
1479// Destroy the mutex attribute.
1480ffrt_mutexattr_destroy(&attr);
1481```
1482
1483### ffrt_mutex_t
1484
1485- Implements `pthread_mutex_t`, but does not supports initialization of `PTHREAD_MUTEX_INITIALIZER`.
1486
1487**Declaration**
1488
1489```c
1490struct ffrt_mutex_t;
1491struct ffrt_mutexattr_t;
1492
1493int ffrt_mutex_init(ffrt_mutex_t* mutex, const ffrt_mutexattr_t* attr);
1494int ffrt_mutex_lock(ffrt_mutex_t* mutex);
1495int ffrt_mutex_unlock(ffrt_mutex_t* mutex);
1496int ffrt_mutex_trylock(ffrt_mutex_t* mutex);
1497int ffrt_mutex_destroy(ffrt_mutex_t* mutex);
1498```
1499
1500**Description**
1501
1502- This API can be called inside or outside an FFRT task.
1503- The traditional function `pthread_mutex_t` may cause unexpected kernel mode trap when it fails to lock a mutex. **ffrt_mutex_t** solves this problem and therefore provides better performance if used properly.
1504- `ffrt_mutexattr_t` in the C API needs to be created and destroyed by calling `ffrt_mutexattr_init` and `ffrt_mutexattr_destroy`. Otherwise, undefined behavior may occur.
1505- `ffrt_mutex_t` in the C API needs to be explicitly created and destroyed by calling `ffrt_mutex_init` and `ffrt_mutex_destroy`. Otherwise, undefined behavior may occur.
1506- You need to set the `ffrt_mutex_t` object in the C code to null or destroy the object. For the same `ffrt_mutex_t` object, `ffrt_mutex_destroy` can be called only once. Otherwise, undefined behavior may occur.
1507- The same `ffrt_mutexattr_t` in the C API can call `ffrt_mutexattr_init` and `ffrt_mutexattr_destroy` only once. Repeated calling may cause undefined behavior.
1508- You need to explicitly call `ffrt_mutex_destroy` after `ffrt_mutex_init` and before `ffrt_mutexattr_destroy`.
1509- If `ffrt_mutex_t` is accessed after `ffrt_mutex_destroy`, undefined behavior may occur.
1510
1511**Methods**
1512
1513**ffrt_mutex_init**
1514
1515```c
1516FFRT_C_API int ffrt_mutex_init(ffrt_mutex_t* mutex, const ffrt_mutexattr_t* attr);
1517```
1518
1519Parameters
1520
1521- `mutex`: pointer to the operated mutex.
1522- `attr`: FFRT mutex attribute. Its valid value can be a null pointer, `ffrt_mutex_normal`, or `ffrt_mutex_recursive`.
1523
1524Return Values
1525
1526- `ffrt_success` is returned if `mutex` is not empty and `attr` is within the valid value range. Otherwise, `ffrt_error_inval` is returned.
1527
1528Description
1529
1530- Initializes the FFRT mutex.
1531
1532**ffrt_mutex_destroy**
1533
1534```c
1535FFRT_C_API int ffrt_mutex_destroy(ffrt_mutex_t* mutex);
1536```
1537
1538Parameters
1539
1540- `mutex`: pointer to the operated mutex.
1541
1542Return Values
1543
1544- `ffrt_success` is returned if `mutex` is not empty. Otherwise, `ffrt_error_inval` is returned.
1545
1546Description
1547
1548- Destroys a specified mutex or recursive lock.
1549
1550**ffrt_mutex_lock**
1551
1552```c
1553FFRT_C_API int ffrt_mutex_lock(ffrt_mutex_t* mutex);
1554```
1555
1556Parameters
1557
1558- `mutex`: pointer to the operated mutex.
1559
1560Return Values
1561
1562- `ffrt_success` is returned if `mutex` is not empty. Otherwise, `ffrt_error_inval` is returned.
1563
1564Description
1565
1566- Locks a specified mutex or recursive lock. This method blocks the current task until the mutex is successfully obtained.
1567
1568**ffrt_mutex_unlock**
1569
1570```c
1571FFRT_C_API int ffrt_mutex_unlock(ffrt_mutex_t* mutex);
1572```
1573
1574Parameters
1575
1576- `mutex`: pointer to the operated mutex.
1577
1578Return Values
1579
1580- `ffrt_success` is returned if `mutex` is not empty. Otherwise, `ffrt_error_inval` is returned.
1581
1582Description
1583
1584- Unlocks a specified mutex or recursive lock.
1585
1586**ffrt_mutex_trylock**
1587
1588```c
1589FFRT_C_API int ffrt_mutex_trylock(ffrt_mutex_t* mutex);
1590```
1591
1592Parameters
1593
1594- `mutex`: pointer to the operated mutex.
1595
1596Return Values
1597
1598- **ffrt_error_inval** is returned if `mutex` is empty. `ffrt_success` is returned if `mutex` is not empty and the mutex is successfully held. `ffrt_error_busy` is returned if `mutex` is not empty and the mutex fails to be held.
1599
1600Description
1601
1602- Locks a specified mutex or recursive lock.
1603
1604**Example**
1605
1606```cpp
1607#include "ffrt/mutex.h"
1608#include "ffrt/cpp/task.h"
1609
1610int main()
1611{
1612    ffrt_mutexattr_t attr;
1613    ffrt_mutex_t lock;
1614    int sum = 0;
1615    int type = ffrt_mutex_default;
1616    ffrt_mutexattr_init(&attr);
1617    ffrt_mutexattr_settype(&attr, ffrt_mutex_recursive);
1618    ffrt_mutexattr_gettype(&attr, &type);
1619    ffrt_mutex_init(&lock, &attr);
1620    ffrt::submit([&]() {
1621        ffrt_mutex_lock(&lock);
1622        ffrt_mutex_trylock(&lock);
1623        sum++;
1624        ffrt_mutex_lock(&lock);
1625        ffrt_mutex_trylock(&lock);
1626        sum++;
1627        ffrt_mutex_unlock(&lock);
1628        ffrt_mutex_unlock(&lock);
1629        ffrt_mutex_unlock(&lock);
1630        ffrt_mutex_unlock(&lock);
1631        }, {}, {});
1632
1633    ffrt::wait();
1634
1635    ffrt_mutexattr_destroy(&attr);
1636    ffrt_mutex_destroy(&lock);
1637    return 0;
1638}
1639```
1640
1641### ffrt_rwlock_t
1642
1643- Implements `pthread_rwlock_t`.
1644
1645**Declaration**
1646
1647```c
1648struct ffrt_rwlock_t;
1649struct ffrt_rwlockattr_t;
1650
1651int ffrt_rwlock_init(ffrt_rwlock_t* rwlock, const ffrt_rwlockattr_t* attr);
1652int ffrt_rwlock_wrlock(ffrt_rwlock_t* rwlock);
1653int ffrt_rwlock_rdlock(ffrt_rwlock_t* rwlock);
1654int ffrt_rwlock_trywrlock(ffrt_rwlock_t* rwlock);
1655int ffrt_rwlock_tryrdlock(ffrt_rwlock_t* rwlock);
1656int ffrt_rwlock_unlock(ffrt_rwlock_t* rwlock);
1657int ffrt_rwlock_destroy(ffrt_rwlock_t* rwlock);
1658```
1659
1660**Description**
1661
1662- This API can be called inside or outside an FFRT task.
1663- This API can avoid the issue that `pthread_rwlock_t` sleeps without releasing threads. The performance is better when the API is properly used.
1664- `ffrt_rwlock_t` in the C API needs to be explicitly created and destroyed by calling `ffrt_rwlock_init` and `ffrt_rwlock_destroy`. Otherwise, undefined behavior may occur.
1665- When `ffrt_rwlockattr_t` is called, the input parameter of `ffrt_rwlockattr_t` must be a null pointer.
1666- You need to set the `ffrt_rwlock_t` object in the C code to null or destroy the object. For the same `ffrt_rwlock_t` object, `ffrt_rwlock_destroy` can be called only once. Otherwise, undefined behavior may occur.
1667- If `ffrt_rwlock_t` is accessed after `ffrt_rwlock_destroy` is called, undefined behavior may occur.
1668
1669**Methods**
1670
1671**ffrt_rwlock_init**
1672
1673```c
1674FFRT_C_API int ffrt_rwlock_init(ffrt_rwlock_t* rwlock, const ffrt_rwlockattr_t* attr);
1675```
1676
1677Parameters
1678
1679- `rwlock`: pointer to the operated read-write lock.
1680- `attr`: pointer to the attribute of the operated read-write lock. Only the default mode is supported. That is, `attr` must be set to a null pointer.
1681
1682Return Values
1683
1684- `ffrt_success` is returned if `rwlock` is not empty and `attr` is empty. Otherwise, `ffrt_error_inval` is returned.
1685
1686Description
1687
1688- Initializes the read-write lock.
1689
1690**ffrt_rwlock_wrlock**
1691
1692```c
1693FFRT_C_API int ffrt_rwlock_wrlock(ffrt_rwlock_t* rwlock);
1694```
1695
1696Parameters
1697
1698- `rwlock`: pointer to the operated read-write lock.
1699
1700Return Values
1701
1702- `ffrt_success` is returned if `rwlock` is not empty. Otherwise, `ffrt_error_inval` is returned.
1703
1704Description
1705
1706- Adds a write lock to the specified read-write lock.
1707
1708**ffrt_rwlock_rdlock**
1709
1710```c
1711FFRT_C_API int ffrt_rwlock_rdlock(ffrt_rwlock_t* rwlock);
1712```
1713
1714Parameters
1715
1716- `rwlock`: pointer to the operated read-write lock.
1717
1718Return Values
1719
1720- `ffrt_success` is returned if `rwlock` is not empty. Otherwise, `ffrt_error_inval` is returned.
1721
1722Description
1723
1724- Adds a read lock to the specified read-write lock.
1725
1726**ffrt_rwlock_trywrlock**
1727
1728```c
1729FFRT_C_API int ffrt_rwlock_trywrlock(ffrt_rwlock_t* rwlock);
1730```
1731
1732Parameters
1733
1734- `rwlock`: pointer to the operated read-write lock.
1735
1736Return Values
1737
1738- `ffrt_success` is returned if `rwlock` is not empty and no other thread holds the read-write lock. Otherwise, `ffrt_error_inval` is returned.
1739
1740Description
1741
1742- Adds a write lock to the specified read-write lock.
1743
1744**ffrt_rwlock_tryrdlock**
1745
1746```c
1747FFRT_C_API int ffrt_rwlock_tryrdlock(ffrt_rwlock_t* rwlock);
1748```
1749
1750Parameters
1751
1752- `rwlock`: pointer to the operated read-write lock.
1753
1754Return Values
1755
1756- `ffrt_success` is returned if `rwlock` is not empty and no other thread holds the write lock. Otherwise, `ffrt_error_inval` is returned.
1757
1758Description
1759
1760- Adds a read lock to the specified read-write lock.
1761
1762**ffrt_rwlock_unlock**
1763
1764```c
1765FFRT_C_API int ffrt_rwlock_unlock(ffrt_rwlock_t* rwlock);
1766```
1767
1768Parameters
1769
1770- `rwlock`: pointer to the operated read-write lock.
1771
1772Return Values
1773
1774- `ffrt_success` is returned if `rwlock` is not empty. Otherwise, `ffrt_error_inval` is returned.
1775
1776Description
1777
1778- Unlocks the specified read-write lock.
1779
1780**ffrt_rwlock_destroy**
1781
1782```c
1783FFRT_C_API int ffrt_rwlock_destroy(ffrt_rwlock_t* rwlock);
1784```
1785
1786Parameters
1787
1788- `rwlock`: pointer to the operated read-write lock.
1789
1790Return Values
1791
1792- `ffrt_success` is returned if `rwlock` is not empty. Otherwise, `ffrt_error_inval` is returned.
1793
1794Description
1795
1796- Destroys a specified read-write lock.
1797
1798**Example**
1799
1800```cpp
1801#include "ffrt/shared_mutex.h"
1802#include "ffrt/sleep.h"
1803#include "ffrt/cpp/task.h"
1804
1805int main()
1806{
1807    ffrt_rwlock_t rwlock;
1808    int x = 0;
1809    ffrt_rwlock_init(&rwlock, nullptr);
1810    ffrt::submit([&]() {
1811        ffrt_rwlock_wrlock(&rwlock);
1812        ffrt_usleep(10);
1813        x++;
1814        ffrt_rwlock_unlock(&rwlock);
1815    },{},{});
1816
1817    ffrt::submit([&]() {
1818        ffrt_usleep(2);
1819        ffrt_rwlock_rdlock(&rwlock);
1820        ffrt_rwlock_unlock(&rwlock);
1821    },{},{});
1822
1823    ffrt::submit([&]() {
1824        ffrt_usleep(2);
1825        if(ffrt_rwlock_trywrlock(&rwlock)){
1826            x++;
1827            ffrt_rwlock_unlock(&rwlock);
1828        }
1829    },{},{});
1830
1831    ffrt::submit([&]() {
1832        ffrt_usleep(2);
1833        if(ffrt_rwlock_tryrdlock(&rwlock)){
1834            ffrt_rwlock_unlock(&rwlock);
1835        }
1836    },{},{});
1837
1838    ffrt::wait();
1839
1840    ffrt_rwlock_destroy(&rwlock);
1841    return 0;
1842}
1843```
1844
1845### ffrt_cond_t
1846
1847- Implements the pthread semaphore function, but does not supports initialization of `PTHREAD_COND_INITIALIZER`.
1848
1849**Declaration**
1850
1851```c
1852typedef enum {
1853    ffrt_error = -1,
1854    ffrt_success = 0,
1855    ffrt_error_nomem = ENOMEM,
1856    ffrt_error_timedout = ETIMEDOUT,
1857    ffrt_error_busy = EBUSY,
1858    ffrt_error_inval = EINVAL
1859} ffrt_error_t;
1860
1861typedef struct {
1862    uint32_t storage[(ffrt_cond_storage_size + sizeof(uint32_t) - 1) / sizeof(uint32_t)];
1863} ffrt_cond_t;
1864
1865int ffrt_cond_init(ffrt_cond_t* cond, const ffrt_condattr_t* attr);
1866int ffrt_cond_signal(ffrt_cond_t* cond);
1867int ffrt_cond_broadcast(ffrt_cond_t* cond);
1868int ffrt_cond_wait(ffrt_cond_t*cond, ffrt_mutex_t* mutex);
1869int ffrt_cond_timedwait(ffrt_cond_t* cond, ffrt_mutex_t* mutex, const struct timespec* time_point);
1870int ffrt_cond_destroy(ffrt_cond_t* cond);
1871```
1872
1873**Description**
1874
1875- This API can be called inside or outside an FFRT task.
1876- The traditional function `pthread_cond_t` may cause unexpected kernel mode trap when the conditions are not met. **ffrt_cond_t** solves this problem and therefore provides better performance if being used properly.
1877- Note that `ffrt_cond_t` in the C API needs to be explicitly created and destroyed by calling `ffrt_cond_init` and `ffrt_cond_destroy`. However, in the C++ API, the dependency construction and destruction are automatically completed.
1878- You need to set the `ffrt_cond_t` object in the C code to null or destroy the object. For the same `ffrt_cond_t` object, `ffrt_cond_destroy` can be called only once. Otherwise, undefined behavior may occur.
1879- If `ffrt_cond_t` is accessed after `ffrt_cond_destroy` is called, undefined behavior may occur.
1880
1881**Methods**
1882
1883**ffrt_cond_init**
1884
1885```c
1886FFRT_C_API int ffrt_cond_init(ffrt_cond_t* cond, const ffrt_condattr_t* attr);
1887```
1888
1889Parameters
1890
1891- `cond`: pointer to the target semaphore.
1892- `attr`: pointer to the attribute. A null pointer indicates that the default attribute is used.
1893
1894Return Values
1895
1896- `ffrt_success` is returned if `cond` is not empty. Otherwise, `ffrt_error_inval` is returned.
1897
1898Description
1899
1900- Initializes the FFRT condition variable.
1901
1902**ffrt_cond_destroy**
1903
1904```c
1905FFRT_C_API int ffrt_cond_destroy(ffrt_cond_t* cond);
1906```
1907
1908Parameters
1909
1910- `cond`: pointer to the target semaphore.
1911
1912Return Values
1913
1914- `ffrt_success` is returned if `cond` is not empty. Otherwise, `ffrt_error_inval` is returned.
1915
1916Description
1917
1918- Destroys an FFRT condition variable.
1919
1920**ffrt_cond_signal**
1921
1922```c
1923FFRT_C_API int ffrt_cond_signal(ffrt_cond_t* cond);
1924```
1925
1926Parameters
1927
1928- `cond`: pointer to the target semaphore.
1929
1930Return Values
1931
1932- `ffrt_success` is returned if `cond` is not empty. Otherwise, `ffrt_error_inval` is returned.
1933
1934Description
1935
1936- Unblocks at least one of the threads that are blocked on a condition variable.
1937
1938**ffrt_cond_broadcast**
1939
1940```c
1941FFRT_C_API int ffrt_cond_broadcast(ffrt_cond_t* cond);
1942```
1943
1944Parameters
1945
1946- `cond`: pointer to the target semaphore.
1947
1948Return Values
1949
1950- `ffrt_success` is returned if `cond` is not empty. Otherwise, `ffrt_error_inval` is returned.
1951
1952Description
1953
1954- Unblocks all threads currently blocked on a condition variable.
1955
1956**ffrt_cond_wait**
1957
1958```c
1959FFRT_C_API int ffrt_cond_wait(ffrt_cond_t* cond, ffrt_mutex_t* mutex);
1960```
1961
1962Parameters
1963
1964- `cond`: pointer to the target semaphore.
1965- `mutex`: pointer to the target mutex.
1966
1967Return Values
1968
1969- `ffrt_success` is returned if neither `cond` nor `mutex` is empty. Otherwise, `ffrt_error_inval` is returned.
1970
1971Description
1972
1973- Blocks a task on a condition variable. When using this method, a task releases the input mutex and enters the waiting state. The task obtains the mutex again and continues to execute until another task notifies the condition variable.
1974- This method is usually used together with `ffrt_mutex_lock` or `ffrt_mutex_trylock` to ensure that the mutex is held before entering the wait state.
1975
1976**ffrt_cond_timedwait**
1977
1978```c
1979FFRT_C_API int ffrt_cond_timedwait(ffrt_cond_t* cond, ffrt_mutex_t* mutex, const struct timespec* time_point);
1980```
1981
1982Parameters
1983
1984- `cond`: pointer to the target semaphore.
1985- `mutex`: pointer to the target mutex.
1986- `time_point`: pointer to the maximum duration during which the thread is blocked.
1987
1988Return Values
1989
1990- `ffrt_success` is returned if `cond`, `mutex`, and `time_point` are not empty. Otherwise, `ffrt_error_inval` is returned.
1991
1992Description
1993
1994- Blocks a task on a condition variable until the specified timeout is reached.
1995- Unlike `ffrt_cond_wait`, the `ffrt_cond_timedwait` method allows a task to wait for a period of time on a condition variable. If no notification is received within the specified period of time, the task is woken up and the function returns.
1996
1997**Example**
1998
1999```cpp
2000#include <iostream>
2001#include "ffrt/condition_variable.h"
2002#include "ffrt/mutex.h"
2003#include "ffrt/sleep.h"
2004#include "ffrt/cpp/task.h"
2005
2006struct timespec timeoutms_to_tm(int timeout_ms) {
2007    struct timespec ts;
2008    clock_gettime(CLOCK_REALTIME, &ts);
2009    ts.tv_sec += timeout_ms / 1000;
2010    ts.tv_nsec += (timeout_ms % 1000) * 1000000;
2011    if (ts.tv_nsec >= 1000000000) {
2012        ts.tv_sec += 1;
2013        ts.tv_nsec -= 1000000000;
2014    }
2015    return ts;
2016}
2017
2018int main()
2019{
2020    int a = 0;
2021    ffrt_cond_t cond;
2022    ffrt_mutex_t lock_;
2023    ffrt_cond_init(&cond, nullptr);
2024    ffrt_mutex_init(&lock_, nullptr);
2025
2026    for (int i = 0; i < 3; i++) {
2027        ffrt::submit([&]() {
2028            int timeout = 2000;
2029            struct timespec tm = timeoutms_to_tm(timeout);
2030            ffrt_mutex_lock(&lock_);
2031            auto start = std::chrono::high_resolution_clock::now();
2032            ffrt_cond_timedwait(&cond, &lock_, &tm);
2033            auto end = std::chrono::high_resolution_clock::now();
2034            a = 123;
2035            ffrt_mutex_unlock(&lock_);
2036            std::chrono::duration<double, std::milli> elapsed = end - start;
2037            double t = elapsed.count();
2038            std::cout << "ffrt_cond_timedwait " << t << " ms" << std::endl;
2039            }, {}, {});
2040    }
2041
2042    ffrt::submit([&]() {
2043        ffrt_usleep(1000 * 1000);
2044        ffrt_mutex_lock(&lock_);
2045        a = 5;
2046        ffrt_cond_broadcast(&cond);
2047        ffrt_mutex_unlock(&lock_);
2048        }, {}, {});
2049    ffrt::wait();
2050    ffrt_cond_destroy(&cond);
2051    ffrt_mutex_destroy(&lock_);
2052    return 0;
2053}
2054```
2055
2056## Blocking Primitive
2057
2058### ffrt_usleep
2059
2060**Declaration**
2061
2062```c
2063FFRT_C_API int ffrt_usleep(uint64_t usec);
2064```
2065
2066**Parameters**
2067
2068- `usec`: sleep duration, in μs.
2069
2070**Description**
2071
2072- Provides performance implementation similar to C11 sleep and Linux usleep.
2073- This API can be called only inside an FFRT task. If it is called outside an FFRT task, undefined behavior may occur.
2074- The sleep precision of this API is μs.
2075- The traditional function `sleep` may cause unexpected kernel mode trap. **ffrt_usleep** solves this problem and therefore provides better performance if used properly.
2076
2077**Example**
2078
2079```cpp
2080#include "ffrt/sleep.h"
2081#include "ffrt/cpp/task.h"
2082
2083int main()
2084{
2085    ffrt::submit([=]() { ffrt_usleep(10); }, {}, {});
2086    ffrt::wait();
2087    return 0;
2088}
2089```
2090
2091## Cooperative Primitive
2092
2093### ffrt_yield
2094
2095**Declaration**
2096
2097```c
2098FFRT_C_API void ffrt_yield();
2099```
2100
2101**Description**
2102
2103- Yields CPU execution resources for other executable tasks. If there is no other executable task, `yield` is invalid.
2104- This API can be called only inside an FFRT task. If it is called outside an FFRT task, undefined behavior may occur.
2105- The exact behavior of this API depends on the implementation, especially the mechanism and system state of the FFRT scheduler in use.
2106
2107**Example**
2108
2109```cpp
2110#include <iostream>
2111#include "ffrt/sleep.h"
2112#include "ffrt/cpp/task.h"
2113
2114int main()
2115{
2116    int count = 12;
2117    for (int i = 0; i < count; i++) {
2118        ffrt::submit([&]() {
2119            ffrt_usleep(100);
2120            std::cout << "test" << std::endl;
2121            ffrt_yield();
2122        }, {}, {});
2123    }
2124    ffrt::wait();
2125    return 0;
2126}
2127```
2128
2129## Timer
2130
2131### ffrt_timer_t
2132
2133**Declaration**
2134
2135```c
2136typedef int ffrt_timer_t;
2137typedef void (*ffrt_timer_cb)(void* data);
2138```
2139
2140**Description**
2141
2142Provides timer-related functions.
2143
2144**Methods**
2145
2146**ffrt_timer_start**
2147
2148Declaration
2149
2150```c
2151FFRT_C_API ffrt_timer_t ffrt_timer_start(ffrt_qos_t qos, uint64_t timeout, void* data, ffrt_timer_cb cb, bool repeat);
2152```
2153
2154Parameters
2155
2156- `qos`: QoS.
2157- `timeout`: timer timeout, in ms.
2158- `cb`: callback function after expiration.
2159- `data`: input parameter of the callback function.
2160- `repeat`: whether the timer is triggered repeatedly.
2161
2162Return Values
2163
2164- `ffrt_timer_t`, which indicates the timer handle.
2165
2166Description
2167
2168- Starts a timer. If the timer expires and is not stopped, the callback function is executed. If `repeat` is set to `repeat`, the timer is set again after it expires.
2169
2170**ffrt_timer_stop**
2171
2172Declaration
2173
2174```c
2175FFRT_C_API int ffrt_timer_stop(ffrt_qos_t qos, ffrt_timer_t handle);
2176```
2177
2178Parameters
2179
2180- `qos`: QoS.
2181- `handle`: timer handle.
2182
2183Return Values
2184
2185- The value **0** indicates success, and the value **-1** indicates failure.
2186
2187Description
2188
2189- Stops a timer. It is used with `ffrt_timer_start`.
2190- This is a blocking API and should be avoided in the callback to prevent deadlock or synchronization problems. If the callback corresponding to the input handle is being executed, this function will wait until the callback is complete.
2191
2192**Example**
2193
2194- Example 1: Use a one-shot timer.
2195
2196    ```c
2197    #include <stdio.h>
2198    #include <unistd.h>
2199    #include "ffrt/timer.h"
2200
2201    static void test_fun(void *data)
2202    {
2203        *(int *)data += 1;
2204    }
2205
2206    void (*cb)(void *) = test_fun;
2207
2208    int main()
2209    {
2210        static int x = 0;
2211        void *data = &x;
2212        uint64_t timeout = 200;
2213        // Start a timer and execute the callback function after 200 ms.
2214        int handle = ffrt_timer_start(ffrt_qos_default, timeout, data, cb, false);
2215        usleep(300000);
2216        // The timer has been executed and cannot be stopped.
2217        ffrt_timer_stop(ffrt_qos_default, handle);
2218        printf("data: %d\n", x); // Set the value of x to 1.
2219        return 0;
2220    }
2221    ```
2222
2223- Example 2: Use a repeating timer.
2224
2225    ```c
2226    #include <stdio.h>
2227    #include <unistd.h>
2228    #include "ffrt/timer.h"
2229
2230    static void test_fun(void *data)
2231    {
2232        *(int *)data += 1;
2233    }
2234
2235    void (*cb)(void *) = test_fun;
2236
2237    int main()
2238    {
2239        static int x = 0;
2240        void *data = &x;
2241        uint64_t timeout = 200;
2242        // Start a repeating timer and execute the callback function every 200 ms.
2243        int handle = ffrt_timer_start(ffrt_qos_default, timeout, data, cb, true);
2244        usleep(500000);
2245        // Stops the repeating timer.
2246        ffrt_timer_stop(ffrt_qos_default, handle);
2247        printf("data: %d\n", x); // Set the value of x to 2.
2248        return 0;
2249    }
2250    ```
2251
2252## Loop
2253
2254### ffrt_loop_t
2255
2256**Declaration**
2257
2258```c
2259typedef void* ffrt_loop_t;
2260```
2261
2262**Description**
2263
2264Provides loop-related functions.
2265
2266**Methods**
2267
2268**ffrt_loop_create**
2269
2270Declaration
2271
2272```c
2273FFRT_C_API ffrt_loop_t ffrt_loop_create(ffrt_queue_t queue);
2274```
2275
2276Parameters
2277
2278- `queue`: a concurrent queue that needs to be bound with a loop.
2279
2280Return Values
2281
2282- `ffrt_loop_t` object.
2283
2284Description
2285
2286- Creates a loop and bind a concurrent queue for storing tasks. You can submit a task to the queue so that the task can be executed in the loop.
2287
2288**ffrt_loop_destroy**
2289
2290Declaration
2291
2292```c
2293FFRT_C_API int ffrt_loop_destroy(ffrt_loop_t loop);
2294```
2295
2296Parameters
2297
2298- `loop`: loop object.
2299
2300Return Values
2301
2302- The value **0** indicates success, and the value **-1** indicates failure.
2303
2304Description
2305
2306- Destroys a loop and unbinds it from the queue.
2307
2308**ffrt_loop_run**
2309
2310Declaration
2311
2312```c
2313FFRT_C_API int ffrt_loop_run(ffrt_loop_t loop);
2314```
2315
2316Parameters
2317
2318- `loop`: loop object.
2319
2320Return Values
2321
2322- The value **0** indicates success, and the value **-1** indicates failure.
2323
2324Description
2325
2326- Runs a loop. The thread that invokes this method executes the loop at the same time, executes queue tasks, and listens for the poller and timer.
2327
2328**ffrt_loop_stop**
2329
2330Declaration
2331
2332```c
2333FFRT_C_API void ffrt_loop_stop(ffrt_loop_t loop);
2334```
2335
2336Parameters
2337
2338- `loop`: loop object.
2339
2340Description
2341
2342- Stops a loop. This method is invoked to enable the thread that executes the loop to exit the loop.
2343
2344**ffrt_loop_epoll_ctl**
2345
2346Declaration
2347
2348```c
2349int ffrt_loop_epoll_ctl(ffrt_loop_t loop, int op, int fd, uint32_t events, void *data, ffrt_poller_cb cb)
2350```
2351
2352Parameters
2353
2354- `loop`: loop object.
2355- `op`: FD operator. For details, see the operation type of **epoll_ctl**.
2356- `fd`: event descriptor.
2357- `events`: event. For details, see the event type of **epoll_ctl**.
2358- `data`: input parameter of the callback function.
2359- `cb`: callback function.
2360
2361Return Values
2362
2363- The value **0** indicates success, and the value **-1** indicates failure.
2364
2365Description
2366
2367- Manages FD listening on the loop. Event listening and callback are processed on the loop thread.
2368
2369**ffrt_loop_timer_start**
2370
2371Declaration
2372
2373```c
2374FFRT_C_API ffrt_timer_t ffrt_loop_timer_start(ffrt_loop_t loop, uint64_t timeout, void* data, ffrt_timer_cb cb, bool repeat);
2375```
2376
2377Parameters
2378
2379- `loop`: loop object.
2380- `timeout`: timer timeout, in ms.
2381- `cb`: callback function after expiration.
2382- `data`: input parameter of the callback function.
2383- `repeat`: whether the timer is triggered repeatedly.
2384
2385Return Values
2386
2387- `ffrt_timer_t`, which indicates the timer handle.
2388
2389Description
2390
2391- Starts a timer on the loop. The usage is the same as that of `ffrt_timer_start`. The only difference is that the listening and callback execution of the timer are processed on the loop thread.
2392
2393**ffrt_loop_timer_stop**
2394
2395Declaration
2396
2397```c
2398FFRT_C_API int ffrt_loop_timer_stop(ffrt_loop_t loop, ffrt_timer_t handle);
2399```
2400
2401Parameters
2402
2403- `loop`: loop object.
2404- `handle`: timer handle.
2405
2406Return Values
2407
2408- The value **0** indicates success, and the value **-1** indicates failure.
2409
2410Description
2411
2412- Stops a timer. The usage is the same as that of `ffrt_timer_stop`.
2413
2414**Example**
2415
2416- Example 1: loop and concurrent queue.
2417
2418    ```c
2419    #include <pthread.h>
2420    #include <stdio.h>
2421    #include "ffrt/loop.h"
2422
2423    void* ThreadFunc(void* p)
2424    {
2425        int ret = ffrt_loop_run(p);
2426        if (ret == 0) {
2427            printf("loop normal operation.");
2428        }
2429        return NULL;
2430    }
2431
2432    int main()
2433    {
2434        // Create a concurrent queue.
2435        ffrt_queue_attr_t queue_attr;
2436        (void)ffrt_queue_attr_init(&queue_attr);
2437        ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_concurrent, "test_queue", &queue_attr);
2438
2439        // Create a loop.
2440        ffrt_loop_t loop = ffrt_loop_create(queue_handle);
2441
2442        // Create a separate thread to perform the loop.
2443        pthread_t thread;
2444        int ret = pthread_create(&thread, 0, ThreadFunc, loop);
2445        if (ret != 0) {
2446            printf("pthread_create failed!");
2447            ffrt_loop_destroy(loop);
2448            ffrt_queue_attr_destroy(&queue_attr);
2449            ffrt_queue_destroy(queue_handle);
2450            return 0;
2451        }
2452
2453        // Stop and destroy the loop.
2454        ffrt_loop_stop(loop);
2455        ffrt_loop_destroy(loop);
2456
2457        // Destroy the concurrent queue.
2458        ffrt_queue_attr_destroy(&queue_attr);
2459        ffrt_queue_destroy(queue_handle);
2460        return 0;
2461    }
2462    ```
2463
2464- Example 2: loop, concurrent queue, and timer.
2465
2466    ```cpp
2467    #include <pthread.h>
2468    #include <unistd.h>
2469    #include <stdio.h>
2470    #include <functional>
2471    #include <sys/epoll.h>
2472    #include <sys/eventfd.h>
2473    #include "ffrt/loop.h"
2474    #include "ffrt/cpp/task.h"
2475
2476    void* ThreadFunc(void* p)
2477    {
2478        ffrt_loop_run(p);
2479        return nullptr;
2480    }
2481
2482    static void test_fun(void* data)
2483    {
2484        *(int*)data += 1;
2485    }
2486
2487    static void (*cb)(void*) = test_fun;
2488
2489    void testCallBack(void *data, unsigned int events) {}
2490
2491    struct TestData {
2492        int fd;
2493        uint64_t expected;
2494    };
2495
2496    int main()
2497    {
2498        // Create a concurrent queue.
2499        ffrt_queue_attr_t queue_attr;
2500        (void)ffrt_queue_attr_init(&queue_attr);
2501        ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_concurrent, "test_queue", &queue_attr);
2502
2503        // Create a loop.
2504        auto loop = ffrt_loop_create(queue_handle);
2505        int result1 = 0;
2506
2507        // Submit a task to the loop queue.
2508        std::function<void()> &&basicFunc1 = [&result1]() { result1 += 10; };
2509        ffrt_task_handle_t task = ffrt_queue_submit_h(queue_handle, ffrt::create_function_wrapper(basicFunc1, ffrt_function_kind_queue), nullptr);
2510
2511        // Create a separate thread to perform the loop.
2512        pthread_t thread;
2513        int ret = pthread_create(&thread, 0, ThreadFunc, loop);
2514        if (ret != 0) {
2515            printf("pthread_create failed!");
2516            ffrt_loop_destroy(loop);
2517            ffrt_queue_attr_destroy(&queue_attr);
2518            ffrt_queue_destroy(queue_handle);
2519            return 0;
2520        }
2521
2522        static int x = 0;
2523        int* xf = &x;
2524        void* data = xf;
2525        uint64_t timeout1 = 20;
2526        uint64_t timeout2 = 10;
2527        uint64_t expected = 0xabacadae;
2528
2529        int testFd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
2530        struct TestData testData {.fd = testFd, .expected = expected};
2531
2532        // Register a timer with the loop.
2533        ffrt_timer_t timeHandle = ffrt_loop_timer_start(loop, timeout1, data, cb, false);
2534
2535        // Register an FD listener with the loop.
2536        int ret = ffrt_loop_epoll_ctl(loop, EPOLL_CTL_ADD, testFd, EPOLLIN, (void*)(&testData), testCallBack);
2537        if (ret == 0) {
2538            printf("ffrt_loop_epoll_ctl executed successfully.\n");
2539        }
2540        ssize_t n = write(testFd, &expected, sizeof(uint64_t));
2541        usleep(25000);
2542        // Delete the FD listener.
2543        ffrt_loop_epoll_ctl(loop, EPOLL_CTL_DEL, testFd, 0, nullptr, nullptr);
2544
2545        // Stop the loop.
2546        ffrt_loop_stop(loop);
2547        pthread_join(thread, nullptr);
2548
2549        // Delete the timer.
2550        ffrt_loop_timer_stop(loop, timeHandle);
2551
2552        // Destroy the loop.
2553        ret = ffrt_loop_destroy(loop);
2554
2555        // Destroy the concurrent queue.
2556        ffrt_queue_attr_destroy(&queue_attr);
2557        ffrt_queue_destroy(queue_handle);
2558        return 0;
2559    }
2560    ```
2561
2562## Fiber
2563
2564### ffrt_fiber_t
2565
2566**Declaration**
2567
2568```c
2569struct ffrt_fiber_t;
2570```
2571
2572**Description**
2573
2574- A fiber is a lightweight user mode thread that enables efficient task scheduling and context switching within the user space.
2575- `ffrt_fiber_t` is used to save and restore the execution context of the fiber.
2576
2577**Methods**
2578
2579**ffrt_fiber_init**
2580
2581Declaration
2582
2583```c
2584FFRT_C_API int ffrt_fiber_init(ffrt_fiber_t* fiber, void(*func)(void*), void* arg, void* stack, size_t stack_size);
2585```
2586
2587Parameters
2588
2589- `fiber`: pointer to the fiber.
2590- `func`: pointer to the function when the fiber is started.
2591- `arg`: pointer to the argument when the fiber is started.
2592- `stack`: pointer to the start address of the stack space used by the fiber during execution.
2593- `stack_size`: size of the fiber stack, in bytes.
2594
2595Return Values
2596
2597- If the initialization is successful, `ffrt_success` is returned. Otherwise, `ffrt_error` is returned.
2598- The common reason of the error is that `stack_size` does not meet the minimum stack space limit that varies by platform. It is recommended that the stack space size be set to 4 KB or larger.
2599
2600Description
2601
2602- Initializes a fiber. The pointer and arguments for starting the fiber process, and the stack space used at runtime need to be transferred. The fiber does not manage any memory; the lifecycle of the stack is managed by the caller.
2603
2604**ffrt_fiber_switch**
2605
2606Declaration
2607
2608```c
2609FFRT_C_API void ffrt_fiber_switch(ffrt_fiber_t* from, ffrt_fiber_t* to);
2610```
2611
2612Parameters
2613
2614- `from`: pointer to the saved fiber context. The thread that calls this function suspends the current task.
2615- `to`: pointer to the restored fiber context. The thread that calls this function executes the task specified by `to`.
2616
2617Description
2618
2619- When the fiber context is switched, the thread that calls this function suspends the current task, saves the context to the `from` fiber, restores the context of the `to` fiber, and executes the task specified by `to`.
2620- Note that `from` and `to` are not verified. The caller must ensure the validity of these addresses to prevent process crashes.
2621