]> git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/dpdk/lib/librte_timer/rte_timer.h
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / spdk / dpdk / lib / librte_timer / rte_timer.h
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_ */