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