diff options
Diffstat (limited to 'nuttx/sched/sched/sched_timerexpiration.c')
-rw-r--r-- | nuttx/sched/sched/sched_timerexpiration.c | 158 |
1 files changed, 126 insertions, 32 deletions
diff --git a/nuttx/sched/sched/sched_timerexpiration.c b/nuttx/sched/sched/sched_timerexpiration.c index c721005d9..2bc737ecb 100644 --- a/nuttx/sched/sched/sched_timerexpiration.c +++ b/nuttx/sched/sched/sched_timerexpiration.c @@ -235,28 +235,28 @@ sched_process_timeslice(unsigned int ticks, bool noswitches) * noswitches - True: Can't do context switches now. * * Returned Value: - * Base code implementation assumes that this function is called from - * interrupt handling logic with interrupts disabled. + * The number of ticks to use when setting up the next timer. Zero if + * there is no interesting event to be timed. * ****************************************************************************/ -static void sched_timer_process(unsigned int ticks, bool noswitches) +static unsigned int sched_timer_process(unsigned int ticks, bool noswitches) { - unsigned int nextime = UINT_MAX; - bool needtimer = false; - uint32_t msecs; - uint32_t secs; - uint32_t nsecs; +#if CONFIG_RR_INTERVAL > 0 + unsigned int cmptime = UINT_MAX; +#endif + unsigned int rettime = 0; unsigned int tmp; - int ret; /* Process watchdogs */ tmp = wd_timer(ticks); if (tmp > 0) { - nextime = tmp; - needtimer = true; +#if CONFIG_RR_INTERVAL > 0 + cmptime = tmp; +#endif + rettime = tmp; } #if CONFIG_RR_INTERVAL > 0 @@ -265,29 +265,52 @@ static void sched_timer_process(unsigned int ticks, bool noswitches) */ tmp = sched_process_timeslice(ticks, noswitches); - if (tmp > 0 && tmp < nextime) + if (tmp > 0 && tmp < cmptime) { - nextime = tmp; - needtimer = true; + rettime = tmp; } #endif + return rettime; +} + +/**************************************************************************** + * Name: sched_timer_start + * + * Description: + * Start the interval timer. + * + * Input Parameters: + * ticks - The number of ticks defining the timer interval to setup. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sched_timer_start(unsigned int ticks) +{ + uint32_t msecs; + uint32_t secs; + uint32_t nsecs; + int ret; + /* Set up the next timer interval (or not) */ g_timer_interval = 0; - if (needtimer) + if (ticks > 0) { struct timespec ts; /* Save new timer interval */ - g_timer_interval = nextime; + g_timer_interval = ticks; /* Convert ticks to a struct timespec that up_timer_start() can * understand. */ - msecs = TICK2MSEC(nextime); + msecs = TICK2MSEC(ticks); secs = msecs / MSEC_PER_SEC; nsecs = (msecs - (secs * MSEC_PER_SEC)) * NSEC_PER_MSEC; @@ -328,37 +351,43 @@ static void sched_timer_process(unsigned int ticks, bool noswitches) void sched_timer_expiration(void) { unsigned int elapsed; + unsigned int nexttime; + + /* Get the interval associated with las expiration */ elapsed = g_timer_interval; g_timer_interval = 0; - sched_timer_process(elapsed, false); + + /* Process the timer ticks and set up the next interval (or not) */ + + nexttime = sched_timer_process(elapsed, false); + sched_timer_start(nexttime); } /**************************************************************************** - * Name: sched_timer_reassess + * Name: sched_timer_cancel * * Description: - * It is necessary to re-assess the timer interval in several - * circumstances: + * Stop the current timing activity. This is currently called just before + * a new entry is inserted at the head of a timer list and also as part + * of the processing of sched_timer_reassess(). * - * - If the watchdog at the head of the expiration list changes (or if its - * delay changes. This can occur as a consequence of the actions of - * wd_start() or wd_cancel(). - * - Any context switch occurs, changing the task at the head of the - * ready-to-run list. The task at the head of list may require - * different timeslice processing (or no timeslice at all). - * - When pre-emption is re-enabled. A previous time slice may have - * expired while pre-emption was enabled and now needs to be executed. + * This function(1) cancels the current timer, (2) determines how much of + * the interval has elapsed, (3) completes any partially timed events + * (including updating the delay of the timer at the head of the timer + * list), and (2) returns the number of ticks that would be needed to + * resume timing and complete this delay. * * Input Parameters: * None * * Returned Value: - * None + * Number of timer ticks that would be needed to complete the delay (zero + * if the timer was not active). * ****************************************************************************/ -void sched_timer_reassess(void) +unsigned int sched_timer_cancel(void) { struct timespec ts; unsigned int ticks; @@ -382,6 +411,71 @@ void sched_timer_reassess(void) elapsed = g_timer_interval - ticks; g_timer_interval = 0; - sched_timer_process(elapsed, true); + + /* Process the timer ticks and return the next interval */ + + return sched_timer_process(elapsed, true); +} + +/**************************************************************************** + * Name: sched_timer_resume + * + * Description: + * Re-assess the next deadline and restart the interval timer. This is + * called from wd_start() after it has inserted a new delay into the + * timer list. + * + * Input Parameters: + * None + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void sched_timer_resume(void) +{ + unsigned int nexttime; + + /* Reassess the next deadline (by simply processing a zero ticks expired) + * and set up the next interval (or not). + */ + + nexttime = sched_timer_process(0, true); + sched_timer_start(nexttime); +} + +/**************************************************************************** + * Name: sched_timer_reassess + * + * Description: + * It is necessary to re-assess the timer interval in several + * circumstances: + * + * - If the watchdog at the head of the expiration list changes (or if its + * delay changes. This can occur as a consequence of the actions of + * wd_start() or wd_cancel(). + * - Any context switch occurs, changing the task at the head of the + * ready-to-run list. The task at the head of list may require + * different timeslice processing (or no timeslice at all). + * - When pre-emption is re-enabled. A previous time slice may have + * expired while pre-emption was enabled and now needs to be executed. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sched_timer_reassess(void) +{ + unsigned int nexttime; + + /* Cancel and restart the timer */ + + nexttime = sched_timer_cancel(); + sched_timer_start(nexttime); } #endif /* CONFIG_SCHED_TICKLESS */ |