1 /*- 2 * BSD LICENSE 3 * 4 * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #ifndef _RTE_TIMER_H_ 35 #define _RTE_TIMER_H_ 36 37 /** 38 * @file 39 RTE Timer 40 * 41 * This library provides a timer service to RTE Data Plane execution 42 * units that allows the execution of callback functions asynchronously. 43 * 44 * - Timers can be periodic or single (one-shot). 45 * - The timers can be loaded from one core and executed on another. This has 46 * to be specified in the call to rte_timer_reset(). 47 * - High precision is possible. NOTE: this depends on the call frequency to 48 * rte_timer_manage() that check the timer expiration for the local core. 49 * - If not used in an application, for improved performance, it can be 50 * disabled at compilation time by not calling the rte_timer_manage() 51 * to improve performance. 52 * 53 * The timer library uses the rte_get_hpet_cycles() function that 54 * uses the HPET, when available, to provide a reliable time reference. [HPET 55 * routines are provided by EAL, which falls back to using the chip TSC (time- 56 * stamp counter) as fallback when HPET is not available] 57 * 58 * This library provides an interface to add, delete and restart a 59 * timer. The API is based on the BSD callout(9) API with a few 60 * differences. 61 * 62 * See the RTE architecture documentation for more information about the 63 * design of this library. 64 */ 65 66 #include <stdio.h> 67 #include <stdint.h> 68 #include <stddef.h> 69 #include <rte_common.h> 70 #include <rte_config.h> 71 72 #ifdef __cplusplus 73 extern "C" { 74 #endif 75 76 #define RTE_TIMER_STOP 0 /**< State: timer is stopped. */ 77 #define RTE_TIMER_PENDING 1 /**< State: timer is scheduled. */ 78 #define RTE_TIMER_RUNNING 2 /**< State: timer function is running. */ 79 #define RTE_TIMER_CONFIG 3 /**< State: timer is being configured. */ 80 81 #define RTE_TIMER_NO_OWNER -2 /**< Timer has no owner. */ 82 83 /** 84 * Timer type: Periodic or single (one-shot). 85 */ 86 enum rte_timer_type { 87 SINGLE, 88 PERIODICAL 89 }; 90 91 /** 92 * Timer status: A union of the state (stopped, pending, running, 93 * config) and an owner (the id of the lcore that owns the timer). 94 */ 95 union rte_timer_status { 96 RTE_STD_C11 97 struct { 98 uint16_t state; /**< Stop, pending, running, config. */ 99 int16_t owner; /**< The lcore that owns the timer. */ 100 }; 101 uint32_t u32; /**< To atomic-set status + owner. */ 102 }; 103 104 #ifdef RTE_LIBRTE_TIMER_DEBUG 105 /** 106 * A structure that stores the timer statistics (per-lcore). 107 */ 108 struct rte_timer_debug_stats { 109 uint64_t reset; /**< Number of success calls to rte_timer_reset(). */ 110 uint64_t stop; /**< Number of success calls to rte_timer_stop(). */ 111 uint64_t manage; /**< Number of calls to rte_timer_manage(). */ 112 uint64_t pending; /**< Number of pending/running timers. */ 113 }; 114 #endif 115 116 struct rte_timer; 117 118 /** 119 * Callback function type for timer expiry. 120 */ 121 typedef void (*rte_timer_cb_t)(struct rte_timer *, void *); 122 123 #define MAX_SKIPLIST_DEPTH 10 124 125 /** 126 * A structure describing a timer in RTE. 127 */ 128 struct rte_timer 129 { 130 uint64_t expire; /**< Time when timer expire. */ 131 struct rte_timer *sl_next[MAX_SKIPLIST_DEPTH]; 132 volatile union rte_timer_status status; /**< Status of timer. */ 133 uint64_t period; /**< Period of timer (0 if not periodic). */ 134 rte_timer_cb_t f; /**< Callback function. */ 135 void *arg; /**< Argument to callback function. */ 136 }; 137 138 139 #ifdef __cplusplus 140 /** 141 * A C++ static initializer for a timer structure. 142 */ 143 #define RTE_TIMER_INITIALIZER { \ 144 0, \ 145 {NULL}, \ 146 {{RTE_TIMER_STOP, RTE_TIMER_NO_OWNER}}, \ 147 0, \ 148 NULL, \ 149 NULL, \ 150 } 151 #else 152 /** 153 * A static initializer for a timer structure. 154 */ 155 #define RTE_TIMER_INITIALIZER { \ 156 .status = {{ \ 157 .state = RTE_TIMER_STOP, \ 158 .owner = RTE_TIMER_NO_OWNER, \ 159 }}, \ 160 } 161 #endif 162 163 /** 164 * Initialize the timer library. 165 * 166 * Initializes internal variables (list, locks and so on) for the RTE 167 * timer library. 168 */ 169 void rte_timer_subsystem_init(void); 170 171 /** 172 * Initialize a timer handle. 173 * 174 * The rte_timer_init() function initializes the timer handle *tim* 175 * for use. No operations can be performed on a timer before it is 176 * initialized. 177 * 178 * @param tim 179 * The timer to initialize. 180 */ 181 void rte_timer_init(struct rte_timer *tim); 182 183 /** 184 * Reset and start the timer associated with the timer handle. 185 * 186 * The rte_timer_reset() function resets and starts the timer 187 * associated with the timer handle *tim*. When the timer expires after 188 * *ticks* HPET cycles, the function specified by *fct* will be called 189 * with the argument *arg* on core *tim_lcore*. 190 * 191 * If the timer associated with the timer handle is already running 192 * (in the RUNNING state), the function will fail. The user has to check 193 * the return value of the function to see if there is a chance that the 194 * timer is in the RUNNING state. 195 * 196 * If the timer is being configured on another core (the CONFIG state), 197 * it will also fail. 198 * 199 * If the timer is pending or stopped, it will be rescheduled with the 200 * new parameters. 201 * 202 * @param tim 203 * The timer handle. 204 * @param ticks 205 * The number of cycles (see rte_get_hpet_hz()) before the callback 206 * function is called. 207 * @param type 208 * The type can be either: 209 * - PERIODICAL: The timer is automatically reloaded after execution 210 * (returns to the PENDING state) 211 * - SINGLE: The timer is one-shot, that is, the timer goes to a 212 * STOPPED state after execution. 213 * @param tim_lcore 214 * The ID of the lcore where the timer callback function has to be 215 * executed. If tim_lcore is LCORE_ID_ANY, the timer library will 216 * launch it on a different core for each call (round-robin). 217 * @param fct 218 * The callback function of the timer. 219 * @param arg 220 * The user argument of the callback function. 221 * @return 222 * - 0: Success; the timer is scheduled. 223 * - (-1): Timer is in the RUNNING or CONFIG state. 224 */ 225 int rte_timer_reset(struct rte_timer *tim, uint64_t ticks, 226 enum rte_timer_type type, unsigned tim_lcore, 227 rte_timer_cb_t fct, void *arg); 228 229 230 /** 231 * Loop until rte_timer_reset() succeeds. 232 * 233 * Reset and start the timer associated with the timer handle. Always 234 * succeed. See rte_timer_reset() for details. 235 * 236 * @param tim 237 * The timer handle. 238 * @param ticks 239 * The number of cycles (see rte_get_hpet_hz()) before the callback 240 * function is called. 241 * @param type 242 * The type can be either: 243 * - PERIODICAL: The timer is automatically reloaded after execution 244 * (returns to the PENDING state) 245 * - SINGLE: The timer is one-shot, that is, the timer goes to a 246 * STOPPED state after execution. 247 * @param tim_lcore 248 * The ID of the lcore where the timer callback function has to be 249 * executed. If tim_lcore is LCORE_ID_ANY, the timer library will 250 * launch it on a different core for each call (round-robin). 251 * @param fct 252 * The callback function of the timer. 253 * @param arg 254 * The user argument of the callback function. 255 */ 256 void 257 rte_timer_reset_sync(struct rte_timer *tim, uint64_t ticks, 258 enum rte_timer_type type, unsigned tim_lcore, 259 rte_timer_cb_t fct, void *arg); 260 261 /** 262 * Stop a timer. 263 * 264 * The rte_timer_stop() function stops the timer associated with the 265 * timer handle *tim*. It may fail if the timer is currently running or 266 * being configured. 267 * 268 * If the timer is pending or stopped (for instance, already expired), 269 * the function will succeed. The timer handle tim must have been 270 * initialized using rte_timer_init(), otherwise, undefined behavior 271 * will occur. 272 * 273 * This function can be called safely from a timer callback. If it 274 * succeeds, the timer is not referenced anymore by the timer library 275 * and the timer structure can be freed (even in the callback 276 * function). 277 * 278 * @param tim 279 * The timer handle. 280 * @return 281 * - 0: Success; the timer is stopped. 282 * - (-1): The timer is in the RUNNING or CONFIG state. 283 */ 284 int rte_timer_stop(struct rte_timer *tim); 285 286 287 /** 288 * Loop until rte_timer_stop() succeeds. 289 * 290 * After a call to this function, the timer identified by *tim* is 291 * stopped. See rte_timer_stop() for details. 292 * 293 * @param tim 294 * The timer handle. 295 */ 296 void rte_timer_stop_sync(struct rte_timer *tim); 297 298 /** 299 * Test if a timer is pending. 300 * 301 * The rte_timer_pending() function tests the PENDING status 302 * of the timer handle *tim*. A PENDING timer is one that has been 303 * scheduled and whose function has not yet been called. 304 * 305 * @param tim 306 * The timer handle. 307 * @return 308 * - 0: The timer is not pending. 309 * - 1: The timer is pending. 310 */ 311 int rte_timer_pending(struct rte_timer *tim); 312 313 /** 314 * Manage the timer list and execute callback functions. 315 * 316 * This function must be called periodically from EAL lcores 317 * main_loop(). It browses the list of pending timers and runs all 318 * timers that are expired. 319 * 320 * The precision of the timer depends on the call frequency of this 321 * function. However, the more often the function is called, the more 322 * CPU resources it will use. 323 */ 324 void rte_timer_manage(void); 325 326 /** 327 * Dump statistics about timers. 328 * 329 * @param f 330 * A pointer to a file for output 331 */ 332 void rte_timer_dump_stats(FILE *f); 333 334 #ifdef __cplusplus 335 } 336 #endif 337 338 #endif /* _RTE_TIMER_H_ */ 339