This patch adds coroutine example, usage:
1. start examples: dpdk-coroutine -a 0000:7d:00.2  -l 10-11
2. will output:
Start yield coroutine test!
        I am in yield coroutine 111!
        I am in yield coroutine 222!
        I am in yield coroutine 333!
        I am in yield coroutine 111!
        I am in yield coroutine 222!
        I am in yield coroutine 333!
...
Start delay coroutine test!
        I am in delay coroutine 111!
        I am in delay coroutine 222!
        I am in delay coroutine 222!
        I am in delay coroutine 111!
        I am in delay coroutine 222!
        I am in delay coroutine 222!
...
3. use ctrl+c to exit example.

Signed-off-by: Chengwen Feng <fengcheng...@huawei.com>
---
 examples/coroutine/main.c      | 153 +++++++++++++++++++++++++++++++++
 examples/coroutine/meson.build |  10 +++
 examples/meson.build           |   1 +
 3 files changed, 164 insertions(+)
 create mode 100644 examples/coroutine/main.c
 create mode 100644 examples/coroutine/meson.build

diff --git a/examples/coroutine/main.c b/examples/coroutine/main.c
new file mode 100644
index 0000000000..2704ad1dc9
--- /dev/null
+++ b/examples/coroutine/main.c
@@ -0,0 +1,153 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 HiSilicon Limited
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <unistd.h>
+
+#include <rte_common.h>
+#include <rte_coroutine.h>
+#include <rte_lcore.h>
+#include <rte_launch.h>
+
+static volatile bool force_quit;
+
+static struct rte_schedule *target_s;
+
+static void
+yield_coroutine_1(void *arg)
+{
+       RTE_SET_USED(arg);
+       int i = 10;
+       while (i--) {
+               printf("\tI am in yield coroutine 111!\n");
+               rte_co_yield();
+       }
+}
+
+static void
+yield_coroutine_2(void *arg)
+{
+       RTE_SET_USED(arg);
+       int i = 10;
+       while (i--) {
+               printf("\tI am in yield coroutine 222!\n");
+               rte_co_yield();
+       }
+}
+
+static void
+yield_coroutine_3(void *arg)
+{
+       RTE_SET_USED(arg);
+       int i = 10;
+       while (i--) {
+               printf("\tI am in yield coroutine 333!\n");
+               rte_co_yield();
+       }
+}
+
+static void
+yield_coroutine_test(void)
+{
+       printf("Start yield coroutine test!\n");
+       rte_co_create(target_s, yield_coroutine_1, NULL, 0);
+       rte_co_create(target_s, yield_coroutine_2, NULL, 0);
+       rte_co_create(target_s, yield_coroutine_3, NULL, 0);
+       sleep(1);
+}
+
+static void
+delay_coroutine_1(void *arg)
+{
+       RTE_SET_USED(arg);
+       int i = 10;
+       while (i--) {
+               printf("\tI am in delay coroutine 111!\n");
+               rte_co_delay(100 * 1000);
+       }
+}
+
+static void
+delay_coroutine_2(void *arg)
+{
+       RTE_SET_USED(arg);
+       int i = 20;
+       while (i--) {
+               printf("\tI am in delay coroutine 222!\n");
+               rte_co_delay(50 * 1000);
+       }
+}
+
+static void
+delay_coroutine_test(void)
+{
+       printf("Start delay coroutine test!\n");
+       rte_co_create(target_s, delay_coroutine_1, NULL, 0);
+       rte_co_create(target_s, delay_coroutine_2, NULL, 0);
+       sleep(1);
+}
+
+static int
+co_main_loop(void *arg)
+{
+       RTE_SET_USED(arg);
+       while (!force_quit)
+               rte_schedule_run(target_s);
+       return 0;
+}
+
+static void
+signal_handler(int signum)
+{
+       if (signum == SIGINT || signum == SIGTERM) {
+               printf("\n\nSignal %d received, preparing to exit...\n",
+                       signum);
+               force_quit = true;
+       }
+}
+
+int
+main(int argc, char **argv)
+{
+       uint32_t lcore_id = rte_lcore_id();
+       int ret;
+
+       /* Init EAL. 8< */
+       ret = rte_eal_init(argc, argv);
+       if (ret < 0)
+               rte_exit(EXIT_FAILURE, "Invalid EAL arguments\n");
+
+       force_quit = false;
+       signal(SIGINT, signal_handler);
+       signal(SIGTERM, signal_handler);
+
+       /* Check if there is enough lcores for all ports. */
+       if (rte_lcore_count() < 2)
+               rte_exit(EXIT_FAILURE,
+                       "There should be at least one worker lcore.\n");
+
+       target_s = rte_schedule_create("co-sched-test", 128);
+       if (target_s == NULL)
+               rte_exit(EXIT_FAILURE,
+                       "Create target scheduler failed!\n");
+
+       lcore_id = rte_get_next_lcore(lcore_id, true, true);
+       rte_eal_remote_launch(co_main_loop, NULL, lcore_id);
+
+       yield_coroutine_test();
+       delay_coroutine_test();
+
+       /* force_quit is true when we get here */
+       rte_eal_mp_wait_lcore();
+
+       /* clean up the EAL */
+       rte_eal_cleanup();
+
+       printf("Bye...\n");
+       return 0;
+}
diff --git a/examples/coroutine/meson.build b/examples/coroutine/meson.build
new file mode 100644
index 0000000000..c3576fe2f3
--- /dev/null
+++ b/examples/coroutine/meson.build
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2023 HiSilicon Limited
+
+allow_experimental_apis = true
+
+deps += ['coroutine']
+
+sources = files(
+        'main.c',
+)
diff --git a/examples/meson.build b/examples/meson.build
index 6968c09252..111d628065 100644
--- a/examples/meson.build
+++ b/examples/meson.build
@@ -11,6 +11,7 @@ all_examples = [
         'bbdev_app',
         'bond',
         'cmdline',
+       'coroutine',
         'distributor',
         'dma',
         'ethtool',
-- 
2.17.1

Reply via email to