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