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 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 RTE_STD_C11 68 struct { 69 uint16_t state; /**< Stop, pending, running, config. */ 70 int16_t owner; /**< The lcore that owns the timer. */ 71 }; 72 uint32_t u32; /**< To atomic-set status + owner. */ 73 }; 74 75 #ifdef RTE_LIBRTE_TIMER_DEBUG 76 /** 77 * A structure that stores the timer statistics (per-lcore). 78 */ 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. */ 84 }; 85 #endif 86 87 struct rte_timer; 88 89 /** 90 * Callback function type for timer expiry. 91 */ 92 typedef void (*rte_timer_cb_t)(struct rte_timer *, void *); 93 94 #define MAX_SKIPLIST_DEPTH 10 95 96 /** 97 * A structure describing a timer in RTE. 98 */ 99 struct rte_timer 100 { 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. */ 107 }; 108 109 110 #ifdef __cplusplus 111 /** 112 * A C++ static initializer for a timer structure. 113 */ 114 #define RTE_TIMER_INITIALIZER { \ 115 0, \ 116 {NULL}, \ 117 {{RTE_TIMER_STOP, RTE_TIMER_NO_OWNER}}, \ 118 0, \ 119 NULL, \ 120 NULL, \ 121 } 122 #else 123 /** 124 * A static initializer for a timer structure. 125 */ 126 #define RTE_TIMER_INITIALIZER { \ 127 .status = {{ \ 128 .state = RTE_TIMER_STOP, \ 129 .owner = RTE_TIMER_NO_OWNER, \ 130 }}, \ 131 } 132 #endif 133 134 /** 135 * Initialize the timer library. 136 * 137 * Initializes internal variables (list, locks and so on) for the RTE 138 * timer library. 139 */ 140 void rte_timer_subsystem_init(void); 141 142 /** 143 * Initialize a timer handle. 144 * 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 147 * initialized. 148 * 149 * @param tim 150 * The timer to initialize. 151 */ 152 void rte_timer_init(struct rte_timer *tim); 153 154 /** 155 * Reset and start the timer associated with the timer handle. 156 * 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*. 161 * 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. 166 * 167 * If the timer is being configured on another core (the CONFIG state), 168 * it will also fail. 169 * 170 * If the timer is pending or stopped, it will be rescheduled with the 171 * new parameters. 172 * 173 * @param tim 174 * The timer handle. 175 * @param ticks 176 * The number of cycles (see rte_get_hpet_hz()) before the callback 177 * function is called. 178 * @param type 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. 184 * @param tim_lcore 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). 188 * @param fct 189 * The callback function of the timer. 190 * @param arg 191 * The user argument of the callback function. 192 * @return 193 * - 0: Success; the timer is scheduled. 194 * - (-1): Timer is in the RUNNING or CONFIG state. 195 */ 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); 199 200 201 /** 202 * Loop until rte_timer_reset() succeeds. 203 * 204 * Reset and start the timer associated with the timer handle. Always 205 * succeed. See rte_timer_reset() for details. 206 * 207 * @param tim 208 * The timer handle. 209 * @param ticks 210 * The number of cycles (see rte_get_hpet_hz()) before the callback 211 * function is called. 212 * @param type 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. 218 * @param tim_lcore 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). 222 * @param fct 223 * The callback function of the timer. 224 * @param arg 225 * The user argument of the callback function. 226 */ 227 void 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); 231 232 /** 233 * Stop a timer. 234 * 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 237 * being configured. 238 * 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 242 * will occur. 243 * 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 247 * function). 248 * 249 * @param tim 250 * The timer handle. 251 * @return 252 * - 0: Success; the timer is stopped. 253 * - (-1): The timer is in the RUNNING or CONFIG state. 254 */ 255 int rte_timer_stop(struct rte_timer *tim); 256 257 258 /** 259 * Loop until rte_timer_stop() succeeds. 260 * 261 * After a call to this function, the timer identified by *tim* is 262 * stopped. See rte_timer_stop() for details. 263 * 264 * @param tim 265 * The timer handle. 266 */ 267 void rte_timer_stop_sync(struct rte_timer *tim); 268 269 /** 270 * Test if a timer is pending. 271 * 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. 275 * 276 * @param tim 277 * The timer handle. 278 * @return 279 * - 0: The timer is not pending. 280 * - 1: The timer is pending. 281 */ 282 int rte_timer_pending(struct rte_timer *tim); 283 284 /** 285 * Manage the timer list and execute callback functions. 286 * 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. 290 * 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. 294 */ 295 void rte_timer_manage(void); 296 297 /** 298 * Dump statistics about timers. 299 * 300 * @param f 301 * A pointer to a file for output 302 */ 303 void rte_timer_dump_stats(FILE *f); 304 305 #ifdef __cplusplus 306 } 307 #endif 308 309 #endif /* _RTE_TIMER_H_ */ 310