2196934b2e2926f155f46e19bb48ed4e117f3d63
[dpdk.git] / lib / librte_timer / rte_timer.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  */
4
5 #ifndef _RTE_TIMER_H_
6 #define _RTE_TIMER_H_
7
8 /**
9  * @file
10  RTE Timer
11  *
12  * This library provides a timer service to RTE Data Plane execution
13  * units that allows the execution of callback functions asynchronously.
14  *
15  * - Timers can be periodic or single (one-shot).
16  * - The timers can be loaded from one core and executed on another. This has
17  *   to be specified in the call to rte_timer_reset().
18  * - High precision is possible. NOTE: this depends on the call frequency to
19  *   rte_timer_manage() that check the timer expiration for the local core.
20  * - If not used in an application, for improved performance, it can be
21  *   disabled at compilation time by not calling the rte_timer_manage()
22  *   to improve performance.
23  *
24  * The timer library uses the rte_get_hpet_cycles() function that
25  * uses the HPET, when available, to provide a reliable time reference. [HPET
26  * routines are provided by EAL, which falls back to using the chip TSC (time-
27  * stamp counter) as fallback when HPET is not available]
28  *
29  * This library provides an interface to add, delete and restart a
30  * timer. The API is based on the BSD callout(9) API with a few
31  * differences.
32  *
33  * See the RTE architecture documentation for more information about the
34  * design of this library.
35  */
36
37 #include <stdio.h>
38 #include <stdint.h>
39 #include <stddef.h>
40 #include <rte_common.h>
41 #include <rte_config.h>
42 #include <rte_spinlock.h>
43
44 #ifdef __cplusplus
45 extern "C" {
46 #endif
47
48 #define RTE_TIMER_STOP    0 /**< State: timer is stopped. */
49 #define RTE_TIMER_PENDING 1 /**< State: timer is scheduled. */
50 #define RTE_TIMER_RUNNING 2 /**< State: timer function is running. */
51 #define RTE_TIMER_CONFIG  3 /**< State: timer is being configured. */
52
53 #define RTE_TIMER_NO_OWNER -2 /**< Timer has no owner. */
54
55 /**
56  * Timer type: Periodic or single (one-shot).
57  */
58 enum rte_timer_type {
59         SINGLE,
60         PERIODICAL
61 };
62
63 /**
64  * Timer status: A union of the state (stopped, pending, running,
65  * config) and an owner (the id of the lcore that owns the timer).
66  */
67 union rte_timer_status {
68         RTE_STD_C11
69         struct {
70                 uint16_t state;  /**< Stop, pending, running, config. */
71                 int16_t owner;   /**< The lcore that owns the timer. */
72         };
73         uint32_t u32;            /**< To atomic-set status + owner. */
74 };
75
76 #ifdef RTE_LIBRTE_TIMER_DEBUG
77 /**
78  * A structure that stores the timer statistics (per-lcore).
79  */
80 struct rte_timer_debug_stats {
81         uint64_t reset;   /**< Number of success calls to rte_timer_reset(). */
82         uint64_t stop;    /**< Number of success calls to rte_timer_stop(). */
83         uint64_t manage;  /**< Number of calls to rte_timer_manage(). */
84         uint64_t pending; /**< Number of pending/running timers. */
85 };
86 #endif
87
88 struct rte_timer;
89
90 /**
91  * Callback function type for timer expiry.
92  */
93 typedef void (*rte_timer_cb_t)(struct rte_timer *, void *);
94
95 #define MAX_SKIPLIST_DEPTH 10
96
97 /**
98  * A structure describing a timer in RTE.
99  */
100 struct rte_timer
101 {
102         uint64_t expire;       /**< Time when timer expire. */
103         struct rte_timer *sl_next[MAX_SKIPLIST_DEPTH];
104         volatile union rte_timer_status status; /**< Status of timer. */
105         uint64_t period;       /**< Period of timer (0 if not periodic). */
106         rte_timer_cb_t f;      /**< Callback function. */
107         void *arg;             /**< Argument to callback function. */
108 };
109
110
111 #ifdef __cplusplus
112 /**
113  * A C++ static initializer for a timer structure.
114  */
115 #define RTE_TIMER_INITIALIZER {             \
116         0,                                      \
117         {NULL},                                 \
118         {{RTE_TIMER_STOP, RTE_TIMER_NO_OWNER}}, \
119         0,                                      \
120         NULL,                                   \
121         NULL,                                   \
122         }
123 #else
124 /**
125  * A static initializer for a timer structure.
126  */
127 #define RTE_TIMER_INITIALIZER {                      \
128                 .status = {{                         \
129                         .state = RTE_TIMER_STOP,     \
130                         .owner = RTE_TIMER_NO_OWNER, \
131                 }},                                  \
132         }
133 #endif
134
135 /**
136  * @warning
137  * @b EXPERIMENTAL: this API may change without prior notice
138  *
139  * Allocate a timer data instance in shared memory to track a set of pending
140  * timer lists.
141  *
142  * @param id_ptr
143  *   Pointer to variable into which to write the identifier of the allocated
144  *   timer data instance.
145  *
146  * @return
147  *   - 0: Success
148  *   - -ENOSPC: maximum number of timer data instances already allocated
149  */
150 int __rte_experimental rte_timer_data_alloc(uint32_t *id_ptr);
151
152 /**
153  * @warning
154  * @b EXPERIMENTAL: this API may change without prior notice
155  *
156  * Deallocate a timer data instance.
157  *
158  * @param id
159  *   Identifier of the timer data instance to deallocate.
160  *
161  * @return
162  *   - 0: Success
163  *   - -EINVAL: invalid timer data instance identifier
164  */
165 int __rte_experimental rte_timer_data_dealloc(uint32_t id);
166
167 /**
168  * Initialize the timer library.
169  *
170  * Initializes internal variables (list, locks and so on) for the RTE
171  * timer library.
172  *
173  * @return
174  *   - 0: Success
175  *   - -EEXIST: Returned in secondary process when primary process has not
176  *      yet initialized the timer subsystem
177  *   - -ENOMEM: Unable to allocate memory needed to initialize timer
178  *      subsystem
179  */
180 int rte_timer_subsystem_init(void);
181 int rte_timer_subsystem_init_v1905(void);
182 void rte_timer_subsystem_init_v20(void);
183
184 /**
185  * @warning
186  * @b EXPERIMENTAL: this API may change without prior notice
187  *
188  * Free timer subsystem resources.
189  */
190 void __rte_experimental rte_timer_subsystem_finalize(void);
191
192 /**
193  * Initialize a timer handle.
194  *
195  * The rte_timer_init() function initializes the timer handle *tim*
196  * for use. No operations can be performed on a timer before it is
197  * initialized.
198  *
199  * @param tim
200  *   The timer to initialize.
201  */
202 void rte_timer_init(struct rte_timer *tim);
203
204 /**
205  * Reset and start the timer associated with the timer handle.
206  *
207  * The rte_timer_reset() function resets and starts the timer
208  * associated with the timer handle *tim*. When the timer expires after
209  * *ticks* HPET cycles, the function specified by *fct* will be called
210  * with the argument *arg* on core *tim_lcore*.
211  *
212  * If the timer associated with the timer handle is already running
213  * (in the RUNNING state), the function will fail. The user has to check
214  * the return value of the function to see if there is a chance that the
215  * timer is in the RUNNING state.
216  *
217  * If the timer is being configured on another core (the CONFIG state),
218  * it will also fail.
219  *
220  * If the timer is pending or stopped, it will be rescheduled with the
221  * new parameters.
222  *
223  * @param tim
224  *   The timer handle.
225  * @param ticks
226  *   The number of cycles (see rte_get_hpet_hz()) before the callback
227  *   function is called.
228  * @param type
229  *   The type can be either:
230  *   - PERIODICAL: The timer is automatically reloaded after execution
231  *     (returns to the PENDING state)
232  *   - SINGLE: The timer is one-shot, that is, the timer goes to a
233  *     STOPPED state after execution.
234  * @param tim_lcore
235  *   The ID of the lcore where the timer callback function has to be
236  *   executed. If tim_lcore is LCORE_ID_ANY, the timer library will
237  *   launch it on a different core for each call (round-robin).
238  * @param fct
239  *   The callback function of the timer.
240  * @param arg
241  *   The user argument of the callback function.
242  * @return
243  *   - 0: Success; the timer is scheduled.
244  *   - (-1): Timer is in the RUNNING or CONFIG state.
245  */
246 int rte_timer_reset(struct rte_timer *tim, uint64_t ticks,
247                     enum rte_timer_type type, unsigned tim_lcore,
248                     rte_timer_cb_t fct, void *arg);
249 int rte_timer_reset_v1905(struct rte_timer *tim, uint64_t ticks,
250                           enum rte_timer_type type, unsigned int tim_lcore,
251                           rte_timer_cb_t fct, void *arg);
252 int rte_timer_reset_v20(struct rte_timer *tim, uint64_t ticks,
253                         enum rte_timer_type type, unsigned int tim_lcore,
254                         rte_timer_cb_t fct, void *arg);
255
256
257 /**
258  * Loop until rte_timer_reset() succeeds.
259  *
260  * Reset and start the timer associated with the timer handle. Always
261  * succeed. See rte_timer_reset() for details.
262  *
263  * @param tim
264  *   The timer handle.
265  * @param ticks
266  *   The number of cycles (see rte_get_hpet_hz()) before the callback
267  *   function is called.
268  * @param type
269  *   The type can be either:
270  *   - PERIODICAL: The timer is automatically reloaded after execution
271  *     (returns to the PENDING state)
272  *   - SINGLE: The timer is one-shot, that is, the timer goes to a
273  *     STOPPED state after execution.
274  * @param tim_lcore
275  *   The ID of the lcore where the timer callback function has to be
276  *   executed. If tim_lcore is LCORE_ID_ANY, the timer library will
277  *   launch it on a different core for each call (round-robin).
278  * @param fct
279  *   The callback function of the timer.
280  * @param arg
281  *   The user argument of the callback function.
282  */
283 void
284 rte_timer_reset_sync(struct rte_timer *tim, uint64_t ticks,
285                      enum rte_timer_type type, unsigned tim_lcore,
286                      rte_timer_cb_t fct, void *arg);
287
288 /**
289  * Stop a timer.
290  *
291  * The rte_timer_stop() function stops the timer associated with the
292  * timer handle *tim*. It may fail if the timer is currently running or
293  * being configured.
294  *
295  * If the timer is pending or stopped (for instance, already expired),
296  * the function will succeed. The timer handle tim must have been
297  * initialized using rte_timer_init(), otherwise, undefined behavior
298  * will occur.
299  *
300  * This function can be called safely from a timer callback. If it
301  * succeeds, the timer is not referenced anymore by the timer library
302  * and the timer structure can be freed (even in the callback
303  * function).
304  *
305  * @param tim
306  *   The timer handle.
307  * @return
308  *   - 0: Success; the timer is stopped.
309  *   - (-1): The timer is in the RUNNING or CONFIG state.
310  */
311 int rte_timer_stop(struct rte_timer *tim);
312 int rte_timer_stop_v1905(struct rte_timer *tim);
313 int rte_timer_stop_v20(struct rte_timer *tim);
314
315 /**
316  * Loop until rte_timer_stop() succeeds.
317  *
318  * After a call to this function, the timer identified by *tim* is
319  * stopped. See rte_timer_stop() for details.
320  *
321  * @param tim
322  *   The timer handle.
323  */
324 void rte_timer_stop_sync(struct rte_timer *tim);
325
326 /**
327  * Test if a timer is pending.
328  *
329  * The rte_timer_pending() function tests the PENDING status
330  * of the timer handle *tim*. A PENDING timer is one that has been
331  * scheduled and whose function has not yet been called.
332  *
333  * @param tim
334  *   The timer handle.
335  * @return
336  *   - 0: The timer is not pending.
337  *   - 1: The timer is pending.
338  */
339 int rte_timer_pending(struct rte_timer *tim);
340
341 /**
342  * Manage the timer list and execute callback functions.
343  *
344  * This function must be called periodically from EAL lcores
345  * main_loop(). It browses the list of pending timers and runs all
346  * timers that are expired.
347  *
348  * The precision of the timer depends on the call frequency of this
349  * function. However, the more often the function is called, the more
350  * CPU resources it will use.
351  *
352  * @return
353  *   - 0: Success
354  *   - -EINVAL: timer subsystem not yet initialized
355  */
356 int rte_timer_manage(void);
357 int rte_timer_manage_v1905(void);
358 void rte_timer_manage_v20(void);
359
360 /**
361  * Dump statistics about timers.
362  *
363  * @param f
364  *   A pointer to a file for output
365  * @return
366  *   - 0: Success
367  *   - -EINVAL: timer subsystem not yet initialized
368  */
369 int rte_timer_dump_stats(FILE *f);
370 int rte_timer_dump_stats_v1905(FILE *f);
371 void rte_timer_dump_stats_v20(FILE *f);
372
373 /**
374  * @warning
375  * @b EXPERIMENTAL: this API may change without prior notice
376  *
377  * This function is the same as rte_timer_reset(), except that it allows a
378  * caller to specify the rte_timer_data instance containing the list to which
379  * the timer should be added.
380  *
381  * @see rte_timer_reset()
382  *
383  * @param timer_data_id
384  *   An identifier indicating which instance of timer data should be used for
385  *   this operation.
386  * @param tim
387  *   The timer handle.
388  * @param ticks
389  *   The number of cycles (see rte_get_hpet_hz()) before the callback
390  *   function is called.
391  * @param type
392  *   The type can be either:
393  *   - PERIODICAL: The timer is automatically reloaded after execution
394  *     (returns to the PENDING state)
395  *   - SINGLE: The timer is one-shot, that is, the timer goes to a
396  *     STOPPED state after execution.
397  * @param tim_lcore
398  *   The ID of the lcore where the timer callback function has to be
399  *   executed. If tim_lcore is LCORE_ID_ANY, the timer library will
400  *   launch it on a different core for each call (round-robin).
401  * @param fct
402  *   The callback function of the timer. This parameter can be NULL if (and
403  *   only if) rte_timer_alt_manage() will be used to manage this timer.
404  * @param arg
405  *   The user argument of the callback function.
406  * @return
407  *   - 0: Success; the timer is scheduled.
408  *   - (-1): Timer is in the RUNNING or CONFIG state.
409  *   - -EINVAL: invalid timer_data_id
410  */
411 int __rte_experimental
412 rte_timer_alt_reset(uint32_t timer_data_id, struct rte_timer *tim,
413                     uint64_t ticks, enum rte_timer_type type,
414                     unsigned int tim_lcore, rte_timer_cb_t fct, void *arg);
415
416 /**
417  * @warning
418  * @b EXPERIMENTAL: this API may change without prior notice
419  *
420  * This function is the same as rte_timer_stop(), except that it allows a
421  * caller to specify the rte_timer_data instance containing the list from which
422  * this timer should be removed.
423  *
424  * @see rte_timer_stop()
425  *
426  * @param timer_data_id
427  *   An identifier indicating which instance of timer data should be used for
428  *   this operation.
429  * @param tim
430  *   The timer handle.
431  * @return
432  *   - 0: Success; the timer is stopped.
433  *   - (-1): The timer is in the RUNNING or CONFIG state.
434  *   - -EINVAL: invalid timer_data_id
435  */
436 int __rte_experimental
437 rte_timer_alt_stop(uint32_t timer_data_id, struct rte_timer *tim);
438
439 /**
440  * Callback function type for rte_timer_alt_manage().
441  */
442 typedef void (*rte_timer_alt_manage_cb_t)(struct rte_timer *tim);
443
444 /**
445  * @warning
446  * @b EXPERIMENTAL: this API may change without prior notice
447  *
448  * Manage a set of timer lists and execute the specified callback function for
449  * all expired timers. This function is similar to rte_timer_manage(), except
450  * that it allows a caller to specify the timer_data instance that should
451  * be operated on, as well as a set of lcore IDs identifying which timer lists
452  * should be processed.  Callback functions of individual timers are ignored.
453  *
454  * @see rte_timer_manage()
455  *
456  * @param timer_data_id
457  *   An identifier indicating which instance of timer data should be used for
458  *   this operation.
459  * @param poll_lcores
460  *   An array of lcore ids identifying the timer lists that should be processed.
461  *   NULL is allowed - if NULL, the timer list corresponding to the lcore
462  *   calling this routine is processed (same as rte_timer_manage()).
463  * @param n_poll_lcores
464  *   The size of the poll_lcores array. If 'poll_lcores' is NULL, this parameter
465  *   is ignored.
466  * @param f
467  *   The callback function which should be called for all expired timers.
468  * @return
469  *   - 0: success
470  *   - -EINVAL: invalid timer_data_id
471  */
472 int __rte_experimental
473 rte_timer_alt_manage(uint32_t timer_data_id, unsigned int *poll_lcores,
474                      int n_poll_lcores, rte_timer_alt_manage_cb_t f);
475
476 /**
477  * Callback function type for rte_timer_stop_all().
478  */
479 typedef void (*rte_timer_stop_all_cb_t)(struct rte_timer *tim, void *arg);
480
481 /**
482  * @warning
483  * @b EXPERIMENTAL: this API may change without prior notice
484  *
485  * Walk the pending timer lists for the specified lcore IDs, and for each timer
486  * that is encountered, stop it and call the specified callback function to
487  * process it further.
488  *
489  * @param timer_data_id
490  *   An identifier indicating which instance of timer data should be used for
491  *   this operation.
492  * @param walk_lcores
493  *   An array of lcore ids identifying the timer lists that should be processed.
494  * @param nb_walk_lcores
495  *   The size of the walk_lcores array.
496  * @param f
497  *   The callback function which should be called for each timers. Can be NULL.
498  * @param f_arg
499  *   An arbitrary argument that will be passed to f, if it is called.
500  * @return
501  *   - 0: success
502  *   - EINVAL: invalid timer_data_id
503  */
504 int __rte_experimental
505 rte_timer_stop_all(uint32_t timer_data_id, unsigned int *walk_lcores,
506                    int nb_walk_lcores, rte_timer_stop_all_cb_t f, void *f_arg);
507
508 /**
509  * @warning
510  * @b EXPERIMENTAL: this API may change without prior notice
511  *
512  * This function is the same as rte_timer_dump_stats(), except that it allows
513  * the caller to specify the rte_timer_data instance that should be used.
514  *
515  * @see rte_timer_dump_stats()
516  *
517  * @param timer_data_id
518  *   An identifier indicating which instance of timer data should be used for
519  *   this operation.
520  * @param f
521  *   A pointer to a file for output
522  * @return
523  *   - 0: success
524  *   - -EINVAL: invalid timer_data_id
525  */
526 int __rte_experimental
527 rte_timer_alt_dump_stats(uint32_t timer_data_id, FILE *f);
528
529 #ifdef __cplusplus
530 }
531 #endif
532
533 #endif /* _RTE_TIMER_H_ */