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 70 #ifdef __cplusplus 71 extern "C" { 72 #endif 73 74 #define RTE_TIMER_STOP 0 /**< State: timer is stopped. */ 75 #define RTE_TIMER_PENDING 1 /**< State: timer is scheduled. */ 76 #define RTE_TIMER_RUNNING 2 /**< State: timer function is running. */ 77 #define RTE_TIMER_CONFIG 3 /**< State: timer is being configured. */ 78 79 #define RTE_TIMER_NO_OWNER -2 /**< Timer has no owner. */ 80 81 /** 82 * Timer type: Periodic or single (one-shot). 83 */ 84 enum rte_timer_type { 85 SINGLE, 86 PERIODICAL 87 }; 88 89 /** 90 * Timer status: A union of the state (stopped, pending, running, 91 * config) and an owner (the id of the lcore that owns the timer). 92 */ 93 union rte_timer_status { 94 struct { 95 uint16_t state; /**< Stop, pending, running, config. */ 96 int16_t owner; /**< The lcore that owns the timer. */ 97 }; 98 uint32_t u32; /**< To atomic-set status + owner. */ 99 }; 100 101 #ifdef RTE_LIBRTE_TIMER_DEBUG 102 /** 103 * A structure that stores the timer statistics (per-lcore). 104 */ 105 struct rte_timer_debug_stats { 106 uint64_t reset; /**< Number of success calls to rte_timer_reset(). */ 107 uint64_t stop; /**< Number of success calls to rte_timer_stop(). */ 108 uint64_t manage; /**< Number of calls to rte_timer_manage(). */ 109 uint64_t pending; /**< Number of pending/running timers. */ 110 }; 111 #endif 112 113 struct rte_timer; 114 115 /** 116 * Callback function type for timer expiry. 117 */ 118 typedef void (*rte_timer_cb_t)(struct rte_timer *, void *); 119 120 #define MAX_SKIPLIST_DEPTH 10 121 122 /** 123 * A structure describing a timer in RTE. 124 */ 125 struct rte_timer 126 { 127 uint64_t expire; /**< Time when timer expire. */ 128 struct rte_timer *sl_next[MAX_SKIPLIST_DEPTH]; 129 volatile union rte_timer_status status; /**< Status of timer. */ 130 uint64_t period; /**< Period of timer (0 if not periodic). */ 131 rte_timer_cb_t f; /**< Callback function. */ 132 void *arg; /**< Argument to callback function. */ 133 }; 134 135 136 #ifdef __cplusplus 137 /** 138 * A C++ static initializer for a timer structure. 139 */ 140 #define RTE_TIMER_INITIALIZER { \ 141 0, \ 142 {NULL}, \ 143 {{RTE_TIMER_STOP, RTE_TIMER_NO_OWNER}}, \ 144 0, \ 145 NULL, \ 146 NULL, \ 147 } 148 #else 149 /** 150 * A static initializer for a timer structure. 151 */ 152 #define RTE_TIMER_INITIALIZER { \ 153 .status = {{ \ 154 .state = RTE_TIMER_STOP, \ 155 .owner = RTE_TIMER_NO_OWNER, \ 156 }}, \ 157 } 158 #endif 159 160 /** 161 * Initialize the timer library. 162 * 163 * Initializes internal variables (list, locks and so on) for the RTE 164 * timer library. 165 */ 166 void rte_timer_subsystem_init(void); 167 168 /** 169 * Initialize a timer handle. 170 * 171 * The rte_timer_init() function initializes the timer handle *tim* 172 * for use. No operations can be performed on a timer before it is 173 * initialized. 174 * 175 * @param tim 176 * The timer to initialize. 177 */ 178 void rte_timer_init(struct rte_timer *tim); 179 180 /** 181 * Reset and start the timer associated with the timer handle. 182 * 183 * The rte_timer_reset() function resets and starts the timer 184 * associated with the timer handle *tim*. When the timer expires after 185 * *ticks* HPET cycles, the function specified by *fct* will be called 186 * with the argument *arg* on core *tim_lcore*. 187 * 188 * If the timer associated with the timer handle is already running 189 * (in the RUNNING state), the function will fail. The user has to check 190 * the return value of the function to see if there is a chance that the 191 * timer is in the RUNNING state. 192 * 193 * If the timer is being configured on another core (the CONFIG state), 194 * it will also fail. 195 * 196 * If the timer is pending or stopped, it will be rescheduled with the 197 * new parameters. 198 * 199 * @param tim 200 * The timer handle. 201 * @param ticks 202 * The number of cycles (see rte_get_hpet_hz()) before the callback 203 * function is called. 204 * @param type 205 * The type can be either: 206 * - PERIODICAL: The timer is automatically reloaded after execution 207 * (returns to the PENDING state) 208 * - SINGLE: The timer is one-shot, that is, the timer goes to a 209 * STOPPED state after execution. 210 * @param tim_lcore 211 * The ID of the lcore where the timer callback function has to be 212 * executed. If tim_lcore is LCORE_ID_ANY, the timer library will 213 * launch it on a different core for each call (round-robin). 214 * @param fct 215 * The callback function of the timer. 216 * @param arg 217 * The user argument of the callback function. 218 * @return 219 * - 0: Success; the timer is scheduled. 220 * - (-1): Timer is in the RUNNING or CONFIG state. 221 */ 222 int rte_timer_reset(struct rte_timer *tim, uint64_t ticks, 223 enum rte_timer_type type, unsigned tim_lcore, 224 rte_timer_cb_t fct, void *arg); 225 226 227 /** 228 * Loop until rte_timer_reset() succeeds. 229 * 230 * Reset and start the timer associated with the timer handle. Always 231 * succeed. See rte_timer_reset() for details. 232 * 233 * @param tim 234 * The timer handle. 235 * @param ticks 236 * The number of cycles (see rte_get_hpet_hz()) before the callback 237 * function is called. 238 * @param type 239 * The type can be either: 240 * - PERIODICAL: The timer is automatically reloaded after execution 241 * (returns to the PENDING state) 242 * - SINGLE: The timer is one-shot, that is, the timer goes to a 243 * STOPPED state after execution. 244 * @param tim_lcore 245 * The ID of the lcore where the timer callback function has to be 246 * executed. If tim_lcore is LCORE_ID_ANY, the timer library will 247 * launch it on a different core for each call (round-robin). 248 * @param fct 249 * The callback function of the timer. 250 * @param arg 251 * The user argument of the callback function. 252 */ 253 void 254 rte_timer_reset_sync(struct rte_timer *tim, uint64_t ticks, 255 enum rte_timer_type type, unsigned tim_lcore, 256 rte_timer_cb_t fct, void *arg); 257 258 /** 259 * Stop a timer. 260 * 261 * The rte_timer_stop() function stops the timer associated with the 262 * timer handle *tim*. It may fail if the timer is currently running or 263 * being configured. 264 * 265 * If the timer is pending or stopped (for instance, already expired), 266 * the function will succeed. The timer handle tim must have been 267 * initialized using rte_timer_init(), otherwise, undefined behavior 268 * will occur. 269 * 270 * This function can be called safely from a timer callback. If it 271 * succeeds, the timer is not referenced anymore by the timer library 272 * and the timer structure can be freed (even in the callback 273 * function). 274 * 275 * @param tim 276 * The timer handle. 277 * @return 278 * - 0: Success; the timer is stopped. 279 * - (-1): The timer is in the RUNNING or CONFIG state. 280 */ 281 int rte_timer_stop(struct rte_timer *tim); 282 283 284 /** 285 * Loop until rte_timer_stop() succeeds. 286 * 287 * After a call to this function, the timer identified by *tim* is 288 * stopped. See rte_timer_stop() for details. 289 * 290 * @param tim 291 * The timer handle. 292 */ 293 void rte_timer_stop_sync(struct rte_timer *tim); 294 295 /** 296 * Test if a timer is pending. 297 * 298 * The rte_timer_pending() function tests the PENDING status 299 * of the timer handle *tim*. A PENDING timer is one that has been 300 * scheduled and whose function has not yet been called. 301 * 302 * @param tim 303 * The timer handle. 304 * @return 305 * - 0: The timer is not pending. 306 * - 1: The timer is pending. 307 */ 308 int rte_timer_pending(struct rte_timer *tim); 309 310 /** 311 * Manage the timer list and execute callback functions. 312 * 313 * This function must be called periodically from EAL lcores 314 * main_loop(). It browses the list of pending timers and runs all 315 * timers that are expired. 316 * 317 * The precision of the timer depends on the call frequency of this 318 * function. However, the more often the function is called, the more 319 * CPU resources it will use. 320 */ 321 void rte_timer_manage(void); 322 323 /** 324 * Dump statistics about timers. 325 * 326 * @param f 327 * A pointer to a file for output 328 */ 329 void rte_timer_dump_stats(FILE *f); 330 331 #ifdef __cplusplus 332 } 333 #endif 334 335 #endif /* _RTE_TIMER_H_ */ 336