IntrOS
Loading...
Searching...
No Matches
ostimer.h
1/******************************************************************************
2
3 @file IntrOS: ostimer.h
4 @author Rajmund Szymanski
5 @date 18.11.2025
6 @brief This file contains definitions for IntrOS.
7
8 ******************************************************************************
9
10 Copyright (c) 2018-2022 Rajmund Szymanski. All rights reserved.
11
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files (the "Software"), to
14 deal in the Software without restriction, including without limitation the
15 rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
16 sell copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be included
20 in all copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
28 IN THE SOFTWARE.
29
30 ******************************************************************************/
31
32#ifndef __INTROS_TMR_H
33#define __INTROS_TMR_H
34
35#include "oskernel.h"
36#include "osclock.h"
37
43
47
48struct __tmr
49{
50 obj_t obj;
51 hdr_t hdr;
52
53 fun_t * proc;
54 void * arg;
55 cnt_t start;
56 cnt_t delay;
57 cnt_t period;
58};
59
60typedef struct __tmr tmr_id [];
61
62/******************************************************************************
63 *
64 * Name : _TMR_INIT
65 *
66 * Description : create and initialize a timer object
67 *
68 * Parameters
69 * proc : callback procedure
70 * NULL: no callback
71 *
72 * Return : timer object
73 *
74 * Note : for internal use
75 *
76 ******************************************************************************/
77
78#define _TMR_INIT( _proc ) \
79 { _OBJ_INIT(), _HDR_INIT(), _proc, NULL, 0, 0, 0 }
80
89#define OS_TMR( tmr, proc ) \
90 tmr_t tmr[] = { _TMR_INIT( proc ) }
91
92/** static alias of OS_TMR() */
93#define static_TMR( tmr, proc ) \
94 static tmr_t tmr[] = { _TMR_INIT( proc ) }
95
104#define OS_TMR_DEF( tmr ) \
105 static void tmr##__fun( void ); \
106 OS_TMR( tmr, tmr##__fun ); \
107 static void tmr##__fun( void )
108
109/** static alias of OS_TMR_DEF() */
110#define static_TMR_DEF( tmr ) \
111 static void tmr##__fun( void ); \
112 static_TMR( tmr, tmr##__fun ); \
113 static void tmr##__fun( void )
114
130
131#ifdef __CONSTRUCTOR
132#define OS_TMR_START( tmr, delay, period ) \
133 static void tmr##__fun( void ); \
134 OS_TMR( tmr, tmr##__fun ); \
135 __CONSTRUCTOR static void tmr##__run( void ) { tmr_start(tmr, delay, period); } \
136 static void tmr##__fun( void )
137#endif
138
139#ifdef __CONSTRUCTOR
140/** static alias of OS_TMR_START() */
141#define static_TMR_START( tmr, delay, period ) \
142 static void tmr##__fun( void ); \
143 static_TMR( tmr, tmr##__fun ); \
144 __CONSTRUCTOR static void tmr##__run( void ) { tmr_start(tmr, delay, period); } \
145 static void tmr##__fun( void )
146#endif
147
158
159#ifdef __CONSTRUCTOR
160#define OS_TMR_UNTIL( tmr, time ) \
161 static void tmr##__fun( void ); \
162 OS_TMR( tmr, tmr##__fun ); \
163 __CONSTRUCTOR static void tmr##__run( void ) { tmr_startUntil(tmr, time); } \
164 static void tmr##__fun( void )
165#endif
166
167#ifdef __CONSTRUCTOR
168/** static alias of OS_TMR_UNTIL() */
169#define static_TMR_UNTIL( tmr, time ) \
170 static void tmr##__fun( void ); \
171 static_TMR( tmr, tmr##__fun ); \
172 __CONSTRUCTOR static void tmr##__run( void ) { tmr_startUntil(tmr, time); } \
173 static void tmr##__fun( void )
174#endif
175
186
187#ifndef __cplusplus
188#define TMR_INIT( proc ) \
189 _TMR_INIT( proc )
190#endif
191
202
203#ifndef __cplusplus
204#define TMR_CREATE( proc ) \
205 { TMR_INIT ( proc ) }
206/** alias of TMR_CREATE() */
207#define TMR_NEW \
208 TMR_CREATE
209#endif
210
211#ifdef __cplusplus
212extern "C" {
213#endif
214
222
223__STATIC_INLINE
224tmr_t *tmr_this( void ) { return (tmr_t *) System.cur; }
225
234void tmr_init( tmr_t *tmr, fun_t *proc );
235
244void tmr_reset( tmr_t *tmr );
245
247__STATIC_INLINE
248void tmr_kill( tmr_t *tmr ) { tmr_reset(tmr); }
249
266void tmr_start( tmr_t *tmr, cnt_t delay, cnt_t period );
267
278
279__STATIC_INLINE
280void tmr_startFor( tmr_t *tmr, cnt_t delay ) { tmr_start(tmr, delay, 0); }
281
294
295__STATIC_INLINE
296void tmr_startPeriodic( tmr_t *tmr, cnt_t period ) { tmr_start(tmr, period, period); }
297
316void tmr_startFrom( tmr_t *tmr, cnt_t delay, cnt_t period, fun_t *proc );
317
329void tmr_startNext( tmr_t *tmr, cnt_t delay );
330
340void tmr_startUntil( tmr_t *tmr, cnt_t time );
341
347
348__STATIC_INLINE
349void tmr_stop( tmr_t *tmr ) { tmr_reset(tmr); }
350
361int tmr_take( tmr_t *tmr );
362
364__STATIC_INLINE
365int tmr_expired( tmr_t *tmr ) { return tmr_take(tmr); }
366
368__STATIC_INLINE
369int tmr_tryWait( tmr_t *tmr ) { return tmr_take(tmr); }
370
385int tmr_waitFor( tmr_t *tmr, cnt_t delay );
386
405int tmr_waitNext( tmr_t *tmr, cnt_t delay );
406
421int tmr_waitUntil( tmr_t *tmr, cnt_t time );
422
432
433__STATIC_INLINE
434int tmr_wait( tmr_t *tmr ) { return tmr_waitFor(tmr, INFINITE); }
435
444
445__STATIC_INLINE
446void tmr_flip( fun_t *proc ) { tmr_this()->proc = proc; }
447
457
458__STATIC_INLINE
459void tmr_delay( cnt_t delay ) { tmr_this()->delay = delay; }
460
461#ifdef __cplusplus
462}
463#endif
464
465/* -------------------------------------------------------------------------- */
466
467#if defined(__cplusplus)
468namespace intros {
469
470/******************************************************************************
471 *
472 * Class : baseTimer
473 *
474 * Description : create and initialize base class for timer objects
475 *
476 * Constructor parameters
477 * proc : callback procedure
478 * nullptr: no callback
479 *
480 * Note : for internal use
481 *
482 ******************************************************************************/
483
484struct baseTimer : public __tmr
485{
486 baseTimer(): __tmr _TMR_INIT(nullptr) {}
487#if __cplusplus >= 201402L
488 template<class F>
489 baseTimer( F&& _proc ): __tmr _TMR_INIT(fun_), fun{_proc} {}
490#else
491 baseTimer( fun_t *_proc ): __tmr _TMR_INIT(_proc) {}
492#endif
493
494 void reset () { tmr_reset (this); }
495 void kill () { tmr_kill (this); }
496 template<typename T>
497 void start ( const T& _delay, const T& _period ) { tmr_start (this, Clock::count(_delay), Clock::count(_period)); }
498 template<typename T>
499 void startFor ( const T& _delay ) { tmr_startFor (this, Clock::count(_delay)); }
500 template<typename T>
501 void startPeriodic( const T& _period ) { tmr_startPeriodic(this, Clock::count(_period)); }
502 template<typename T>
503 void startNext ( const T& _delay ) { tmr_startNext (this, Clock::count(_delay)); }
504 template<typename T>
505 void startUntil ( const T& _time ) { tmr_startUntil (this, Clock::until(_time)); }
506#if __cplusplus >= 201402L
507 template<typename T>
508 void startFrom ( const T& _delay, const T& _period, std::nullptr_t ) { tmr_startFrom (this, Clock::count(_delay), Clock::count(_period), nullptr); }
509 template<typename T, class F>
510 void startFrom ( const T& _delay, const T& _period, F&& _proc ) { fun = Fun_t(_proc);
511 tmr_startFrom (this, Clock::count(_delay), Clock::count(_period), fun_); }
512#else
513 template<typename T>
514 void startFrom ( const T& _delay, const T& _period, fun_t * _proc ) { tmr_startFrom (this, Clock::count(_delay), Clock::count(_period), _proc); }
515#endif
516 void stop () { tmr_stop (this); }
517 int take () { return tmr_take (this); }
518 int expired () { return tmr_expired (this); }
519 int tryWait () { return tmr_tryWait (this); }
520 template<typename T>
521 int waitFor ( const T& _delay ) { return tmr_waitFor (this, Clock::count(_delay)); }
522 template<typename T>
523 int waitNext ( const T& _delay ) { return tmr_waitNext (this, Clock::count(_delay)); }
524 template<typename T>
525 int waitUntil ( const T& _time ) { return tmr_waitUntil (this, Clock::until(_time)); }
526 int wait () { return tmr_wait (this); }
527 explicit
528 operator bool () const { return __tmr::hdr.id != ID_STOPPED; }
529
530 template<class T = baseTimer> static
531 T * current () { return static_cast<T *>(tmr_this()); }
532
533#if __cplusplus >= 201402L
534 static
535 void fun_ ()
536 {
537 auto tmr = current();
538 Fun_t run;
539 run.swap(tmr->fun); // the running function must live until the callback returns,
540 run(); // the callback can replace it (flip, startFrom)
541 if (!tmr->fun)
542 tmr->fun.swap(run);
543 }
544 Fun_t fun;
545#endif
546
550
551 struct Current
552 {
553#if __cplusplus >= 201402L
554 static
555 void flip ( std::nullptr_t ) { tmr_flip (nullptr); }
556 template<class F> static
557 void flip ( F&& _proc ) { current()->fun = Fun_t(_proc);
558 tmr_flip (fun_); }
559 template<typename F, typename... A> static
560 void flip ( F&& _proc, A&&... _args ) { flip(std::bind(std::forward<F>(_proc), std::forward<A>(_args)...)); }
561#else
562 static
563 void flip ( fun_t * _proc ) { tmr_flip (_proc); }
564#endif
565 template<typename T> static
566 void delay( const T& _delay ) { tmr_delay(Clock::count(_delay)); }
567 };
568};
569
570using thisTimer = baseTimer::Current;
571using this_timer = baseTimer::Current;
572
581struct Timer : public baseTimer
582{
584 Timer(): baseTimer{} {}
586 template<class F>
587 Timer( F&& _proc ): baseTimer{_proc} {}
588#if __cplusplus >= 201402L
590 Timer( std::nullptr_t ): baseTimer{} {}
592 template<typename F, typename... A>
593 Timer( F&& _proc, A&&... _args ): baseTimer{std::bind(std::forward<F>(_proc), std::forward<A>(_args)...)} {}
594#endif
595
596 ~Timer() { assert(__tmr::hdr.id == ID_STOPPED); }
597
598 /// move constructor
599 Timer( Timer&& _src ): baseTimer(static_cast<baseTimer&&>(_src))
600 {
601 assert(_src.hdr.id == ID_STOPPED && _src.obj.queue == nullptr);
602 }
603
604 Timer( const Timer& ) = delete;
605 Timer& operator=( Timer&& ) = delete;
606 Timer& operator=( const Timer& ) = delete;
607
608private:
609 struct Starter {}; // Start* functions return the timer started in place: a started timer must not be moved
610 template<class S, typename... A>
611 Timer( Starter, S&& _start, A&&... _args ): Timer{static_cast<A&&>(_args)...} { _start(*this); }
612public:
613
624
625 static
626 Timer Make()
627 {
628 return {};
629 }
630
632 template<class F> static
633 Timer Make( F&& _proc )
634 {
635 return { _proc };
636 }
637
638#if __cplusplus >= 201402L
640 static
641 Timer Make( std::nullptr_t )
642 {
643 return Make();
644 }
645
647 template<typename F, typename... A> static
648 Timer Make( F&& _proc, A&&... _args )
649 {
650 return Make(std::bind(std::forward<F>(_proc), std::forward<A>(_args)...));
651 }
652#endif
653
675
676 template<typename T> static
677 Timer Start( const T& _delay, const T& _period )
678 {
679 return { Starter{}, [&]( Timer& _tmr ){ _tmr.start(_delay, _period); } };
680 }
681
683 template<typename T, class F> static
684 Timer Start( const T& _delay, const T& _period, F&& _proc )
685 {
686 return { Starter{}, [&]( Timer& _tmr ){ _tmr.start(_delay, _period); }, _proc };
687 }
688
689#if __cplusplus >= 201402L
691 template<typename T> static
692 Timer Start( const T& _delay, const T& _period, std::nullptr_t )
693 {
694 return Start(_delay, _period);
695 }
696
698 template<typename T, typename F, typename... A> static
699 Timer Start( const T& _delay, const T& _period, F&& _proc, A&&... _args )
700 {
701 return Start(_delay, _period, std::bind(std::forward<F>(_proc), std::forward<A>(_args)...));
702 }
703#endif
704
721
722 template<typename T> static
723 Timer StartFor( const T& _delay )
724 {
725 return { Starter{}, [&]( Timer& _tmr ){ _tmr.startFor(_delay); } };
726 }
727
729 template<typename T, class F> static
730 Timer StartFor( const T& _delay, F&& _proc )
731 {
732 return { Starter{}, [&]( Timer& _tmr ){ _tmr.startFor(_delay); }, _proc };
733 }
734
735#if __cplusplus >= 201402L
737 template<typename T> static
738 Timer StartFor( const T& _delay, std::nullptr_t )
739 {
740 return StartFor(_delay);
741 }
742
744 template<typename T, typename F, typename... A> static
745 Timer StartFor( const T& _delay, F&& _proc, A&&... _args )
746 {
747 return StartFor(_delay, std::bind(std::forward<F>(_proc), std::forward<A>(_args)...));
748 }
749#endif
750
769
770 template<typename T> static
771 Timer StartPeriodic( const T& _period )
772 {
773 return { Starter{}, [&]( Timer& _tmr ){ _tmr.startPeriodic(_period); } };
774 }
775
777 template<typename T, class F> static
778 Timer StartPeriodic( const T& _period, F&& _proc )
779 {
780 return { Starter{}, [&]( Timer& _tmr ){ _tmr.startPeriodic(_period); }, _proc };
781 }
782
783#if __cplusplus >= 201402L
785 template<typename T> static
786 Timer StartPeriodic( const T& _period, std::nullptr_t )
787 {
788 return StartPeriodic(_period);
789 }
790
792 template<typename T, typename F, typename... A> static
793 Timer StartPeriodic( const T& _period, F&& _proc, A&&... _args )
794 {
795 return StartPeriodic(_period, std::bind(std::forward<F>(_proc), std::forward<A>(_args)...));
796 }
797#endif
798
813
814 template<typename T> static
815 Timer StartUntil( const T& _time )
816 {
817 return { Starter{}, [&]( Timer& _tmr ){ _tmr.startUntil(_time); } };
818 }
819
821 template<typename T, class F> static
822 Timer StartUntil( const T& _time, F&& _proc )
823 {
824 return { Starter{}, [&]( Timer& _tmr ){ _tmr.startUntil(_time); }, _proc };
825 }
826
827#if __cplusplus >= 201402L
829 template<typename T> static
830 Timer StartUntil( const T& _time, std::nullptr_t )
831 {
832 return StartUntil(_time);
833 }
834
836 template<typename T, typename F, typename... A> static
837 Timer StartUntil( const T& _time, F&& _proc, A&&... _args )
838 {
839 return StartUntil(_time, std::bind(std::forward<F>(_proc), std::forward<A>(_args)...));
840 }
841#endif
842};
843
844} // namespace
845#endif//__cplusplus
846
847/* -------------------------------------------------------------------------- */
848
850
851#endif//__INTROS_TMR_H
#define INFINITE
infinite waiting
Definition osbase.h:250
void fun_t(void)
timer/task procedure
Definition osbase.h:142
int tmr_wait(tmr_t *tmr)
wait indefinitely until the timer finishes countdown
Definition ostimer.h:433
void tmr_startPeriodic(tmr_t *tmr, cnt_t period)
start/restart periodic timer for given duration of time
Definition ostimer.h:295
void tmr_reset(tmr_t *tmr)
reset the timer object and wake up all waiting tasks with 'E_STOPPED' event value
void tmr_stop(tmr_t *tmr)
stop timer
Definition ostimer.h:348
int tmr_tryWait(tmr_t *tmr)
alias of tmr_take()
Definition ostimer.h:368
int tmr_waitUntil(tmr_t *tmr, cnt_t time)
wait until given timepoint until the timer finishes countdown
void tmr_startUntil(tmr_t *tmr, cnt_t time)
start/restart one-shot timer until given timepoint
void tmr_init(tmr_t *tmr, fun_t *proc)
initialize a timer object
tmr_t * tmr_this(void)
return current timer object
Definition ostimer.h:223
int tmr_take(tmr_t *tmr)
check if the timer finishes countdown
void tmr_delay(cnt_t delay)
change delay time for current timer
Definition ostimer.h:458
void tmr_kill(tmr_t *tmr)
alias of tmr_reset()
Definition ostimer.h:247
void tmr_startNext(tmr_t *tmr, cnt_t delay)
restart the timer for given duration of time from the end of the previous countdown
void tmr_flip(fun_t *proc)
change callback procedure for current periodic timer (available in next period)
Definition ostimer.h:445
int tmr_waitFor(tmr_t *tmr, cnt_t delay)
wait for given duration of time until the timer finishes countdown
int tmr_expired(tmr_t *tmr)
alias of tmr_take()
Definition ostimer.h:364
void tmr_startFor(tmr_t *tmr, cnt_t delay)
start/restart one-shot timer for given duration of time
Definition ostimer.h:279
void tmr_start(tmr_t *tmr, cnt_t delay, cnt_t period)
start/restart periodic timer for given duration of time
void tmr_startFrom(tmr_t *tmr, cnt_t delay, cnt_t period, fun_t *proc)
start/restart periodic timer for given duration of time
int tmr_waitNext(tmr_t *tmr, cnt_t delay)
wait for given duration of time from the end of the previous countdown
static constexpr rep until(const std::chrono::time_point< Clock, _Duration > &_time)
time point in ticks, rounded up to whole ticks (only a time point of this clock)
Definition osclock.h:109
static constexpr rep count(const std::chrono::duration< _Rep, _Period > &_delay)
delay in ticks, rounded up to whole ticks; negative delay: IMMEDIATE, delay out of range: INFINITE
Definition osclock.h:102
create and initialize a timer object
Definition ostimer.h:581
Timer()
constructor, see the constructor parameters of the class
Definition ostimer.h:583
static Timer StartFor(const T &_delay)
create and initialize static timer object and start one-shot timer for given duration of time
Definition ostimer.h:722
static Timer Start(const T &_delay, const T &_period)
create and initialize static timer object and start periodic timer for given duration of time
Definition ostimer.h:676
static Timer StartUntil(const T &_time)
create and initialize static timer object and start one-shot timer until given timepoint
Definition ostimer.h:814
static Timer StartPeriodic(const T &_period)
create and initialize static timer object and start periodic timer for given duration of time
Definition ostimer.h:770
static Timer Make()
create and initialize static timer object
Definition ostimer.h:625