1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2014 Intel Corporation
12 * This library provides a timer service to RTE Data Plane execution
13 * units that allows the execution of callback functions asynchronously.
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.
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]
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
33 * See the RTE architecture documentation for more information about the
34 * design of this library.
40 #include <rte_common.h>
46 #define RTE_TIMER_STOP 0 /**< State: timer is stopped. */
47 #define RTE_TIMER_PENDING 1 /**< State: timer is scheduled. */
48 #define RTE_TIMER_RUNNING 2 /**< State: timer function is running. */
49 #define RTE_TIMER_CONFIG 3 /**< State: timer is being configured. */
51 #define RTE_TIMER_NO_OWNER -2 /**< Timer has no owner. */
54 * Timer type: Periodic or single (one-shot).
62 * Timer status: A union of the state (stopped, pending, running,
63 * config) and an owner (the id of the lcore that owns the timer).
65 union rte_timer_status {
68 uint16_t state; /**< Stop, pending, running, config. */
69 int16_t owner; /**< The lcore that owns the timer. */
71 uint32_t u32; /**< To atomic-set status + owner. */
74 #ifdef RTE_LIBRTE_TIMER_DEBUG
76 * A structure that stores the timer statistics (per-lcore).
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. */
89 * Callback function type for timer expiry.
91 typedef void (*rte_timer_cb_t)(struct rte_timer *, void *);
93 #define MAX_SKIPLIST_DEPTH 10
96 * A structure describing a timer in RTE.
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. */
111 * A C++ static initializer for a timer structure.
113 #define RTE_TIMER_INITIALIZER { \
116 {{RTE_TIMER_STOP, RTE_TIMER_NO_OWNER}}, \
123 * A static initializer for a timer structure.
125 #define RTE_TIMER_INITIALIZER { \
127 .state = RTE_TIMER_STOP, \
128 .owner = RTE_TIMER_NO_OWNER, \
134 * Initialize the timer library.
136 * Initializes internal variables (list, locks and so on) for the RTE
139 void rte_timer_subsystem_init(void);
142 * Initialize a timer handle.
144 * The rte_timer_init() function initializes the timer handle *tim*
145 * for use. No operations can be performed on a timer before it is
149 * The timer to initialize.
151 void rte_timer_init(struct rte_timer *tim);
154 * Reset and start the timer associated with the timer handle.
156 * The rte_timer_reset() function resets and starts the timer
157 * associated with the timer handle *tim*. When the timer expires after
158 * *ticks* HPET cycles, the function specified by *fct* will be called
159 * with the argument *arg* on core *tim_lcore*.
161 * If the timer associated with the timer handle is already running
162 * (in the RUNNING state), the function will fail. The user has to check
163 * the return value of the function to see if there is a chance that the
164 * timer is in the RUNNING state.
166 * If the timer is being configured on another core (the CONFIG state),
169 * If the timer is pending or stopped, it will be rescheduled with the
175 * The number of cycles (see rte_get_hpet_hz()) before the callback
176 * function is called.
178 * The type can be either:
179 * - PERIODICAL: The timer is automatically reloaded after execution
180 * (returns to the PENDING state)
181 * - SINGLE: The timer is one-shot, that is, the timer goes to a
182 * STOPPED state after execution.
184 * The ID of the lcore where the timer callback function has to be
185 * executed. If tim_lcore is LCORE_ID_ANY, the timer library will
186 * launch it on a different core for each call (round-robin).
188 * The callback function of the timer.
190 * The user argument of the callback function.
192 * - 0: Success; the timer is scheduled.
193 * - (-1): Timer is in the RUNNING or CONFIG state.
195 int rte_timer_reset(struct rte_timer *tim, uint64_t ticks,
196 enum rte_timer_type type, unsigned tim_lcore,
197 rte_timer_cb_t fct, void *arg);
201 * Loop until rte_timer_reset() succeeds.
203 * Reset and start the timer associated with the timer handle. Always
204 * succeed. See rte_timer_reset() for details.
209 * The number of cycles (see rte_get_hpet_hz()) before the callback
210 * function is called.
212 * The type can be either:
213 * - PERIODICAL: The timer is automatically reloaded after execution
214 * (returns to the PENDING state)
215 * - SINGLE: The timer is one-shot, that is, the timer goes to a
216 * STOPPED state after execution.
218 * The ID of the lcore where the timer callback function has to be
219 * executed. If tim_lcore is LCORE_ID_ANY, the timer library will
220 * launch it on a different core for each call (round-robin).
222 * The callback function of the timer.
224 * The user argument of the callback function.
227 rte_timer_reset_sync(struct rte_timer *tim, uint64_t ticks,
228 enum rte_timer_type type, unsigned tim_lcore,
229 rte_timer_cb_t fct, void *arg);
234 * The rte_timer_stop() function stops the timer associated with the
235 * timer handle *tim*. It may fail if the timer is currently running or
238 * If the timer is pending or stopped (for instance, already expired),
239 * the function will succeed. The timer handle tim must have been
240 * initialized using rte_timer_init(), otherwise, undefined behavior
243 * This function can be called safely from a timer callback. If it
244 * succeeds, the timer is not referenced anymore by the timer library
245 * and the timer structure can be freed (even in the callback
251 * - 0: Success; the timer is stopped.
252 * - (-1): The timer is in the RUNNING or CONFIG state.
254 int rte_timer_stop(struct rte_timer *tim);
258 * Loop until rte_timer_stop() succeeds.
260 * After a call to this function, the timer identified by *tim* is
261 * stopped. See rte_timer_stop() for details.
266 void rte_timer_stop_sync(struct rte_timer *tim);
269 * Test if a timer is pending.
271 * The rte_timer_pending() function tests the PENDING status
272 * of the timer handle *tim*. A PENDING timer is one that has been
273 * scheduled and whose function has not yet been called.
278 * - 0: The timer is not pending.
279 * - 1: The timer is pending.
281 int rte_timer_pending(struct rte_timer *tim);
284 * Manage the timer list and execute callback functions.
286 * This function must be called periodically from EAL lcores
287 * main_loop(). It browses the list of pending timers and runs all
288 * timers that are expired.
290 * The precision of the timer depends on the call frequency of this
291 * function. However, the more often the function is called, the more
292 * CPU resources it will use.
294 void rte_timer_manage(void);
297 * Dump statistics about timers.
300 * A pointer to a file for output
302 void rte_timer_dump_stats(FILE *f);
308 #endif /* _RTE_TIMER_H_ */