mirror of
https://github.com/apache/nuttx.git
synced 2026-05-28 20:08:15 +08:00
sched/wdog: improve accuracy of wd_gettime() in tickless mode
This commit is contained in:
@@ -129,19 +129,6 @@ static void sched_timer_start(unsigned int ticks);
|
|||||||
* Private Data
|
* Private Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/* This is the duration of the currently active timer or, when
|
|
||||||
* sched_timer_expiration() is called, the duration of interval timer
|
|
||||||
* that just expired. The value zero means that no timer was active.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static unsigned int g_timer_interval;
|
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_SPORADIC
|
|
||||||
/* This is the time of the last scheduler assessment */
|
|
||||||
|
|
||||||
static struct timespec g_sched_time;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_TICKLESS_ALARM
|
#ifdef CONFIG_SCHED_TICKLESS_ALARM
|
||||||
/* This is the time that the timer was stopped. All future times are
|
/* This is the time that the timer was stopped. All future times are
|
||||||
* calculated against this time. It must be valid at all times when
|
* calculated against this time. It must be valid at all times when
|
||||||
@@ -149,6 +136,19 @@ static struct timespec g_sched_time;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static struct timespec g_stop_time;
|
static struct timespec g_stop_time;
|
||||||
|
#else
|
||||||
|
/* This is the duration of the currently active timer or, when
|
||||||
|
* sched_timer_expiration() is called, the duration of interval timer
|
||||||
|
* that just expired. The value zero means that no timer was active.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static unsigned int g_timer_interval;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_SCHED_SPORADIC
|
||||||
|
/* This is the time of the last scheduler assessment */
|
||||||
|
|
||||||
|
static struct timespec g_sched_time;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -183,8 +183,8 @@ static struct timespec g_stop_time;
|
|||||||
#if CONFIG_RR_INTERVAL > 0 || defined(CONFIG_SCHED_SPORADIC)
|
#if CONFIG_RR_INTERVAL > 0 || defined(CONFIG_SCHED_SPORADIC)
|
||||||
static uint32_t sched_cpu_scheduler(int cpu, uint32_t ticks, bool noswitches)
|
static uint32_t sched_cpu_scheduler(int cpu, uint32_t ticks, bool noswitches)
|
||||||
{
|
{
|
||||||
FAR struct tcb_s *rtcb = current_task(cpu);
|
FAR struct tcb_s *rtcb = current_task(cpu);
|
||||||
FAR struct tcb_s *ntcb = current_task(cpu);
|
FAR struct tcb_s *ntcb = current_task(cpu);
|
||||||
uint32_t ret = 0;
|
uint32_t ret = 0;
|
||||||
|
|
||||||
#if CONFIG_RR_INTERVAL > 0
|
#if CONFIG_RR_INTERVAL > 0
|
||||||
@@ -343,7 +343,7 @@ static uint32_t sched_process_scheduler(uint32_t ticks, bool noswitches)
|
|||||||
static unsigned int sched_timer_process(unsigned int ticks, bool noswitches)
|
static unsigned int sched_timer_process(unsigned int ticks, bool noswitches)
|
||||||
{
|
{
|
||||||
unsigned int cmptime = UINT_MAX;
|
unsigned int cmptime = UINT_MAX;
|
||||||
unsigned int rettime = 0;
|
unsigned int rettime = 0;
|
||||||
unsigned int tmp;
|
unsigned int tmp;
|
||||||
|
|
||||||
#ifdef CONFIG_CLOCK_TIMEKEEPING
|
#ifdef CONFIG_CLOCK_TIMEKEEPING
|
||||||
@@ -368,7 +368,7 @@ static unsigned int sched_timer_process(unsigned int ticks, bool noswitches)
|
|||||||
tmp = sched_process_scheduler(ticks, noswitches);
|
tmp = sched_process_scheduler(ticks, noswitches);
|
||||||
if (tmp > 0 && tmp < cmptime)
|
if (tmp > 0 && tmp < cmptime)
|
||||||
{
|
{
|
||||||
rettime = tmp;
|
rettime = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rettime;
|
return rettime;
|
||||||
@@ -394,15 +394,12 @@ static void sched_timer_start(unsigned int ticks)
|
|||||||
uint64_t usecs;
|
uint64_t usecs;
|
||||||
uint64_t secs;
|
uint64_t secs;
|
||||||
#else
|
#else
|
||||||
uint64_t usecs;
|
uint32_t usecs;
|
||||||
uint64_t secs;
|
uint32_t secs;
|
||||||
#endif
|
#endif
|
||||||
uint32_t nsecs;
|
uint32_t nsecs;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Set up the next timer interval (or not) */
|
|
||||||
|
|
||||||
g_timer_interval = 0;
|
|
||||||
if (ticks > 0)
|
if (ticks > 0)
|
||||||
{
|
{
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
@@ -414,10 +411,6 @@ static void sched_timer_start(unsigned int ticks)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Save new timer interval */
|
|
||||||
|
|
||||||
g_timer_interval = ticks;
|
|
||||||
|
|
||||||
/* Convert ticks to a struct timespec that up_timer_start() can
|
/* Convert ticks to a struct timespec that up_timer_start() can
|
||||||
* understand.
|
* understand.
|
||||||
*
|
*
|
||||||
@@ -445,6 +438,10 @@ static void sched_timer_start(unsigned int ticks)
|
|||||||
ret = up_alarm_start(&ts);
|
ret = up_alarm_start(&ts);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
/* Save new timer interval */
|
||||||
|
|
||||||
|
g_timer_interval = ticks;
|
||||||
|
|
||||||
/* [Re-]start the interval timer */
|
/* [Re-]start the interval timer */
|
||||||
|
|
||||||
ret = up_timer_start(&ts);
|
ret = up_timer_start(&ts);
|
||||||
@@ -487,9 +484,17 @@ void sched_alarm_expiration(FAR const struct timespec *ts)
|
|||||||
{
|
{
|
||||||
unsigned int elapsed;
|
unsigned int elapsed;
|
||||||
unsigned int nexttime;
|
unsigned int nexttime;
|
||||||
|
struct timespec delta;
|
||||||
|
|
||||||
DEBUGASSERT(ts);
|
DEBUGASSERT(ts);
|
||||||
|
|
||||||
|
/* Calculate elapsed */
|
||||||
|
|
||||||
|
clock_timespec_subtract(ts, &g_stop_time, &delta);
|
||||||
|
|
||||||
|
elapsed = SEC2TICK(delta.tv_sec);
|
||||||
|
elapsed += delta.tv_nsec / NSEC_PER_TICK;
|
||||||
|
|
||||||
/* Save the time that the alarm occurred */
|
/* Save the time that the alarm occurred */
|
||||||
|
|
||||||
g_stop_time.tv_sec = ts->tv_sec;
|
g_stop_time.tv_sec = ts->tv_sec;
|
||||||
@@ -502,10 +507,14 @@ void sched_alarm_expiration(FAR const struct timespec *ts)
|
|||||||
g_sched_time.tv_nsec = ts->tv_nsec;
|
g_sched_time.tv_nsec = ts->tv_nsec;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Get the interval associated with last expiration */
|
/* Correct g_stop_time cause of the elapsed have remainder */
|
||||||
|
|
||||||
elapsed = g_timer_interval;
|
g_stop_time.tv_nsec -= delta.tv_nsec % NSEC_PER_TICK;
|
||||||
g_timer_interval = 0;
|
if (g_stop_time.tv_nsec < 0)
|
||||||
|
{
|
||||||
|
g_stop_time.tv_nsec += NSEC_PER_SEC;
|
||||||
|
g_stop_time.tv_sec--;
|
||||||
|
}
|
||||||
|
|
||||||
/* Process the timer ticks and set up the next interval (or not) */
|
/* Process the timer ticks and set up the next interval (or not) */
|
||||||
|
|
||||||
@@ -589,9 +598,8 @@ unsigned int sched_timer_cancel(void)
|
|||||||
* current time.
|
* current time.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ts.tv_sec = g_stop_time.tv_sec;
|
ts.tv_sec = g_stop_time.tv_sec;
|
||||||
ts.tv_nsec = g_stop_time.tv_nsec;
|
ts.tv_nsec = g_stop_time.tv_nsec;
|
||||||
g_timer_interval = 0;
|
|
||||||
|
|
||||||
(void)up_alarm_cancel(&g_stop_time);
|
(void)up_alarm_cancel(&g_stop_time);
|
||||||
|
|
||||||
@@ -609,7 +617,16 @@ unsigned int sched_timer_cancel(void)
|
|||||||
/* Convert to ticks */
|
/* Convert to ticks */
|
||||||
|
|
||||||
elapsed = SEC2TICK(ts.tv_sec);
|
elapsed = SEC2TICK(ts.tv_sec);
|
||||||
elapsed += NSEC2TICK(ts.tv_nsec);
|
elapsed += ts.tv_nsec / NSEC_PER_TICK;
|
||||||
|
|
||||||
|
/* Correct g_stop_time cause of the elapsed have remainder */
|
||||||
|
|
||||||
|
g_stop_time.tv_nsec -= ts.tv_nsec % NSEC_PER_TICK;
|
||||||
|
if (g_stop_time.tv_nsec < 0)
|
||||||
|
{
|
||||||
|
g_stop_time.tv_nsec += NSEC_PER_SEC;
|
||||||
|
g_stop_time.tv_sec--;
|
||||||
|
}
|
||||||
|
|
||||||
/* Process the timer ticks and return the next interval */
|
/* Process the timer ticks and return the next interval */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user