timer: add function to stop all timers in a list
authorErik Gabriel Carrillo <erik.g.carrillo@intel.com>
Mon, 15 Apr 2019 21:41:28 +0000 (16:41 -0500)
committerThomas Monjalon <thomas@monjalon.net>
Wed, 17 Apr 2019 18:05:30 +0000 (20:05 +0200)
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 <erik.g.carrillo@intel.com>
lib/librte_timer/rte_timer.c
lib/librte_timer/rte_timer.h
lib/librte_timer/rte_timer_version.map

index 511d902..ae5d236 100644 (file)
@@ -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)
index 6a9c499..b502f8c 100644 (file)
@@ -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
index c2e5836..72f75c8 100644 (file)
@@ -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;
 };