EM-ODP  3.8.0-1
Event Machine on ODP
api/event_machine_timer.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016-2024, Nokia Solutions and Networks
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * * Neither the name of the copyright holder nor the names of its
15  * contributors may be used to endorse or promote products derived
16  * from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 #ifndef EVENT_MACHINE_TIMER_H_
31 #define EVENT_MACHINE_TIMER_H_
32 
33 #pragma GCC visibility push(default)
34 
35 /**
36  * @file
37  * Event Machine timer
38  * @defgroup em_timer Event timer
39  * Event Machine timer
40  * @{
41  *
42  * The timer API can be used to request an event to be sent to a specified
43  * queue at a specified time once (one-shot) or at regular intervals (periodic).
44  * A timer needs to be created first - it represents a collection of timeouts
45  * with certain attributes (e.g. timeout resolution and maximum period).
46  * A timer can be mapped to a HW resource on an SoC, thus the number of timers,
47  * capabilities and time bases are system specific. Typically only a few timers
48  * are supported.
49  * The application can specify required capabilities when a timer is created.
50  * The creation will fail if the implementation cannot fulfill the required
51  * values. Timers are typically created once at system startup.
52  *
53  * A timer is a shared resource with proper synchronization for concurrent
54  * multi-thread use. It is possible to exclude all multi-thread protections if a
55  * timer is used exclusively by a single thread (for potential performance
56  * gains). This is done by setting EM_TIMER_FLAG_PRIVATE when creating a timer.
57  * Setting this flag means that the application must ensure that only a single
58  * thread is using the timer (this also includes the receiver of periodic
59  * timeouts due to the ack-functionality). This private-mode is not necessarily
60  * implemented on all systems, in which case the flag is ignored as it will not
61  * cause any functional difference.
62  *
63  * Timeouts (tmo) can be created once a timer exists. Creating a timeout
64  * allocates the resources needed to serve the timeout, but does not arm it.
65  * This makes it possible to pre-create timeout(s) and set the expiry
66  * later at runtime. This can improve performance but also minimizes the
67  * possibility that the runtime call setting the expiry would fail, as resources
68  * have already been reserved beforehand.
69  *
70  * A pending timeout can be cancelled. Note that there is no way to cancel an
71  * expired timeout for which the event has already been sent but not yet
72  * received by the application. Canceling in this case will return an error
73  * to enable the application to detect the situation. For a periodic timer,
74  * a cancel will stop further timeouts, but may not be able to prevent the
75  * latest event from being received. An active timeout cannot be altered without
76  * canceling it first.
77  *
78  * A timeout can be reused after the timeout event has been received or when
79  * successfully cancelled. Timeouts need to be deleted after use. Deletion frees
80  * the resources reserved during creation.
81  *
82  * The timeout value is an abstract system and timer dependent tick count.
83  * It is assumed that the tick count increases with a static frequency.
84  * The frequency can be inquired at runtime for time calculations, e.g. tick
85  * frequency divided by 1000 gives ticks for 1ms. The tick frequency is at least
86  * equal to the resolution, but can also be higher (implementation can quantize
87  * ticks to any underlying implementation). The supported resolution can also be
88  * inquired.
89  * A clock source can be specified when creating a timer. It defines the time
90  * base of the timer for systems with multiple sources implemented (optional).
91  * EM_TIMER_CLKSRC_DEFAULT is a portable value that implements a basic
92  * monotonic time, that will not wrap back to zero in any reasonable uptime.
93  *
94  * Events with major event types EM_EVENT_TYPE_SW, EM_EVENT_TYPE_PACKET and
95  * EM_EVENT_TYPE_TIMER can be used as timeout events to indicate expiry. The
96  * type EM_EVENT_TYPE_TIMER is an alternative to EM_EVENT_TYPE_SW and works the
97  * same way. Additionally, for periodic ring timer only, the type
98  * EM_EVENT_TYPE_TIMER_IND is used. This is a special timeout indication event
99  * without visible payload.
100  *
101  * Regular periodic timeouts:
102  * (i.e. NOT periodic ring timer timeouts, see differences further down)
103  * A periodic timer requires the application to acknowledge each received
104  * timeout event after it has been processed. The acknowledgment activates the
105  * next timeout and compensates for the processing delay to keep the original
106  * interval. This creates a flow control mechanism and also protects the event
107  * handling from races if the same event is reused every time - the next
108  * timeout will not be sent before the previous has been acknowledged.
109  * The event to be received for each periodic timeout can also be different as
110  * the next event is given by the application via the acknowledgment.
111  * The target queue cannot be modified after the timeout has been created.
112  *
113  * If the acknowledgment of a periodic timeout is done too late (after the next
114  * period has already passed), the default action is to skip the missed timeout
115  * slot(s) and arm for the next valid slot. If the application never wants to
116  * skip a missed timeout it can set the flag EM_TMO_FLAG_NOSKIP when creating a
117  * timeout. This causes each acknowledgment to schedule an immediate timeout
118  * event until all the missed time slots have been served. This keeps the number
119  * of timeouts as expected but may cause an event storm if a long processing
120  * delay has occurred.
121  *
122  * The timeout handle is needed when acknowledging a periodic timeout event.
123  * Because any event can be used for the timeout, the application must itself
124  * provide a way to derive the timeout handle from the received timeout event.
125  * A typical way is to include the tmo handle within the timeout event.
126  * The application also needs to have a mechanism to detect which event is a
127  * periodic timeout to be able to acknowledge it via em_tmo_ack().
128  *
129  * If the requested timeout tick value for a timeout is in the past or is too
130  * close to the current time then the error code EM_ERR_TOONEAR is returned.
131  * In this case EM will not call the error handler - instead EM lets the
132  * application decide whether to treat the situation as an error or to try again
133  * with an updated target time.
134  *
135  * Periodic ring timer:
136  * There is also an alternative periodic ring timer. It uses a different
137  * abstraction and is created and started via separate ring specific APIs.
138  * It has three main differences to the regular periodic timeouts:
139  * 1. Only a pre-defined read-only event type can be used and is provided
140  * by the timer (EM_EVENT_TYPE_TIMER_IND).
141  * 2. Flow control is not supported. Some implementations may have it,
142  * but the specification does not quarantee any so the user needs to be
143  * prepared to see the same event enqueued multiple times if handling of
144  * the received timeouts is not fast enough.
145  * 2. A limited set of period times are supported per timer (the base rate or
146  * an integer multiple thereof).
147  *
148  * Ring timers can be thought of as a clock face ticking the pointer forward.
149  * One cycle around is the base rate (minimum rate). The same timeout can be
150  * inserted into multiple locations evenly spread within the clock face thus
151  * multiplying the base rate. The starting offset can be adjusted only up to
152  * one timeout period.
153  * Depending on platform, this mode may provide better integration with HW and
154  * thus have less runtime overhead. However, as it exposes a potential queue
155  * overflow and a race hazard (race avoidable by using atomic queue as target),
156  * regular periodic timeouts are recommended as a default.
157  *
158  * Example usage
159  * @code
160  *
161  * // This would typically be done at application init.
162  * // Accept all defaults but change the name
163  * em_timer_attr_t attr;
164  * em_timer_attr_init(&attr);
165  * strncpy(attr.name, "myTimer", EM_TIMER_NAME_LEN);
166  * em_timer_t tmr = em_timer_create(&attr);
167  * if(tmr == EM_TIMER_UNDEF) {
168  * // handle error here or via the error handler
169  * }
170  *
171  * // At runtime - create a timeout resource.
172  * // Can be done in advance to save time if the target queue is known.
173  * em_tmo_t tmo = em_tmo_create(tmr, EM_TIMER_FLAG_ONESHOT, target_queue);
174  * if(tmo == EM_TMO_UNDEF) {
175  * // no such timer or out of resources
176  * // handle error here or via error handler
177  * }
178  *
179  * // Get the timer tick frequency
180  * uint64_t hz = em_timer_get_freq(tmr);
181  *
182  * // Activate a 10ms timeout from now.
183  * // Very unlikely to fail with valid arguments.
184  * if (em_tmo_set_rel(tmo, hz / 100, my_tmo_event) != EM_OK) {
185  * // handle error here or via error handler
186  * }
187  *
188  * @endcode
189  *
190  */
191 #include <inttypes.h>
192 
193 #ifdef __cplusplus
194 extern "C" {
195 #endif
196 
197 /**
198  * @typedef em_timer_t
199  * System specific type for a timer handle.
200  */
201 
202 /**
203  * @typedef em_tmo_t
204  * System specific type for a timeout handle.
205  */
206 
207 /**
208  * @typedef em_timer_flag_t
209  * System specific type for timer flags.
210  * This is system specific, but all implementations must define
211  * EM_TIMER_FLAG_DEFAULT and EM_TIMER_FLAG_PRIVATE, of which the latter is used
212  * to skip API synchronization for single threaded apps.
213  * Flags can be combined by bitwise OR.
214  */
215 
216 /**
217  * @typedef em_tmo_flag_t
218  * System specific enum type for timeout flags.
219  * This is system specific, but all implementations must define
220  * EM_TMO_FLAG_ONESHOT, EM_TMO_FLAG_PERIODIC and EM_TMO_FLAG_NOSKIP.
221  * Flags can be combined by bitwise OR.
222  */
223 
224 /**
225  * @typedef em_timer_clksrc_t
226  * System specific enum type for timer clock source.
227  * This is system specific, but all implementations must define
228  * EM_TIMER_CLKSRC_DEFAULT.
229  */
230 
231 /**
232  * Visible state of a timeout
233  */
234 typedef enum em_tmo_state_t {
235  EM_TMO_STATE_UNKNOWN = 0,
236  EM_TMO_STATE_IDLE = 1, /**< just created or canceled */
237  EM_TMO_STATE_ACTIVE = 2, /**< armed */
238  EM_TMO_STATE_INACTIVE = 3 /**< unused state */
240 
241 /**
242  * Type returned by em_tmo_get_type()
243  */
244 typedef enum em_tmo_type_t {
245  EM_TMO_TYPE_NONE = 0, /**< unknown or not a timer-related event */
246  EM_TMO_TYPE_ONESHOT = 1, /**< event is a oneshot timeout indication */
247  EM_TMO_TYPE_PERIODIC = 2, /**< event is a periodic timeout indication */
249 
250 /**
251  * The timer tick has HW and timer specific meaning, but the type is always a
252  * 64-bit integer and is normally assumed to be monotonic and not to wrap
253  * around. Exceptions with exotic extra timers should be clearly documented.
254  */
255 typedef uint64_t em_timer_tick_t;
256 
257 /**
258  * Fractional 64-bit unsigned value for timer frequency.
259  */
260 typedef struct em_fract_u64_t {
261  /** Int */
262  uint64_t integer;
263 
264  /** Numerator. Set 0 for integers */
265  uint64_t numer;
266 
267  /** Denominator */
268  uint64_t denom;
270 
271 /**
272  * Type for timer resolution parameters.
273  *
274  * This structure is used to group timer resolution parameters that may affect
275  * each other. All time values are in nanoseconds (ns).
276  *
277  * @note This type used both as capability and configuration. When used as
278  * configuration either res_ns or res_hz must be 0 (for em_timer_create()).
279  * @see em_timer_capability(), em_timer_create()
280  */
281 typedef struct em_timer_res_param_t {
282  /** Clock source (system specific) */
284  /** resolution, ns */
285  uint64_t res_ns;
286  /** resolution, hz */
287  uint64_t res_hz;
288  /** minimum timeout, ns */
289  uint64_t min_tmo;
290  /** maximum timeout, ns */
291  uint64_t max_tmo;
293 
294 /**
295  * Periodic timer ring timing parameters.
296  */
297 typedef struct em_timer_ring_param_t {
298  /** Clock source (system specific) */
300  /** Base rate, i.e. minimum period rate */
302  /** Maximum base rate multiplier needed. 1 for single rate = base_hz */
303  uint64_t max_mul;
304  /** Resolution */
305  uint64_t res_ns;
307 
308 /**
309  * EM timer attributes.
310  *
311  * The type is used when creating a timer or inquiring its configuration later.
312  *
313  * This needs to be initialized with em_timer_attr_init(), which fills default
314  * values to each field. After that the values can be modified as needed.
315  * Values set are considered a requirement, e.g. setting 'resparam.res_ns' to
316  * 1000(ns) requires the timer to have at least 1us resolution. The timer
317  * creation will fail if the implementation cannot support such a resolution
318  * (e.g. if it only goes down to 1500ns).
319  * The implementation is free to provide better than requested, but not worse.
320  *
321  * To know the implementation specific limits, use em_timer_capability() and
322  * em_timer_res_capability().
323  *
324  * When creating the alternative periodic ring timer, this type needs to be
325  * initialized with em_timer_ring_attr_init() instead. EM_TIMER_FLAG_RING will
326  * be set by em_timer_ring_attr_init() so it does not need to be manually set.
327  *
328  * @see em_timer_attr_init(), em_timer_create(),
329  * em_timer_ring_attr_init(), em_timer_ring_create(),
330  * em_timer_
331  */
332 typedef struct em_timer_attr_t {
333  /**
334  * Resolution parameters for em_timer_create().
335  * Used when creating normal one shot or periodic timers, but not when
336  * creating periodic ring timers (see ringparam below instead).
337  * (cleared by em_timer_ring_attr_init() when using a ring timer)
338  */
340 
341  /** Maximum simultaneous timeouts */
342  uint32_t num_tmo;
343  /** Extra flags. A set flag is a requirement */
345  /** Optional name for this timer */
346  char name[EM_TIMER_NAME_LEN];
347 
348  /**
349  * Parameters specifically for em_timer_ring_create().
350  * Used when creating an alternative periodic ring timer.
351  * (cleared by em_timer_attr_init() since not needed in that case)
352  */
354 
355  /**
356  * Internal check - don't touch!
357  *
358  * EM will verify that em_timer_attr_init() has been called before
359  * creating a timer
360  */
363 
364 /**
365  * Timeout statistics counters
366  *
367  * Some fields relate to periodic timeout only (0 on one-shots) and vice versa.
368  * New fields may be added later at the end.
369  */
370 typedef struct em_tmo_stats_t {
371  /** number of periodic ack() calls */
372  uint64_t num_acks;
373  /** number of delayed periodic ack() calls. 0 with ring timer */
374  uint64_t num_late_ack;
375  /** number of skipped periodic timeslots due to late ack. 0 with ring timer */
378 
379 /**
380  * Timer capability info
381  */
382 typedef struct em_timer_capability_t {
383  /** Number of supported timers of all types */
384  uint32_t max_timers;
385  /** Maximum number of simultaneous timeouts. 0 means only limited by memory */
386  uint32_t max_num_tmo;
387  /** Highest supported resolution and related limits for a timeout */
389  /** Longest supported timeout and related resolution */
391 
392  /** alternate periodic ring */
393  struct {
394  /** Maximum ring timers */
395  uint32_t max_rings;
396  /** Maximum simultaneous ring timeouts */
397  uint32_t max_num_tmo;
398  /** Minimum base_hz */
400  /** Minimum base_hz */
402  } ring;
403 
405 
406 /**
407  * tmo optional extra arguments
408  *
409  */
410 typedef struct em_tmo_args_t {
411  /** can be used with ring timer, see em_tmo_get_userptr */
412  void *userptr;
414 
415 /**
416  * Initialize em_timer_attr_t for normal timers (i.e. NOT periodic ring timers).
417  *
418  * Initializes em_timer_attr_t to system specific default values.
419  * The user can after initialization adjust the values as needed before
420  * calling em_timer_create(). The functions em_timer_capability() and/or
421  * em_timer_res_capability() can optionally be used to find valid values.
422  *
423  * Always initialize em_timer_attr_t with em_timer_attr_init() before use.
424  *
425  * This function will not trigger EM error handler calls internally.
426  *
427  * Example for all defaults
428  * @code
429  * em_timer_attr_t tmr_attr;
430  * em_timer_attr_init(&tmr_attr);
431  * em_timer_t tmr = em_timer_create(&tmr_attr);
432  * @endcode
433  *
434  * @param tmr_attr Pointer to em_timer_attr_t to be initialized
435  *
436  * @see em_timer_capability, em_timer_create
437  */
438 void em_timer_attr_init(em_timer_attr_t *tmr_attr);
439 
440 /**
441  * Initialize em_timer_attr_t for periodic ring timers.
442  *
443  * Initializes em_timer_ring_attr_t according to given values.
444  * After successful return, the attributes can be given to em_timer_ring_create().
445  * Note, that if the implementation cannot use the exact given combination it may
446  * update the ring_attr values, but always to meet or exceed the given values.
447  * The user can read the new values to determine if they were modified.
448  * An error is returned if the given values cannot be met.
449  *
450  * Before creating the ring timer, other values like num_tmo and name can be
451  * adjusted as needed. Also, if a non-integer frequency is needed, the base_hz
452  * fractional part can be adjusted before em_timer_ring_create().
453  *
454  * This function will not trigger error handler calls.
455  *
456  * @param[out] ring_attr Pointer to em_timer_attr_t to be initialized
457  * @param clk_src Clock source to use (system specific or portable
458  * EM_TIMER_CLKSRC_DEFAULT)
459  * @param base_hz Base rate of the ring (minimum rate i.e. longest period)
460  * @param max_mul Maximum multiplier (maximum rate = base_hz * max_mul)
461  * @param res_ns Required resolution of the timer or 0 to accept default
462  *
463  * @return EM_OK if the given clk_src and other values are supported
464  *
465  * @see em_timer_ring_capability(), em_timer_ring_create()
466  */
468  em_timer_clksrc_t clk_src,
469  uint64_t base_hz,
470  uint64_t max_mul,
471  uint64_t res_ns);
472 
473 /**
474  * Inquire timer capabilities
475  *
476  * Returns timer capabilities for the given clock source, which is also written
477  * to both 'capa->max_res.clk_src' and 'capa->max_tmo.clk_src'.
478  * For resolution both 'res_ns' and 'res_hz' are filled.
479  *
480  * This function will not trigger error handler calls internally.
481  *
482  * @param capa pointer to em_timer_capability_t to be updated
483  * (does not need to be initialized)
484  * @param clk_src Clock source to use for timer
485  * (EM_TIMER_CLKSRC_DEFAULT for system specific default)
486  * @return EM_OK if the given clk_src is supported (capa updated)
487  *
488  * @see em_timer_capability_t, em_timer_res_capability
489  */
491 
492 /**
493  * Inquire timer capabilities for a specific resolution or maximum timeout
494  *
495  * Returns timer capabilities by the given resolution or maximum timeout.
496  * Set either the resolution (res.res_ns) or the maximum timeout (res.max_tmo)
497  * to the required value and the other to zero, and the function will fill the
498  * other fields with valid limits.
499  * An error is returned if the given value is not supported.
500  * The given clk_src is used to set the values and also written to 'res->clk_src'.
501  * Both 'res_ns' and 'res_hz' are filled, so if passed further to em_timer_create(),
502  * one of those must be set to 0.
503  *
504  * Example for external clock maximum resolution
505  * @code
506  * em_timer_attr_t *tmr_attr;
507  * em_timer_capability_t capa;
508  *
509  * em_timer_attr_init(&tmr_attr);
510  * if (em_timer_capability(&capa, EM_TIMER_CLKSRC_EXT) != EM_OK) {
511  * // external clock not supported
512  * }
513  * tmr_attr.resparam = capa.max_res;
514  * tmr_attr.resparam.res_hz = 0;
515  * tmr = em_timer_create(&tmr_attr);
516  * @endcode
517  *
518  * This function will not trigger error handler calls internally.
519  *
520  * @param res Pointer to em_timer_res_param_t with one field set
521  * @param clk_src Clock source to use for timer
522  * (EM_TIMER_CLKSRC_DEFAULT for system specific default)
523  * @return EM_OK if the input value is supported (res updated)
524  *
525  * @see em_timer_capability
526  */
528 
529 /**
530  * @brief Check periodic ring timer capability.
531  *
532  * Returns the ring timer capability based on the given input values.
533  * The parameter 'ring' must be initialized with the values required by the user.
534  * The ring.res_ns can be 0 and gets replaced by the system default.
535  * The values are updated during the call. If EM_OK is returned then the
536  * combination of given values are all supported (or exceeded, e.g. better
537  * resolution), otherwise values are updated with the closest supported.
538  *
539  * As em_timer_ring_attr_init() only takes integer base_hz, this can also be
540  * used to verify valid values for modified fractional frequencies to avoid
541  * error handler calls from em_timer_ring_create().
542  *
543  * This function will not trigger error handler calls.
544  *
545  * @param ring[in,out] timer ring parameters to check
546  *
547  * @retval EM_OK Parameter combination is supported
548  * @retval EM_ERR_NOT_SUPPORTED Parameters not supported, values updated to closest
549  * @retval (other error) Unsupported arguments
550  */
552 
553 /**
554  * Create and start a timer resource
555  *
556  * Required attributes are given via tmr_attr. The given structure must be
557  * initialized with em_timer_attr_init() before setting any field.
558  *
559  * Timer resolution can be given as time 'res_ns' or frequency 'res_hz'.
560  * The user must choose which one to use by setting the other one to 0.
561  *
562  * To use all defaults, initialize tmr_attr with em_timer_attr_init() and pass
563  * it as is to em_timer_create().
564  *
565  * @param tmr_attr Timer parameters to use, pointer to an initialized em_timer_attr_t
566  * @note NULL is no longer supported, pointer must be to an initialized em_timer_attr_t
567  *
568  * @return Timer handle on success or EM_TIMER_UNDEF on error
569  *
570  * @see em_timer_attr_init(), em_timer_capability()
571  */
572 em_timer_t em_timer_create(const em_timer_attr_t *tmr_attr);
573 
574 /**
575  * Create and start a periodic timer ring (alternative periodic timer)
576  *
577  * The required attributes are given via ring_attr, which must have been
578  * initialized with em_timer_ring_attr_init() and optionally adjusted for the
579  * required timing constraints.
580  *
581  * A periodic ring timer is a bit different and will only send
582  * EM_EVENT_TYPE_TIMER_IND timeout events, which are automatically provided and
583  * cannot be modified. These events can be allocated only via timer APIs.
584  *
585  * Example for 1ms ... 125us periodic ring timer (base 1000 hz, multiplier up to 8):
586  * @code
587  * em_timer_ring_attr_t attr;
588  * if (em_timer_ring_attr_init(&attr, EM_TIMER_CLKSRC_DEFAULT, 1000, 8, 0) != EM_OK) {
589  * // given values not supported
590  * }
591  *
592  * em_timer_t tmr = em_timer_ring_create(&attr);
593  * if (tmr == EM_TIMER_UNDEF) {
594  * // handle error here or via error handler
595  * }
596  * @endcode
597  *
598  * @param ring_attr Timer ring parameters to use
599  *
600  * @return Timer handle on success or EM_TIMER_UNDEF on error
601  *
602  * @see em_timer_ring_attr_init
603  */
604 em_timer_t em_timer_ring_create(const em_timer_attr_t *ring_attr);
605 
606 /**
607  * Stop and delete a timer
608  *
609  * Delete a timer, free all resources.
610  * All timeouts for this timer must have been cancelled and deleted first.
611  *
612  * @param tmr Timer handle
613  *
614  * @return EM_OK on success
615  */
616 em_status_t em_timer_delete(em_timer_t tmr);
617 
618 /**
619  * Return the current tick value of the given timer
620  *
621  * This can be used for calculating absolute timeouts.
622  *
623  * @param tmr Timer handle
624  *
625  * @return Current time in timer specific ticks or 0 on non-existing timer
626  */
627 em_timer_tick_t em_timer_current_tick(em_timer_t tmr);
628 
629 /**
630  * Allocate a new timeout
631  *
632  * Create a new timeout. Allocates the necessary internal resources from the
633  * given timer and prepares for em_tmo_set_abs/rel/periodic().
634  *
635  * Scheduled queues are always supported as timeout event destinations. LOCAL or
636  * OUTPUT queues can not be used as timeout targets. Support for unscheduled
637  * queues is implementation specific.
638  *
639  * Flags are used to select functionality:
640  * - EM_TMO_FLAG_ONESHOT creates a one-shot timeout and
641  * - EM_TMO_FLAG_PERIODIC creates a periodic timeout.
642  * The flag EM_TMO_FLAG_NOSKIP can, in the periodic case, be 'OR':d into the
643  * flags to make the timeout acknowledgment never skip a missed timeout (the
644  * default is to skip missed time slots).
645  *
646  * The NOSKIP flag is ignored if used timer is a periodic timer ring.
647  *
648  * @param tmr Timer handle
649  * @param flags Functionality flags
650  * @param queue Target queue where the timeout event should be delivered
651  *
652  * @return Timeout handle on success or EM_TMO_UNDEF on failure
653  */
654 em_tmo_t em_tmo_create(em_timer_t tmr, em_tmo_flag_t flags, em_queue_t queue);
655 
656 /**
657  * Allocate a new timeout with extra arguments
658  *
659  * Similar to em_tmo_create() but with an additional 'args' pointer. This API
660  * can be used with any timer type, but 'args->userptr' is only meaningful for
661  * ring timers using events of type EM_EVENT_TYPE_TIMER_IND that can carry a
662  * 'userptr'.
663  *
664  * @param tmr Timer handle
665  * @param flags Functionality flags
666  * @param queue Target queue where the timeout event should be delivered
667  * @param args Optional pointer holding extra arguments e.g. userptr for
668  * ring timers. NULL ok.
669  *
670  * @return Timeout handle on success or EM_TMO_UNDEF on failure
671  * @see em_tmo_create
672  */
673 em_tmo_t em_tmo_create_arg(em_timer_t tmr, em_tmo_flag_t flags, em_queue_t queue,
674  em_tmo_args_t *args);
675 
676 /**
677  * Delete a timeout
678  *
679  * The deleted timeout must be inactive i.e. it must be successfully canceled or
680  * the last timeout event must have been received (following too late a cancel).
681  * A periodic or a periodic ring timeout can be deleted after a successful
682  * cancel or after em_tmo_ack() returned EM_ERR_CANCELED. This indicates that
683  * the acknowledged timeout is canceled and that it was the last timeout event
684  * coming for that periodic timeout.
685  *
686  * After and during this call, the tmo handle is not valid anymore and must not
687  * be used by or passed to other timer APIs.
688  *
689  * @param tmo Timeout handle
690  *
691  * @return EM_OK on success
692  */
694 
695 /**
696  * Activate a oneshot timeout with absolute time.
697  *
698  * Activates a oneshot timeout to expire at a specific absolute time. The given
699  * timeout event will be sent to the queue given to em_tmo_create() when the
700  * timeout expires.
701  *
702  * It is not possible to send timeouts with an event group, but the application
703  * can assign the event group when receiving the timeout event, see
704  * em_event_group_assign().
705  *
706  * The timeout event should not be accessed after it has been given to the
707  * timer, similar to sending an event.
708  *
709  * Even if not guaranteed, the implementation should make sure that this call
710  * can fail only in exceptional situations (em_tmo_create() should pre-allocate
711  * needed resources).
712  *
713  * The allowed minimum and maximum timeouts can be inquired with
714  * em_timer_res_capability().
715  *
716  * An active timeout can not be modified. The timeout needs to be canceled and
717  * then set again with new arguments.
718  *
719  * An inactive timeout can be reused by calling em_tmo_set_abs/rel() again. The
720  * timeout becomes inactive after the oneshot timeout event has been received
721  * or after it has been successfully cancelled.
722  *
723  * This function is for activating oneshot timeouts only. To activate
724  * periodic timeouts use em_tmo_set_periodic() (or em_tmo_set_periodic_ring()).
725  *
726  * @param tmo Timeout handle
727  * @param ticks_abs Expiration time in absolute timer specific ticks
728  * @param tmo_ev Timeout event
729  *
730  * @retval EM_OK Success, event taken.
731  * @retval EM_ERR_TOONEAR Failure, the tick value is in past or too close to the
732  * current time. Error handler not called, event not taken.
733  * @retval (other_codes) Failure, event not taken.
734  *
735  * @see em_timer_res_capability()
736  */
738  em_event_t tmo_ev);
739 
740 /**
741  * Activate a timeout with a relative time.
742  *
743  * Similar to em_tmo_set_abs(), but instead of an absolute time uses a timeout
744  * value relative to the moment of the call.
745  *
746  * This function is for activating oneshot timeouts only. To activate
747  * periodic timeouts use em_tmo_set_periodic() (or em_tmo_set_periodic_ring()).
748  *
749  * @param tmo Timeout handle
750  * @param ticks_rel Expiration time in relative timer specific ticks
751  * @param tmo_ev Timeout event handle
752  *
753  * @retval EM_OK Success, event taken.
754  * @retval EM_ERR_TOONEAR Failure, the tick value is too low.
755  * Error handler not called, event not taken.
756  * @retval (other_codes) Failure, event not taken.
757  *
758  * @see em_tmo_set_abs(), em_tmo_set_periodic()
759  */
761  em_event_t tmo_ev);
762 
763 /**
764  * Activate a periodic timeout
765  *
766  * Used to activate periodic timeouts. The first period can be different from
767  * the repetitive period by providing an absolute start time.
768  * Set 'start_abs' to 0 if the repetitive period can start from the moment of
769  * the call.
770  *
771  * The timeout event will be sent to the queue given to em_tmo_create() when the
772  * first timeout expires. The receiver then needs to call em_tmo_ack() to allow
773  * the timer to send the next event for the following period.
774  *
775  * This function can only be used with periodic timeouts (created with flag
776  * EM_TMO_FLAG_PERIODIC).
777  *
778  * @param tmo Timeout handle
779  * @param start_abs Absolute start time (or 0 for period starting at call time)
780  * @param period Period in timer specific ticks
781  * @param tmo_ev Timeout event handle
782  *
783  * @retval EM_OK Success, event taken
784  * @retval EM_ERR_TOONEAR Failure, the tick value is in past or too close to
785  * the current time.
786  * Error handler not called, event not taken.
787  * @retval (other_codes) Failure, event not taken.
788  *
789  * @see em_tmo_ack()
790  */
792  em_timer_tick_t start_abs,
793  em_timer_tick_t period,
794  em_event_t tmo_ev);
795 
796 /**
797  * Activate a periodic timeout on a periodic ring timer
798  *
799  * Use 'start_abs' value 0 to start the timer relative to current time. To
800  * adjust the offset of timeouts, an absolute tick can also be given, but the
801  * maximum distance from the current time can only be up to one period.
802  * The periodic rate of the timeout event is 'base_hz' (given when creating the
803  * timer) multiplied by the given 'multiplier'. For example 1000Hz 'base_hz'
804  * with a 'multiplier' of 8 will give a 125us period.
805  *
806  * A timeout event of type EM_EVENT_TYPE_TIMER_IND is automatically allocated,
807  * if not provided, and will be sent to the queue given to em_tmo_create() when
808  * the timeout expires. The user needs to call em_tmo_ack() when receiving the
809  * timeout event, similar as with a regular periodic timeout. However, with a
810  * ring timer there is no guaranteed flow control - new events may be sent even
811  * before user has called em_tmo_ack(). This means that the same event may be in
812  * the input queue multiple times if the application can not keep up with the
813  * period rate. If the destination queue is not atomic, the same event can also
814  * be concurrently received by multiple cores. This is a race hazard the user
815  * must prepare for. Additionally, the used timeout event can not be changed via
816  * em_tmo_ack(), the actual received event must always be passed to it.
817  *
818  * The last argument 'tmo_ev' is normally 'EM_EVENT_UNDEF' when activating a new
819  * periodic ring timeout. The implementation will in this case use a
820  * pre-allocated event. The exception case concerns reuse of a canceled ring
821  * timeout event (when em_tmo_ack() returns 'EM_ERR_CANCELED', the event stays
822  * with the user and can be reused). Such an event can be recycled via 'tmo_ev'
823  * to avoid an extra event free and alloc during reactivation.
824  *
825  * This function can only be used with periodic timeouts from a ring timer.
826  * The timeout indication event is read-only and can be accessed only via
827  * accessor APIs.
828  *
829  * @param tmo Timeout handle
830  * @param start_abs Absolute start time (or 0 for period starting at call time)
831  * @param multiplier Rate multiplier (period rate = multiplier * timer base_hz)
832  * @param tmo_ev Event of type EM_EVENT_TYPE_TIMER_IND to reuse.
833  * Normally EM_EVENT_UNDEF.
834  *
835  * @retval EM_OK Success
836  * @retval EM_ERR_TOONEAR Failure, start tick value is past or too close
837  * to current time or multiplier is too high.
838  * @retval EM_ERR_TOOFAR Failure, start tick value exceeds one period.
839  * @retval (other_codes) Failure
840  *
841  * @see em_tmo_get_user_ptr(), em_tmo_get_type(), em_timer_create_ring()
842  */
844  em_timer_tick_t start_abs,
845  uint64_t multiplier,
846  em_event_t tmo_ev);
847 
848 /**
849  * Cancel a timeout
850  *
851  * Cancels a timeout preventing future expiration. Returns the timeout event
852  * if the timeout has not expired.
853  * A timeout that has already expired, or just is about to, is too late to be
854  * cancelled and the timeout event will be delivered to the destination queue.
855  * In this case the error 'EM_ERR_TOONEAR' is returned - no EM error handler is
856  * called.
857  *
858  * Periodic timeout: cancel may fail if attempted too close to the next period.
859  * This can be considered normal and indicates that at least one more timeout
860  * event will be delivered to the user. In this case, the error 'EM_ERR_TOONEAR'
861  * is returned and no valid event is output. The EM error handler is not called
862  * is this scenario.
863  * The user calls em_tmo_ack() for each received periodic timeout event. The
864  * em_tmo_ack() function returns 'EM_ERR_CANCELED' for the last timeout event
865  * from the cancelled periodic timeout to let the user know that it is now OK to
866  * e.g. delete the timeout.
867  *
868  * @param tmo Timeout handle
869  * @param[out] cur_event Event handle pointer to return the pending
870  * timeout event for a successful cancel or
871  * EM_EVENT_UNDEF if cancel fails (e.g. called too late)
872  *
873  * @retval EM_OK Cancel successful, timeout event returned.
874  * @retval EM_ERR_TOONEAR Timeout already expired, too late to cancel.
875  * EM error handler is not called.
876  * @retval (other_codes) Failure
877  *
878  * @see em_tmo_set_abs(), em_tmo_set_rel(), em_tmo_set_periodic(),
879  * em_tmo_set_periodic_ring()
880  * @see em_tmo_ack() for periodic timeouts
881  */
882 em_status_t em_tmo_cancel(em_tmo_t tmo, em_event_t *cur_event);
883 
884 /**
885  * Acknowledge a periodic timeout
886  *
887  * All received periodic timeout events must be acknowledged with em_tmo_ack().
888  * No further timeout event(s) will be sent before the user has acknowledged
889  * the previous one unless a ring timer is used.
890  *
891  * Timeout acknowledgment is usually done at the end of the EO-receive function
892  * to prevent race conditions (e.g. if the same event is reused for the next
893  * timeout period also). The implementation will adjust for the processing delay
894  * so that the time slot will not drift over time.
895  *
896  * If em_tmo_ack() is called too late, e.g. the next period(s) is already
897  * passed, the implementation by default will skip all the missed time slots and
898  * arm for the next future one keeping the original start offset. The
899  * application can alter this behaviour with the flag 'EM_TMO_FLAG_NOSKIP' when
900  * creating a timeout: no past timeout will be skipped and each late
901  * acknowledgment will immediately trigger sending the next timeout event until
902  * the current time has been reached.
903  * Note that using 'EM_TMO_FLAG_NOSKIP' may result in an event storm if a large
904  * number of timeouts have been unacknowledged for a longer time (limited by
905  * application response latency). Timing problems will not call the EM error
906  * handler.
907  *
908  * If the timeout has been canceled, but the cancel happened too late for the
909  * current period, the timeout event will still be delivered. The em_tmo_ack()
910  * call for this event will return 'EM_ERR_CANCELED' and does not call the error
911  * handler. This error code signals that the timeout event was the last one
912  * coming for that, now cancelled, timeout.
913  *
914  * The application may reuse the same received timeout event or provide a new
915  * one for the next timeout via 'next_tmo_ev'. With a periodic ring timer, the
916  * actual received event must be always be passed via 'next_tmo_ev'.
917  *
918  * The given event should not be touched after calling this function until it
919  * has been received again or after the timeout is successfully cancelled and
920  * event returned.
921  *
922  * A regular periodic timeout (i.e. not a ring one) will stop if em_tmo_ack()
923  * returns an error other than related to timing. Unless the timeout was
924  * canceled, the implementation will call the EM error handler in this case
925  * (the error/exception can be handled also there).
926  *
927  * em_tmo_ack() can only be used with periodic timeouts.
928  *
929  * @param tmo Timeout handle
930  * @param next_tmo_ev Next timeout event handle.
931  * Can be the received one for regular periodic timeouts.
932  * Must be the received one for periodic ring timeouts.
933  *
934  * @retval EM_OK Success, event taken.
935  * @retval EM_ERR_CANCELED Timer cancelled, last event - no further timeout
936  * events coming, event not taken.
937  * @retval (other_codes) Failure, event not taken.
938  */
939 em_status_t em_tmo_ack(em_tmo_t tmo, em_event_t next_tmo_ev);
940 
941 /**
942  * Get a list of currently active timers.
943  *
944  * The timer handles returned via 'tmr_list' can be used for further timer
945  * queries or to destroy existing timers.
946  *
947  * The return value always reflects the actual number of timers in the
948  * EM instance but the output parameter 'tmr_list' is only written up to the
949  * given 'max' length.
950  *
951  * Note that the return value (number of timers) can be greater than the given
952  * 'max'. It is the user's responsibility to check the return value against the
953  * given 'max'.
954  *
955  * To only get the current number of active timers, without any timer handles
956  * output, use the following: num_timers = em_timer_get_all(NULL, 0);
957  *
958  * @param[out] tmr_list Pointer to an array of timer handles.
959  * Use NULL if only interested in the return value.
960  * @param max Max number of handles that can be written into
961  * 'tmr_list'. 'max' is ignored if 'tmr_list' is NULL.
962  *
963  * @return The number of active timers
964  */
965 int em_timer_get_all(em_timer_t *tmr_list, int max);
966 
967 /**
968  * Get timer attributes
969  *
970  * Returns the actual capabilities of the given timer.
971  *
972  * @param tmr Timer handle
973  * @param[out] tmr_attr Pointer to em_timer_attr_t to fill
974  *
975  * @return EM_OK on success
976  */
977 em_status_t em_timer_get_attr(em_timer_t tmr, em_timer_attr_t *tmr_attr);
978 
979 /**
980  * Returns the timer frequency, i.e. ticks per second, for the given timer.
981  *
982  * Can be used to convert real time to timer specific ticks.
983  *
984  * @param tmr Timer handle
985  *
986  * @return ticks per second (Hz), or 0 for non-existing timer
987  */
988 uint64_t em_timer_get_freq(em_timer_t tmr);
989 
990 /**
991  * Convert timer ticks to nanoseconds (ns)
992  *
993  * @param tmr Valid timer handle
994  * @param ticks Timer specific ticks to convert
995  *
996  * @return converted amount in ns
997  */
998 uint64_t em_timer_tick_to_ns(em_timer_t tmr, em_timer_tick_t ticks);
999 
1000 /**
1001  * Convert nanoseconds (ns) to timer ticks
1002  *
1003  * @param tmr Valid timer handle
1004  * @param ns ns value to convert
1005  *
1006  * @return converted amount in timer ticks
1007  */
1008 em_timer_tick_t em_timer_ns_to_tick(em_timer_t tmr, uint64_t ns);
1009 
1010 /**
1011  * Returns the current state of the given timeout.
1012  *
1013  * Note that the returned state may change at any time if the timeout expires
1014  * or is manipulated by other threads.
1015  *
1016  * @param tmo Timeout handle
1017  *
1018  * @return current timeout state (EM_TMO_STATE_UNKNOWN on error)
1019  *
1020  * @see em_tmo_state_t
1021  */
1023 
1024 /**
1025  * Returns the statistic counters for a timeout.
1026  *
1027  * Returns a snapshot of the current counters of the given timeout.
1028  * Statistics can be accessed while the timeout is valid, i.e. tmo created but
1029  * not deleted.
1030  *
1031  * Counter support is optional. If counters are not supported, the function
1032  * returns 'EM_ERR_NOT_IMPLEMENTED'.
1033  * A quick way to detect whether counters are supported is to call the function
1034  * with 'stat=NULL' and check the return value.
1035  *
1036  * @param tmo Timeout handle
1037  * @param[out] stat Pointer to em_tmo_stats_t to receive the values (NULL ok)
1038  *
1039  * @return EM_OK on success
1040  */
1042 
1043 /**
1044  * Ask if the given event is currently used as a timeout indication event.
1045  *
1046  * This function can be used with any valid event handle to ask if it is used as
1047  * a timeout indication event.
1048  * Events are updated to a tmo-type when going through the timer API.
1049  * @note Because a received timeout event is owned by the application, and not
1050  * necessarily passing through the timer API anymore, this type will not be
1051  * reset until the event is freed, reused as another timeout or explicitly reset
1052  * by setting the 'reset' argument to true. This reset should be done if
1053  * re-using the received timeout event for something else than a timeout to
1054  * avoid wrong interpretations.
1055  *
1056  * A successful timeout cancel (event returned) will reset the event type to
1057  * 'EM_TMO_TYPE_NONE'.
1058  *
1059  * @note The 'reset' argument is ignored if the given event is of type
1060  * 'EM_EVENT_TYPE_TIMER_IND'.
1061  *
1062  * The related tmo handle can be retrieved via the 'tmo' argument. This
1063  * can be useful when calling em_tmo_ack() for periodic timeouts:
1064  * @code
1065  * em_tmo_t tmo;
1066  *
1067  * if (em_tmo_get_type(event, &tmo, false) == EM_TMO_TYPE_PERIODIC)
1068  * retval = em_tmo_ack(tmo, event);
1069  * @endcode
1070  *
1071  * @param event Event handle to check.
1072  * @param[out] tmo em_tmo_t pointer to output the related tmo handle.
1073  * Use NULL if not interested in the tmo handle.
1074  * @param reset Set to 'true' to reset the event's tmo type to
1075  * 'EM_TMO_TYPE_NONE' to e.g. enable non-timer related reuse
1076  * of the event.
1077  *
1078  * @return The type of the timeout or 'EM_TMO_TYPE_NONE' if event is not related
1079  * to a timeout
1080  * @see em_tmo_type_t
1081  */
1082 em_tmo_type_t em_tmo_get_type(em_event_t event, em_tmo_t *tmo, bool reset);
1083 
1084 /**
1085  * Returns the optional user pointer for a periodic ring timeout.
1086  *
1087  * Can only be used with an event received as a timeout event for a periodic
1088  * ring, i.e. for events of type 'EM_EVENT_TYPE_TIMER_IND' only. Other event
1089  * types will return NULL.
1090  *
1091  * @param event Event received as timeout
1092  * @param[out] tmo Optionally returns associated tmo handle. NULL ok.
1093  *
1094  * @return A pointer given when creating the associated tmo or
1095  * NULL if the event is not a ring timeout event.
1096  */
1097 void *em_tmo_get_userptr(em_event_t event, em_tmo_t *tmo);
1098 
1099 /**
1100  * Returns the associated timer handle from a timeout handle
1101  *
1102  * The associated timer handle is returned from a valid timeout. Can be used to
1103  * e.g. read the current timer tick without having the timer handle:
1104  * @code
1105  * em_timer_tick_t tick = em_timer_current_tick(em_tmo_get_timer(tmo));
1106  * @endcode
1107  *
1108  * @param tmo Valid timeout handle
1109  *
1110  * @return The associated timer handle or
1111  * 'EM_TIMER_UNDEF' if the tmo is not valid
1112  */
1113 em_timer_t em_tmo_get_timer(em_tmo_t tmo);
1114 
1115 /**
1116  * Convert a timer handle to an unsigned integer.
1117  *
1118  * @param timer Timer handle to be converted.
1119  * @return A 'uint64_t' value that can be used to print/display the handle
1120  *
1121  * @note This routine is intended to be used for diagnostic purposes
1122  * to enable applications to e.g. generate a printable value that represents
1123  * an em_timer_t handle.
1124  */
1125 uint64_t em_timer_to_u64(em_timer_t timer);
1126 
1127 /**
1128  * Convert a timeout handle to an unsigned integer.
1129  *
1130  * @param tmo Timeout handle to be converted.
1131  * @return A 'uint64_t' value that can be used to print/display the handle.
1132  *
1133  * @note This routine is intended to be used for diagnostic purposes
1134  * to enable applications to e.g. generate a printable value that represents
1135  * an em_tmo_t handle.
1136  */
1137 uint64_t em_tmo_to_u64(em_tmo_t tmo);
1138 
1139 /**
1140  * @}
1141  */
1142 #ifdef __cplusplus
1143 }
1144 #endif
1145 
1146 #pragma GCC visibility pop
1147 #endif /* EVENT_MACHINE_TIMER_H_ */
uint32_t em_status_t
em_status_t em_timer_capability(em_timer_capability_t *capa, em_timer_clksrc_t clk_src)
em_status_t em_timer_get_attr(em_timer_t tmr, em_timer_attr_t *tmr_attr)
em_status_t em_tmo_set_abs(em_tmo_t tmo, em_timer_tick_t ticks_abs, em_event_t tmo_ev)
uint64_t em_tmo_to_u64(em_tmo_t tmo)
em_tmo_type_t em_tmo_get_type(em_event_t event, em_tmo_t *tmo, bool reset)
struct em_timer_ring_param_t em_timer_ring_param_t
int em_timer_get_all(em_timer_t *tmr_list, int max)
em_status_t em_timer_delete(em_timer_t tmr)
em_timer_t em_tmo_get_timer(em_tmo_t tmo)
struct em_tmo_args_t em_tmo_args_t
em_status_t em_timer_ring_attr_init(em_timer_attr_t *ring_attr, em_timer_clksrc_t clk_src, uint64_t base_hz, uint64_t max_mul, uint64_t res_ns)
em_status_t em_tmo_set_periodic_ring(em_tmo_t tmo, em_timer_tick_t start_abs, uint64_t multiplier, em_event_t tmo_ev)
struct em_timer_attr_t em_timer_attr_t
em_timer_tick_t em_timer_ns_to_tick(em_timer_t tmr, uint64_t ns)
em_tmo_t em_tmo_create(em_timer_t tmr, em_tmo_flag_t flags, em_queue_t queue)
struct em_tmo_stats_t em_tmo_stats_t
em_timer_t em_timer_create(const em_timer_attr_t *tmr_attr)
em_tmo_state_t em_tmo_get_state(em_tmo_t tmo)
em_status_t em_tmo_delete(em_tmo_t tmo)
struct em_timer_capability_t em_timer_capability_t
struct em_timer_res_param_t em_timer_res_param_t
em_status_t em_tmo_cancel(em_tmo_t tmo, em_event_t *cur_event)
struct em_fract_u64_t em_fract_u64_t
em_timer_t em_timer_ring_create(const em_timer_attr_t *ring_attr)
em_status_t em_tmo_set_periodic(em_tmo_t tmo, em_timer_tick_t start_abs, em_timer_tick_t period, em_event_t tmo_ev)
em_status_t em_tmo_get_stats(em_tmo_t tmo, em_tmo_stats_t *stat)
em_timer_tick_t em_timer_current_tick(em_timer_t tmr)
em_status_t em_tmo_set_rel(em_tmo_t tmo, em_timer_tick_t ticks_rel, em_event_t tmo_ev)
uint64_t em_timer_tick_to_ns(em_timer_t tmr, em_timer_tick_t ticks)
uint64_t em_timer_to_u64(em_timer_t timer)
em_tmo_t em_tmo_create_arg(em_timer_t tmr, em_tmo_flag_t flags, em_queue_t queue, em_tmo_args_t *args)
void em_timer_attr_init(em_timer_attr_t *tmr_attr)
uint64_t em_timer_get_freq(em_timer_t tmr)
em_status_t em_timer_ring_capability(em_timer_ring_param_t *ring)
Check periodic ring timer capability.
em_status_t em_tmo_ack(em_tmo_t tmo, em_event_t next_tmo_ev)
void * em_tmo_get_userptr(em_event_t event, em_tmo_t *tmo)
uint64_t em_timer_tick_t
em_status_t em_timer_res_capability(em_timer_res_param_t *res, em_timer_clksrc_t clk_src)
@ EM_TMO_STATE_INACTIVE
@ EM_TMO_STATE_IDLE
@ EM_TMO_STATE_ACTIVE
@ EM_TMO_TYPE_ONESHOT
@ EM_TMO_TYPE_NONE
@ EM_TMO_TYPE_PERIODIC
em_timer_ring_param_t ringparam
char name[EM_TIMER_NAME_LEN]
em_timer_res_param_t resparam
em_timer_res_param_t max_tmo
struct em_timer_capability_t::@2 ring
em_timer_res_param_t max_res