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