From 821c51267bcd63a5310eb1a4293f5355defbe6f4 Mon Sep 17 00:00:00 2001 From: Erik Gabriel Carrillo Date: Mon, 15 Apr 2019 16:41:28 -0500 Subject: [PATCH] timer: add function to stop all timers in a list Add a function to the timer API that allows a caller to traverse a specified set of timer lists, stopping each timer in each list, and invoking a callback function. Signed-off-by: Erik Gabriel Carrillo --- lib/librte_timer/rte_timer.c | 38 ++++++++++++++++++++++++++ lib/librte_timer/rte_timer.h | 32 ++++++++++++++++++++++ lib/librte_timer/rte_timer_version.map | 1 + 3 files changed, 71 insertions(+) diff --git a/lib/librte_timer/rte_timer.c b/lib/librte_timer/rte_timer.c index 511d90278e..ae5d2369ce 100644 --- a/lib/librte_timer/rte_timer.c +++ b/lib/librte_timer/rte_timer.c @@ -999,6 +999,44 @@ rte_timer_alt_manage(uint32_t timer_data_id, return 0; } +/* Walk pending lists, stopping timers and calling user-specified function */ +int __rte_experimental +rte_timer_stop_all(uint32_t timer_data_id, unsigned int *walk_lcores, + int nb_walk_lcores, + rte_timer_stop_all_cb_t f, void *f_arg) +{ + int i; + struct priv_timer *priv_timer; + uint32_t walk_lcore; + struct rte_timer *tim, *next_tim; + struct rte_timer_data *timer_data; + + TIMER_DATA_VALID_GET_OR_ERR_RET(timer_data_id, timer_data, -EINVAL); + + for (i = 0; i < nb_walk_lcores; i++) { + walk_lcore = walk_lcores[i]; + priv_timer = &timer_data->priv_timer[walk_lcore]; + + rte_spinlock_lock(&priv_timer->list_lock); + + for (tim = priv_timer->pending_head.sl_next[0]; + tim != NULL; + tim = next_tim) { + next_tim = tim->sl_next[0]; + + /* Call timer_stop with lock held */ + __rte_timer_stop(tim, 1, timer_data); + + if (f) + f(tim, f_arg); + } + + rte_spinlock_unlock(&priv_timer->list_lock); + } + + return 0; +} + /* dump statistics about timers */ static void __rte_timer_dump_stats(struct rte_timer_data *timer_data __rte_unused, FILE *f) diff --git a/lib/librte_timer/rte_timer.h b/lib/librte_timer/rte_timer.h index 6a9c499093..b502f8c1a2 100644 --- a/lib/librte_timer/rte_timer.h +++ b/lib/librte_timer/rte_timer.h @@ -499,6 +499,38 @@ int __rte_experimental rte_timer_alt_manage(uint32_t timer_data_id, unsigned int *poll_lcores, int n_poll_lcores, rte_timer_alt_manage_cb_t f); +/** + * Callback function type for rte_timer_stop_all(). + */ +typedef void (*rte_timer_stop_all_cb_t)(struct rte_timer *tim, void *arg); + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice + * + * Walk the pending timer lists for the specified lcore IDs, and for each timer + * that is encountered, stop it and call the specified callback function to + * process it further. + * + * @param timer_data_id + * An identifier indicating which instance of timer data should be used for + * this operation. + * @param walk_lcores + * An array of lcore ids identifying the timer lists that should be processed. + * @param nb_walk_lcores + * The size of the walk_lcores array. + * @param f + * The callback function which should be called for each timers. Can be NULL. + * @param f_arg + * An arbitrary argument that will be passed to f, if it is called. + * @return + * - 0: success + * - EINVAL: invalid timer_data_id + */ +int __rte_experimental +rte_timer_stop_all(uint32_t timer_data_id, unsigned int *walk_lcores, + int nb_walk_lcores, rte_timer_stop_all_cb_t f, void *f_arg); + /** * @warning * @b EXPERIMENTAL: this API may change without prior notice diff --git a/lib/librte_timer/rte_timer_version.map b/lib/librte_timer/rte_timer_version.map index c2e5836a3c..72f75c8181 100644 --- a/lib/librte_timer/rte_timer_version.map +++ b/lib/librte_timer/rte_timer_version.map @@ -33,5 +33,6 @@ EXPERIMENTAL { rte_timer_alt_stop; rte_timer_data_alloc; rte_timer_data_dealloc; + rte_timer_stop_all; rte_timer_subsystem_finalize; };