It is common that sample applications call rte_eal_wait_lcore() while waiting for worker threads to be terminated. Mostly master lcore keeps waiting in this function.
The waiting app for termination is not a time critical task, app can prefer a sleep version of the waiting to consume less cycles. A sleeping version of the API, rte_eal_wait_lcore_sleep(), has been added which gets sleeping interval as parameter. Sample applications will be updated later to use this API. Signed-off-by: Ferruh Yigit <ferruh.yi...@intel.com> --- lib/librte_eal/common/eal_common_launch.c | 22 ++++++++++++++++++ lib/librte_eal/common/include/rte_launch.h | 27 ++++++++++++++++++++++ lib/librte_eal/rte_eal_version.map | 1 + 3 files changed, 50 insertions(+) diff --git a/lib/librte_eal/common/eal_common_launch.c b/lib/librte_eal/common/eal_common_launch.c index fe0ba3f0d..e804c70c3 100644 --- a/lib/librte_eal/common/eal_common_launch.c +++ b/lib/librte_eal/common/eal_common_launch.c @@ -5,6 +5,7 @@ #include <errno.h> #include <stdint.h> #include <stdio.h> +#include <unistd.h> #include <sys/queue.h> #include <rte_launch.h> @@ -35,6 +36,27 @@ rte_eal_wait_lcore(unsigned slave_id) return lcore_config[slave_id].ret; } +/* + * Wait until a lcore finished its job by sleeping. + * Sleep time will be times of 'usec' + */ +int +rte_eal_wait_lcore_sleep(unsigned slave_id, size_t usec) +{ + if (lcore_config[slave_id].state == WAIT) + return 0; + + while (lcore_config[slave_id].state != WAIT && + lcore_config[slave_id].state != FINISHED) + usleep(usec); + + rte_rmb(); + + /* we are in finished state, go to wait state */ + lcore_config[slave_id].state = WAIT; + return lcore_config[slave_id].ret; +} + /* * Check that every SLAVE lcores are in WAIT state, then call * rte_eal_remote_launch() for all of them. If call_master is true diff --git a/lib/librte_eal/common/include/rte_launch.h b/lib/librte_eal/common/include/rte_launch.h index 06a671752..a935fd8b5 100644 --- a/lib/librte_eal/common/include/rte_launch.h +++ b/lib/librte_eal/common/include/rte_launch.h @@ -11,6 +11,8 @@ * Launch tasks on other lcores */ +#include <rte_compat.h> + #ifdef __cplusplus extern "C" { #endif @@ -129,6 +131,31 @@ enum rte_lcore_state_t rte_eal_get_lcore_state(unsigned slave_id); */ int rte_eal_wait_lcore(unsigned slave_id); + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice + * + * Wait until an lcore finishes its job. + * + * To be executed on the MASTER lcore only. + * + * Same as rte_eal_wait_lcore() but sleeps instead of busy wait. + * + * @param slave_id + * The identifier of the lcore. + * @param usec + * The sleep interval in microseconds + * @return + * - 0: If the lcore identified by the slave_id is in a WAIT state. + * - The value that was returned by the previous remote launch + * function call if the lcore identified by the slave_id was in a + * FINISHED or RUNNING state. In this case, it changes the state + * of the lcore to WAIT. + */ +__rte_experimental int +rte_eal_wait_lcore_sleep(unsigned slave_id, size_t usec); + /** * Wait until all lcores finish their jobs. * diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map index e968edc2e..6c636a65d 100644 --- a/lib/librte_eal/rte_eal_version.map +++ b/lib/librte_eal/rte_eal_version.map @@ -292,6 +292,7 @@ EXPERIMENTAL { rte_devargs_remove; rte_devargs_type_count; rte_eal_cleanup; + rte_eal_wait_lcore_sleep; rte_fbarray_attach; rte_fbarray_destroy; rte_fbarray_detach; -- 2.17.1