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>
41 #include <rte_config.h>
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. */
52 #define RTE_TIMER_NO_OWNER -2 /**< Timer has no owner. */
55 * Timer type: Periodic or single (one-shot).
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).
66 union rte_timer_status {
69 uint16_t state; /**< Stop, pending, running, config. */
70 int16_t owner; /**< The lcore that owns the timer. */
72 uint32_t u32; /**< To atomic-set status + owner. */
75 #ifdef RTE_LIBRTE_TIMER_DEBUG
77 * A structure that stores the timer statistics (per-lcore).
79 struct rte_timer_debug_stats {
80 uint64_t reset; /**< Number of success calls to rte_timer_reset(). */
81 uint64_t stop; /**< Number of success calls to rte_timer_stop(). */
82 uint64_t manage; /**< Number of calls to rte_timer_manage(). */
83 uint64_t pending; /**< Number of pending/running timers. */
90 * Callback function type for timer expiry.
92 typedef void (*rte_timer_cb_t)(struct rte_timer *, void *);
94 #define MAX_SKIPLIST_DEPTH 10
97 * A structure describing a timer in RTE.
101 uint64_t expire; /**< Time when timer expire. */
102 struct rte_timer *sl_next[MAX_SKIPLIST_DEPTH];
103 volatile union rte_timer_status status; /**< Status of timer. */
104 uint64_t period; /**< Period of timer (0 if not periodic). */
105 rte_timer_cb_t f; /**< Callback function. */
106 void *arg; /**< Argument to callback function. */
112 * A C++ static initializer for a timer structure.
114 #define RTE_TIMER_INITIALIZER { \
117 {{RTE_TIMER_STOP, RTE_TIMER_NO_OWNER}}, \
124 * A static initializer for a timer structure.
126 #define RTE_TIMER_INITIALIZER { \
128 .state = RTE_TIMER_STOP, \
129 .owner = RTE_TIMER_NO_OWNER, \
135 * Initialize the timer library.
137 * Initializes internal variables (list, locks and so on) for the RTE
140 void rte_timer_subsystem_init(void);
143 * Initialize a timer handle.
145 * The rte_timer_init() function initializes the timer handle *tim*
146 * for use. No operations can be performed on a timer before it is
150 * The timer to initialize.
152 void rte_timer_init(struct rte_timer *tim);
155 * Reset and start the timer associated with the timer handle.
157 * The rte_timer_reset() function resets and starts the timer
158 * associated with the timer handle *tim*. When the timer expires after
159 * *ticks* HPET cycles, the function specified by *fct* will be called
160 * with the argument *arg* on core *tim_lcore*.
162 * If the timer associated with the timer handle is already running
163 * (in the RUNNING state), the function will fail. The user has to check
164 * the return value of the function to see if there is a chance that the
165 * timer is in the RUNNING state.
167 * If the timer is being configured on another core (the CONFIG state),
170 * If the timer is pending or stopped, it will be rescheduled with the
176 * The number of cycles (see rte_get_hpet_hz()) before the callback
177 * function is called.
179 * The type can be either:
180 * - PERIODICAL: The timer is automatically reloaded after execution
181 * (returns to the PENDING state)
182 * - SINGLE: The timer is one-shot, that is, the timer goes to a
183 * STOPPED state after execution.
185 * The ID of the lcore where the timer callback function has to be
186 * executed. If tim_lcore is LCORE_ID_ANY, the timer library will
187 * launch it on a different core for each call (round-robin).
189 * The callback function of the timer.
191 * The user argument of the callback function.
193 * - 0: Success; the timer is scheduled.
194 * - (-1): Timer is in the RUNNING or CONFIG state.
196 int rte_timer_reset(struct rte_timer *tim, uint64_t ticks,
197 enum rte_timer_type type, unsigned tim_lcore,
198 rte_timer_cb_t fct, void *arg);
202 * Loop until rte_timer_reset() succeeds.
204 * Reset and start the timer associated with the timer handle. Always
205 * succeed. See rte_timer_reset() for details.
210 * The number of cycles (see rte_get_hpet_hz()) before the callback
211 * function is called.
213 * The type can be either:
214 * - PERIODICAL: The timer is automatically reloaded after execution
215 * (returns to the PENDING state)
216 * - SINGLE: The timer is one-shot, that is, the timer goes to a
217 * STOPPED state after execution.
219 * The ID of the lcore where the timer callback function has to be
220 * executed. If tim_lcore is LCORE_ID_ANY, the timer library will
221 * launch it on a different core for each call (round-robin).
223 * The callback function of the timer.
225 * The user argument of the callback function.
228 rte_timer_reset_sync(struct rte_timer *tim, uint64_t ticks,
229 enum rte_timer_type type, unsigned tim_lcore,
230 rte_timer_cb_t fct, void *arg);
235 * The rte_timer_stop() function stops the timer associated with the
236 * timer handle *tim*. It may fail if the timer is currently running or
239 * If the timer is pending or stopped (for instance, already expired),
240 * the function will succeed. The timer handle tim must have been
241 * initialized using rte_timer_init(), otherwise, undefined behavior
244 * This function can be called safely from a timer callback. If it
245 * succeeds, the timer is not referenced anymore by the timer library
246 * and the timer structure can be freed (even in the callback
252 * - 0: Success; the timer is stopped.
253 * - (-1): The timer is in the RUNNING or CONFIG state.
255 int rte_timer_stop(struct rte_timer *tim);
259 * Loop until rte_timer_stop() succeeds.
261 * After a call to this function, the timer identified by *tim* is
262 * stopped. See rte_timer_stop() for details.
267 void rte_timer_stop_sync(struct rte_timer *tim);
270 * Test if a timer is pending.
272 * The rte_timer_pending() function tests the PENDING status
273 * of the timer handle *tim*. A PENDING timer is one that has been
274 * scheduled and whose function has not yet been called.
279 * - 0: The timer is not pending.
280 * - 1: The timer is pending.
282 int rte_timer_pending(struct rte_timer *tim);
285 * Manage the timer list and execute callback functions.
287 * This function must be called periodically from EAL lcores
288 * main_loop(). It browses the list of pending timers and runs all
289 * timers that are expired.
291 * The precision of the timer depends on the call frequency of this
292 * function. However, the more often the function is called, the more
293 * CPU resources it will use.
295 void rte_timer_manage(void);
298 * Dump statistics about timers.
301 * A pointer to a file for output
303 void rte_timer_dump_stats(FILE *f);
309 #endif /* _RTE_TIMER_H_ */