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