ChibiOS  21.6.0
chvt.c
Go to the documentation of this file.
1 /*
2  ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
3  2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
4 
5  This file is part of ChibiOS.
6 
7  ChibiOS is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation version 3 of the License.
10 
11  ChibiOS is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 /**
21  * @file rt/src/chvt.c
22  * @brief Time and Virtual Timers module code.
23  *
24  * @addtogroup time
25  * @details Time and Virtual Timers related APIs and services.
26  * @{
27  */
28 
29 #include "ch.h"
30 
31 /*===========================================================================*/
32 /* Module local definitions. */
33 /*===========================================================================*/
34 
35 /*===========================================================================*/
36 /* Module exported variables. */
37 /*===========================================================================*/
38 
39 /*===========================================================================*/
40 /* Module local types. */
41 /*===========================================================================*/
42 
43 /*===========================================================================*/
44 /* Module local variables. */
45 /*===========================================================================*/
46 
47 /*===========================================================================*/
48 /* Module local functions. */
49 /*===========================================================================*/
50 
51 #if (CH_CFG_ST_TIMEDELTA > 0) || defined(__DOXYGEN__)
52 /**
53  * @brief Inserts a timer as first element in a delta list.
54  * @note This is the special case when the delta list is initially empty.
55  */
57  virtual_timer_t *vtp,
58  systime_t now,
59  sysinterval_t delay) {
60 
61  /* The delta list is empty, the current time becomes the new
62  delta list base time, the timer is inserted.*/
63  vtlp->lasttime = now;
64  ch_dlist_insert_after(&vtlp->dlist, &vtp->dlist, delay);
65 
66  /* If the requested delay is lower than the minimum safe delta then it
67  is raised to the minimum safe value.*/
68  if (delay < (sysinterval_t)CH_CFG_ST_TIMEDELTA) {
69  /* We need to avoid that the system time goes past the alarm we are
70  going to set before the alarm is actually set.*/
71  delay = (sysinterval_t)CH_CFG_ST_TIMEDELTA;
72  }
73 #if CH_CFG_INTERVALS_SIZE > CH_CFG_ST_RESOLUTION
74  else if (delay > (sysinterval_t)TIME_MAX_SYSTIME) {
75  /* The delta could be too large for the physical timer to handle
76  this can happen when: sizeof (systime_t) < sizeof (sysinterval_t).*/
78  }
79 #endif
80 
81  /* Being the first element inserted in the list the alarm timer
82  is started.*/
83  port_timer_start_alarm(chTimeAddX(vtlp->lasttime, delay));
84 }
85 #endif /* CH_CFG_ST_TIMEDELTA > 0 */
86 
87 /**
88  * @brief Enqueues a virtual timer in a virtual timers list.
89  */
91  virtual_timer_t *vtp,
92  systime_t now,
93  sysinterval_t delay) {
94  sysinterval_t delta;
95 
96 #if CH_CFG_ST_TIMEDELTA > 0
97  {
98  sysinterval_t nowdelta;
99 
100  /* Special case where the timers list is empty.*/
101  if (ch_dlist_isempty(&vtlp->dlist)) {
102 
103  vt_insert_first(vtlp, vtp, now, delay);
104 
105  return;
106  }
107 
108  /* Delay as delta from 'lasttime'. Note, it can overflow and the value
109  becomes lower than 'deltanow'.*/
110  nowdelta = chTimeDiffX(vtlp->lasttime, now);
111  delta = nowdelta + delay;
112 
113  /* Scenario where a very large delay exceeded the numeric range, the
114  delta is shortened to make it fit the numeric range, the timer
115  will be triggered "deltanow" cycles earlier.*/
116  if (delta < nowdelta) {
117  delta = delay;
118  }
119 
120  /* Checking if this timer would become the first in the delta list, this
121  requires changing the current alarm setting.*/
122  if (delta < vtlp->dlist.next->delta) {
123  sysinterval_t deadline_delta;
124 
125  /* A small delay that will become the first element in the delta list
126  and next deadline.*/
127  deadline_delta = delta;
128 
129  /* Limit delta to CH_CFG_ST_TIMEDELTA.*/
130  if (deadline_delta < (sysinterval_t)CH_CFG_ST_TIMEDELTA) {
131  deadline_delta = (sysinterval_t)CH_CFG_ST_TIMEDELTA;
132  }
133 #if CH_CFG_INTERVALS_SIZE > CH_CFG_ST_RESOLUTION
134  /* The delta could be too large for the physical timer to handle
135  this can happen when: sizeof (systime_t) < sizeof (sysinterval_t).*/
136  else if (deadline_delta > (sysinterval_t)TIME_MAX_SYSTIME) {
137  deadline_delta = (sysinterval_t)TIME_MAX_SYSTIME;
138  }
139 #endif
140  port_timer_set_alarm(chTimeAddX(vtlp->lasttime, deadline_delta));
141  }
142  }
143 #else /* CH_CFG_ST_TIMEDELTA == 0 */
144  (void)now;
145 
146  /* Delta is initially equal to the specified delay.*/
147  delta = delay;
148 #endif /* CH_CFG_ST_TIMEDELTA == 0 */
149 
150  ch_dlist_insert(&vtlp->dlist, &vtp->dlist, delta);
151 }
152 
153 /*===========================================================================*/
154 /* Module exported functions. */
155 /*===========================================================================*/
156 
157 /**
158  * @brief Enables a one-shot virtual timer.
159  * @details The timer is enabled and programmed to trigger after the delay
160  * specified as parameter.
161  * @pre The timer must not be already armed before calling this function.
162  * @note The callback function is invoked from interrupt context.
163  *
164  * @param[out] vtp the @p virtual_timer_t structure pointer
165  * @param[in] delay the number of ticks before the operation timeouts, the
166  * special values are handled as follow:
167  * - @a TIME_INFINITE is allowed but interpreted as a
168  * normal time specification.
169  * - @a TIME_IMMEDIATE this value is not allowed.
170  * .
171  * @param[in] vtfunc the timer callback function. After invoking the
172  * callback the timer is disabled and the structure can
173  * be disposed or reused.
174  * @param[in] par a parameter that will be passed to the callback
175  * function
176  *
177  * @iclass
178  */
180  vtfunc_t vtfunc, void *par) {
181  virtual_timers_list_t *vtlp = &currcore->vtlist;
182 
183  chDbgCheckClassI();
184  chDbgCheck((vtp != NULL) && (vtfunc != NULL) && (delay != TIME_IMMEDIATE));
185 
186  /* Timer initialization.*/
187  vtp->par = par;
188  vtp->func = vtfunc;
189  vtp->reload = (sysinterval_t)0;
190 
191  /* Inserting the timer in the delta list.*/
192  vt_enqueue(vtlp, vtp, chVTGetSystemTimeX(), delay);
193 }
194 
195 /**
196  * @brief Enables a continuous virtual timer.
197  * @details The timer is enabled and programmed to trigger after the delay
198  * specified as parameter.
199  * @pre The timer must not be already armed before calling this function.
200  * @note The callback function is invoked from interrupt context.
201  *
202  * @param[out] vtp the @p virtual_timer_t structure pointer
203  * @param[in] delay the number of ticks before the operation timeouts, the
204  * special values are handled as follow:
205  * - @a TIME_INFINITE is allowed but interpreted as a
206  * normal time specification.
207  * - @a TIME_IMMEDIATE this value is not allowed.
208  * .
209  * @param[in] vtfunc the timer callback function. After invoking the
210  * callback the timer is disabled and the structure can
211  * be disposed or reused.
212  * @param[in] par a parameter that will be passed to the callback
213  * function
214  *
215  * @iclass
216  */
218  vtfunc_t vtfunc, void *par) {
219  virtual_timers_list_t *vtlp = &currcore->vtlist;
220 
221  chDbgCheckClassI();
222  chDbgCheck((vtp != NULL) && (vtfunc != NULL) && (delay != TIME_IMMEDIATE));
223 
224  /* Timer initialization.*/
225  vtp->par = par;
226  vtp->func = vtfunc;
227  vtp->reload = delay;
228 
229  /* Inserting the timer in the delta list.*/
230  vt_enqueue(vtlp, vtp, chVTGetSystemTimeX(), delay);
231 }
232 
233 /**
234  * @brief Disables a Virtual Timer.
235  * @pre The timer must be in armed state before calling this function.
236  *
237  * @param[in] vtp the @p virtual_timer_t structure pointer
238  *
239  * @iclass
240  */
242  virtual_timers_list_t *vtlp = &currcore->vtlist;
243 
244  chDbgCheckClassI();
245  chDbgCheck(vtp != NULL);
246  chDbgAssert(chVTIsArmedI(vtp), "timer not armed");
247 
248 #if CH_CFG_ST_TIMEDELTA == 0
249 
250  /* The delta of the timer is added to the next timer.*/
251  vtp->dlist.next->delta += vtp->dlist.delta;
252 
253  /* Removing the element from the delta list, marking it as not armed.*/
254  (void) ch_dlist_dequeue(&vtp->dlist);
255  vtp->dlist.next = NULL;
256 
257  /* The above code changes the value in the header when the removed element
258  is the last of the list, restoring it.*/
259  vtlp->dlist.delta = (sysinterval_t)-1;
260 #else /* CH_CFG_ST_TIMEDELTA > 0 */
261  sysinterval_t nowdelta, delta;
262 
263  /* If the timer is not the first of the list then it is simply unlinked
264  else the operation is more complex.*/
265  if (!ch_dlist_isfirst(&vtlp->dlist, &vtp->dlist)) {
266 
267  /* Removing the element from the delta list.*/
268  (void) ch_dlist_dequeue(&vtp->dlist);
269 
270  /* Adding delta to the next element, if it is not the last one.*/
271  vtp->dlist.next->delta += vtp->dlist.delta;
272 
273  /* Marking timer as not armed.*/
274  vtp->dlist.next = NULL;
275 
276  /* Special case when the removed element from the last position in the list,
277  the value in the header must be restored, just doing it is faster than
278  checking then doing.*/
279  vtlp->dlist.delta = (sysinterval_t)-1;
280 
281  return;
282  }
283 
284  /* Removing the first timer from the list, marking it as not armed.*/
286  vtp->dlist.next = NULL;
287 
288  /* If the list become empty then the alarm timer is stopped and done.*/
289  if (ch_dlist_isempty(&vtlp->dlist)) {
290  port_timer_stop_alarm();
291 
292  return;
293  }
294 
295  /* The delta of the removed timer is added to the new first timer.*/
296  vtlp->dlist.next->delta += vtp->dlist.delta;
297 
298  /* Distance in ticks between the last alarm event and current time.*/
299  nowdelta = chTimeDiffX(vtlp->lasttime, chVTGetSystemTimeX());
300 
301  /* If the current time surpassed the time of the next element in list
302  then the event interrupt is already pending, just return.*/
303  if (nowdelta >= vtlp->dlist.next->delta) {
304  return;
305  }
306 
307  /* Distance from the next scheduled event and now.*/
308  delta = vtlp->dlist.next->delta - nowdelta;
309 
310  /* Making sure to not schedule an event closer than CH_CFG_ST_TIMEDELTA
311  ticks from now.*/
312  if (delta < (sysinterval_t)CH_CFG_ST_TIMEDELTA) {
313  delta = nowdelta + (sysinterval_t)CH_CFG_ST_TIMEDELTA;
314  }
315  else {
316  delta = nowdelta + delta;
317 #if CH_CFG_INTERVALS_SIZE > CH_CFG_ST_RESOLUTION
318  /* The delta could be too large for the physical timer to handle.*/
319  if (delta > (sysinterval_t)TIME_MAX_SYSTIME) {
321  }
322 #endif
323  }
324  port_timer_set_alarm(chTimeAddX(vtlp->lasttime, delta));
325 #endif /* CH_CFG_ST_TIMEDELTA > 0 */
326 }
327 
328 /**
329  * @brief Returns the remaining time interval before next timer trigger.
330  * @note This function can be called while the timer is active.
331  *
332  * @param[in] vtp the @p virtual_timer_t structure pointer
333  * @return The remaining time interval.
334  *
335  * @iclass
336  */
338  virtual_timers_list_t *vtlp = &currcore->vtlist;
339  sysinterval_t delta;
340  ch_delta_list_t *dlp;
341 
342  chDbgCheckClassI();
343 
344  delta = (sysinterval_t)0;
345  dlp = vtlp->dlist.next;
346  do {
347  delta += dlp->delta;
348  if (dlp == &vtp->dlist) {
349 #if CH_CFG_ST_TIMEDELTA > 0
351  sysinterval_t nowdelta = chTimeDiffX(vtlp->lasttime, now);
352  if (nowdelta > delta) {
353  return (sysinterval_t)0;
354  }
355  return delta - nowdelta;
356 #else
357  return delta;
358 #endif
359  }
360  dlp = dlp->next;
361  } while (dlp != &vtlp->dlist);
362 
363  chDbgAssert(false, "timer not in list");
364 
365  return (sysinterval_t)-1;
366 }
367 
368 /**
369  * @brief Virtual timers ticker.
370  * @note The system lock is released before entering the callback and
371  * re-acquired immediately after. It is callback's responsibility
372  * to acquire the lock if needed. This is done in order to reduce
373  * interrupts jitter when many timers are in use.
374  *
375  * @iclass
376  */
377 void chVTDoTickI(void) {
378  virtual_timers_list_t *vtlp = &currcore->vtlist;
379 
380  chDbgCheckClassI();
381 
382 #if CH_CFG_ST_TIMEDELTA == 0
383  vtlp->systime++;
384  if (ch_dlist_notempty(&vtlp->dlist)) {
385  /* The list is not empty, processing elements on top.*/
386  --vtlp->dlist.next->delta;
387  while (vtlp->dlist.next->delta == (sysinterval_t)0) {
388  virtual_timer_t *vtp;
389 
390  /* Triggered timer.*/
391  vtp = (virtual_timer_t *)vtlp->dlist.next;
392 
393  /* Removing the element from the delta list, marking it as not armed.*/
394  (void) ch_dlist_dequeue(&vtp->dlist);
395  vtp->dlist.next = NULL;
396 
398  vtp->func(vtp, vtp->par);
400 
401  /* If a reload is defined the timer needs to be restarted.*/
402  if (vtp->reload > (sysinterval_t)0) {
403  ch_dlist_insert(&vtlp->dlist, &vtp->dlist, vtp->reload);
404  }
405  }
406  }
407 #else /* CH_CFG_ST_TIMEDELTA > 0 */
408  virtual_timer_t *vtp;
409  sysinterval_t delta, nowdelta;
410  systime_t now;
411 
412  /* Looping through timers consuming all timers with deltas lower or equal
413  than the interval between "now" and "lasttime".*/
414  while (true) {
415  systime_t lasttime;
416 
417  /* First timer in the delta list.*/
418  vtp = (virtual_timer_t *)vtlp->dlist.next;
419 
420  /* Delta between current time and last execution time.*/
421  now = chVTGetSystemTimeX();
422  nowdelta = chTimeDiffX(vtlp->lasttime, now);
423 
424  /* Loop break condition.
425  Note that the list scan is limited by the delta list header having
426  "vtlp->dlist.delta == (sysinterval_t)-1" which is greater than all
427  deltas*/
428  if (nowdelta < vtp->dlist.delta) {
429  break;
430  }
431 
432  /* Last time deadline is updated to the next timer's time.*/
433  lasttime = chTimeAddX(vtlp->lasttime, vtp->dlist.delta);
434  vtlp->lasttime = lasttime;
435 
436  /* Removing the timer from the list, marking it as not armed.*/
437  (void) ch_dlist_dequeue(&vtp->dlist);
438  vtp->dlist.next = NULL;
439 
440  /* If the list becomes empty then the alarm is disabled.*/
441  if (ch_dlist_isempty(&vtlp->dlist)) {
442  port_timer_stop_alarm();
443  }
444 
445  /* The callback is invoked outside the kernel critical section, it
446  is re-entered on the callback return. Note that "lasttime" can be
447  modified within the callback if some timer function is called.*/
449  vtp->func(vtp, vtp->par);
451 
452  /* If a reload is defined the timer needs to be restarted.*/
453  if (unlikely(vtp->reload > (sysinterval_t)0)) {
454  sysinterval_t delay;
455 
456  /* Refreshing the current time after spending time in the callback for
457  a more accurate detection of too fast reloads.*/
458  now = chVTGetSystemTimeX();
459  nowdelta = chTimeDiffX(lasttime, now);
460 
461 #if !defined(CH_VT_RFCU_DISABLED)
462  /* Checking if the required reload is feasible.*/
463  if (nowdelta > vtp->reload) {
464  /* System time is already past the deadline, logging the fault and
465  proceeding with a minimum delay.*/
466 
467  chDbgAssert(false, "skipped deadline");
468  chRFCUCollectFaultsI(CH_RFCU_VT_SKIPPED_DEADLINE);
469 
470  delay = (sysinterval_t)0;
471  }
472  else {
473  /* Enqueuing the timer again using the calculated delta.*/
474  delay = vtp->reload - nowdelta;
475  }
476 #else
477  chDbgAssert(nowdelta <= vtp->reload, "skipped deadline");
478 
479  /* Enqueuing the timer again using the calculated delta.*/
480  delay = vtp->reload - nowdelta;
481 #endif
482 
483  /* Special case where the timers list is empty.*/
484  if (ch_dlist_isempty(&vtlp->dlist)) {
485 
486  vt_insert_first(vtlp, vtp, now, delay);
487 
488  return;
489  }
490 
491  /* Delay as delta from 'lasttime'. Note, it can overflow and the value
492  becomes lower than 'nowdelta'. In that case the delta is shortened
493  to make it fit the numeric range and the timer will be triggered
494  "nowdelta" cycles earlier.*/
495  delta = nowdelta + delay;
496  if (delta < nowdelta) {
497  delta = delay;
498  }
499 
500  /* Insert into delta list. */
501  ch_dlist_insert(&vtlp->dlist, &vtp->dlist, delta);
502  }
503  }
504 
505  /* If the list is empty, nothing else to do.*/
506  if (ch_dlist_isempty(&vtlp->dlist)) {
507  return;
508  }
509 
510  /* Calculating the delta to the next alarm time.*/
511  delta = vtp->dlist.delta - nowdelta;
512 
513  /* Limit delta to CH_CFG_ST_TIMEDELTA.*/
514  if (delta < (sysinterval_t)CH_CFG_ST_TIMEDELTA) {
515  delta = (sysinterval_t)CH_CFG_ST_TIMEDELTA;
516  }
517 #if CH_CFG_INTERVALS_SIZE > CH_CFG_ST_RESOLUTION
518  /* The delta could be too large for the physical timer to handle.*/
519  else if (delta > (sysinterval_t)TIME_MAX_SYSTIME) {
521  }
522 #endif
523 
524  /* Update alarm time to next timer.*/
525  {
526  sysinterval_t next_alarm = chTimeAddX(now, delta);
527 
528  port_timer_set_alarm(next_alarm);
529 
530 #if !defined(CH_VT_RFCU_DISABLED)
531  if (chTimeDiffX(vtlp->lasttime, chVTGetSystemTimeX()) >
532  chTimeDiffX(vtlp->lasttime, next_alarm)) {
533 
534  chDbgAssert(false, "insufficient delta");
535  chRFCUCollectFaultsI(CH_RFCU_VT_INSUFFICIENT_DELTA);
536  }
537 #else
539  chTimeDiffX(vtlp->lasttime, next_alarm),
540  "insufficient delta");
541 #endif
542  }
543 #endif /* CH_CFG_ST_TIMEDELTA > 0 */
544 }
545 
546 #if (CH_CFG_USE_TIMESTAMP == TRUE) || defined(__DOXYGEN__)
547 /**
548  * @brief Generates a monotonic time stamp.
549  * @details This function generates a monotonic time stamp synchronized with
550  * the system time. The time stamp has the same resolution of
551  * system time.
552  * @note There is an assumption, this function must be called at
553  * least once before the system time wraps back to zero or
554  * synchronization is lost. You may use a periodic virtual timer with
555  * a very large interval in order to keep time stamps synchronized
556  * by calling this function.
557  *
558  * @return The time stamp.
559  *
560  * @iclass
561  */
563  os_instance_t * oip = currcore;
564  systimestamp_t last, stamp;
565  systime_t now;
566 
567  chDbgCheckClassI();
568 
569  /* Current system time.*/
570  now = chVTGetSystemTimeX();
571 
572  /* Last time stamp generated.*/
573  last = oip->vtlist.laststamp;
574 
575  /* Interval between the last time stamp and current time used for a new
576  time stamp. Note that this fails if the interval is larger than a
577  systime_t type.*/
578  stamp = last + (systimestamp_t)chTimeDiffX((systime_t)last, now);
579 
580  chDbgAssert(oip->vtlist.laststamp <= stamp, "wrapped");
581 
582  /* Storing the new stamp.*/
583  oip->vtlist.laststamp = stamp;
584 
585  return stamp;
586 }
587 
588 /**
589  * @brief Resets and re-synchronizes the time stamps monotonic counter.
590  *
591  * @iclass
592  */
594 
595  chDbgCheckClassI();
596 
597  currcore->vtlist.laststamp = (systimestamp_t)chVTGetSystemTimeX();
598 }
599 
600 #endif /* CH_CFG_USE_TIMESTAMP == TRUE */
601 
602 /** @} */
chVTDoTickI
void chVTDoTickI(void)
Virtual timers ticker.
Definition: chvt.c:377
chVTGetSystemTimeX
#define chVTGetSystemTimeX()
Current system time.
Definition: nil/include/ch.h:1254
ch_virtual_timer::dlist
ch_delta_list_t dlist
Delta list element.
Definition: chobjects.h:79
chVTGetTimeStampI
systimestamp_t chVTGetTimeStampI(void)
Generates a monotonic time stamp.
Definition: chvt.c:562
chTimeDiffX
#define chTimeDiffX(start, end)
Subtracts two system times returning an interval.
Definition: nil/include/ch.h:1307
ch_os_instance::vtlist
virtual_timers_list_t vtlist
Virtual timers delta list header.
Definition: chobjects.h:402
currcore
#define currcore
Access to current core's instance structure.
Definition: chsys.h:90
chVTIsArmedI
static bool chVTIsArmedI(const virtual_timer_t *vtp)
Returns true if the specified timer is armed.
Definition: chvt.h:248
chSysUnlockFromISR
#define chSysUnlockFromISR()
Leaves the kernel lock state from within an interrupt handler.
Definition: nil/include/ch.h:1088
systime_t
uint64_t systime_t
Type of system time.
Definition: chtime.h:107
vtfunc_t
void(* vtfunc_t)(virtual_timer_t *vtp, void *p)
Type of a Virtual Timer callback function.
Definition: chobjects.h:70
chDbgAssert
#define chDbgAssert(c, r)
Condition assertion.
Definition: chdebug.h:144
chVTResetTimeStampI
void chVTResetTimeStampI(void)
Resets and re-synchronizes the time stamps monotonic counter.
Definition: chvt.c:593
chSysLockFromISR
#define chSysLockFromISR()
Enters the kernel lock state from within an interrupt handler.
Definition: nil/include/ch.h:1070
ch_os_instance
System instance data structure.
Definition: chobjects.h:394
chVTGetRemainingIntervalI
sysinterval_t chVTGetRemainingIntervalI(virtual_timer_t *vtp)
Returns the remaining time interval before next timer trigger.
Definition: chvt.c:337
ch_virtual_timer::func
vtfunc_t func
Timer callback function pointer.
Definition: chobjects.h:83
systimestamp_t
uint64_t systimestamp_t
Type of a time stamp.
Definition: chtime.h:129
chRFCUCollectFaultsI
void chRFCUCollectFaultsI(rfcu_mask_t mask)
Adds fault flags to the current mask.
Definition: chrfcu.c:60
ch_dlist_isempty
static bool ch_dlist_isempty(ch_delta_list_t *dlhp)
Evaluates to true if the specified delta list is empty.
Definition: chlists.h:441
ch_dlist_dequeue
static ch_delta_list_t * ch_dlist_dequeue(ch_delta_list_t *dlp)
Dequeues an element from the delta list.
Definition: chlists.h:587
ch_dlist_insert_after
static void ch_dlist_insert_after(ch_delta_list_t *dlhp, ch_delta_list_t *dlp, sysinterval_t delta)
Inserts an element after another header element.
Definition: chlists.h:496
vt_enqueue
static void vt_enqueue(virtual_timers_list_t *vtlp, virtual_timer_t *vtp, systime_t now, sysinterval_t delay)
Enqueues a virtual timer in a virtual timers list.
Definition: chvt.c:90
chDbgCheck
#define chDbgCheck(c)
Function parameters check.
Definition: chdebug.h:118
TIME_IMMEDIATE
#define TIME_IMMEDIATE
Zero interval specification for some functions with a timeout specification.
Definition: chtime.h:47
ch_virtual_timers_list::dlist
ch_delta_list_t dlist
Delta list header.
Definition: chobjects.h:104
ch_virtual_timers_list::systime
volatile systime_t systime
System Time counter.
Definition: chobjects.h:109
ch_delta_list::delta
sysinterval_t delta
Time interval from previous.
Definition: chlists.h:103
ch_delta_list::next
ch_delta_list_t * next
Next in the delta list.
Definition: chlists.h:101
ch_virtual_timer::reload
sysinterval_t reload
Current reload interval.
Definition: chobjects.h:91
ch_dlist_isfirst
static bool ch_dlist_isfirst(ch_delta_list_t *dlhp, ch_delta_list_t *dlp)
Fist element in the delta list check.
Definition: chlists.h:481
ch_virtual_timers_list::laststamp
volatile uint64_t laststamp
Last generated time stamp.
Definition: chobjects.h:121
ch_virtual_timer
Structure representing a Virtual Timer.
Definition: chobjects.h:75
ch_dlist_notempty
static bool ch_dlist_notempty(ch_delta_list_t *dlhp)
Evaluates to true if the specified queue is not empty.
Definition: chlists.h:454
sysinterval_t
uint64_t sysinterval_t
Type of time interval.
Definition: chtime.h:119
TIME_MAX_SYSTIME
#define TIME_MAX_SYSTIME
Maximum system of system time before it wraps.
Definition: chtime.h:65
chVTDoResetI
void chVTDoResetI(virtual_timer_t *vtp)
Disables a Virtual Timer.
Definition: chvt.c:241
chTimeAddX
#define chTimeAddX(systime, interval)
Adds an interval to a system time returning a system time.
Definition: nil/include/ch.h:1295
ch_virtual_timers_list::lasttime
systime_t lasttime
System time of the last tick event.
Definition: chobjects.h:115
ch_virtual_timers_list
Type of virtual timers list header.
Definition: chobjects.h:100
unlikely
#define unlikely(x)
Marks a boolean expression as likely false.
Definition: chearly.h:191
vt_insert_first
static void vt_insert_first(virtual_timers_list_t *vtlp, virtual_timer_t *vtp, systime_t now, sysinterval_t delay)
Inserts a timer as first element in a delta list.
Definition: chvt.c:56
chVTDoSetI
void chVTDoSetI(virtual_timer_t *vtp, sysinterval_t delay, vtfunc_t vtfunc, void *par)
Enables a one-shot virtual timer.
Definition: chvt.c:179
ch_dlist_insert
static void ch_dlist_insert(ch_delta_list_t *dlhp, ch_delta_list_t *dlep, sysinterval_t delta)
Inserts an element in a delta list.
Definition: chlists.h:536
ch_virtual_timer::par
void * par
Timer callback function parameter.
Definition: chobjects.h:87
ch_dlist_remove_first
static ch_delta_list_t * ch_dlist_remove_first(ch_delta_list_t *dlhp)
Dequeues an element from the delta list.
Definition: chlists.h:571
chVTDoSetContinuousI
void chVTDoSetContinuousI(virtual_timer_t *vtp, sysinterval_t delay, vtfunc_t vtfunc, void *par)
Enables a continuous virtual timer.
Definition: chvt.c:217
ch_delta_list
Delta list element and header structure.
Definition: chlists.h:100