forked from nuttx/nuttx-update
sched: use tick count for sched timer expiration
This commit is contained in:
parent
7225e44725
commit
750007ded9
12 changed files with 206 additions and 165 deletions
|
@ -685,7 +685,7 @@ int up_timer_gettime(struct timespec *ts)
|
|||
#ifdef CONFIG_CLOCK_TIMEKEEPING
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_timer_getcounter
|
||||
* Name: up_timer_gettick
|
||||
*
|
||||
* Description:
|
||||
* To be provided
|
||||
|
@ -698,9 +698,9 @@ int up_timer_gettime(struct timespec *ts)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_timer_getcounter(uint64_t *cycles)
|
||||
int up_timer_gettick(clock_t *ticks)
|
||||
{
|
||||
*cycles = (uint64_t)STM32_TIM_GETCOUNTER(g_tickless.tch);
|
||||
*ticks = (clock_t)STM32_TIM_GETCOUNTER(g_tickless.tch);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -718,7 +718,7 @@ int up_timer_getcounter(uint64_t *cycles)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_timer_getmask(uint64_t *mask)
|
||||
void up_timer_getmask(clock_t *mask)
|
||||
{
|
||||
DEBUGASSERT(mask != NULL);
|
||||
#ifdef HAVE_32BIT_TICKLESS
|
||||
|
|
|
@ -743,7 +743,7 @@ int up_timer_gettime(struct timespec *ts)
|
|||
#ifdef CONFIG_CLOCK_TIMEKEEPING
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_timer_getcounter
|
||||
* Name: up_timer_gettick
|
||||
*
|
||||
* Description:
|
||||
* To be provided
|
||||
|
@ -756,9 +756,9 @@ int up_timer_gettime(struct timespec *ts)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_timer_getcounter(uint64_t *cycles)
|
||||
int up_timer_gettick(clock_t *ticks)
|
||||
{
|
||||
*cycles = (uint64_t)STM32_TIM_GETCOUNTER(g_tickless.tch);
|
||||
*ticks = (clock_t)STM32_TIM_GETCOUNTER(g_tickless.tch);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -776,7 +776,7 @@ int up_timer_getcounter(uint64_t *cycles)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_timer_getmask(uint64_t *mask)
|
||||
void up_timer_getmask(clock_t *mask)
|
||||
{
|
||||
DEBUGASSERT(mask != NULL);
|
||||
#ifdef HAVE_32BIT_TICKLESS
|
||||
|
|
|
@ -716,7 +716,7 @@ int up_timer_gettime(struct timespec *ts)
|
|||
#ifdef CONFIG_CLOCK_TIMEKEEPING
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_timer_getcounter
|
||||
* Name: up_timer_gettick
|
||||
*
|
||||
* Description:
|
||||
* To be provided
|
||||
|
@ -729,9 +729,9 @@ int up_timer_gettime(struct timespec *ts)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_timer_getcounter(uint64_t *cycles)
|
||||
int up_timer_gettick(clock_t *ticks)
|
||||
{
|
||||
*cycles = (uint64_t)STM32_TIM_GETCOUNTER(g_tickless.tch);
|
||||
*ticks = (clock_t)STM32_TIM_GETCOUNTER(g_tickless.tch);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -749,7 +749,7 @@ int up_timer_getcounter(uint64_t *cycles)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_timer_getmask(uint64_t *mask)
|
||||
void up_timer_getmask(clock_t *mask)
|
||||
{
|
||||
DEBUGASSERT(mask != NULL);
|
||||
#ifdef HAVE_32BIT_TICKLESS
|
||||
|
|
|
@ -559,7 +559,7 @@ int up_timer_gettime(struct timespec *ts)
|
|||
#ifdef CONFIG_CLOCK_TIMEKEEPING
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_timer_getcounter
|
||||
* Name: up_timer_gettick
|
||||
*
|
||||
* Description:
|
||||
* To be provided
|
||||
|
@ -572,9 +572,9 @@ int up_timer_gettime(struct timespec *ts)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_timer_getcounter(uint64_t *cycles)
|
||||
int up_timer_gettick(clock_t *ticks)
|
||||
{
|
||||
*cycles = (uint64_t)STM32WB_TIM_GETCOUNTER(g_tickless.tch);
|
||||
*ticks = (clock_t)STM32WB_TIM_GETCOUNTER(g_tickless.tch);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -592,7 +592,7 @@ int up_timer_getcounter(uint64_t *cycles)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_timer_getmask(uint64_t *mask)
|
||||
void up_timer_getmask(clock_t *mask)
|
||||
{
|
||||
DEBUGASSERT(mask != NULL);
|
||||
#ifdef HAVE_32BIT_TICKLESS
|
||||
|
|
|
@ -204,39 +204,21 @@ void up_alarm_set_lowerhalf(FAR struct oneshot_lowerhalf_s *lower)
|
|||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_CLOCK_TIMEKEEPING
|
||||
int weak_function up_timer_getcounter(FAR uint64_t *cycles)
|
||||
{
|
||||
int ret = -EAGAIN;
|
||||
|
||||
if (g_oneshot_lower != NULL)
|
||||
{
|
||||
struct timespec now;
|
||||
|
||||
ret = ONESHOT_CURRENT(g_oneshot_lower, &now);
|
||||
if (ret == 0)
|
||||
{
|
||||
*cycles = timespec_to_usec(&now) / USEC_PER_TICK;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void weak_function up_timer_getmask(FAR uint64_t *mask)
|
||||
void weak_function up_timer_getmask(FAR clock_t *mask)
|
||||
{
|
||||
*mask = 0;
|
||||
|
||||
if (g_oneshot_lower != NULL)
|
||||
{
|
||||
struct timespec maxts;
|
||||
uint64_t maxticks;
|
||||
clock_t maxticks;
|
||||
|
||||
ONESHOT_MAX_DELAY(g_oneshot_lower, &maxts);
|
||||
maxticks = timespec_to_usec(&maxts) / USEC_PER_TICK;
|
||||
|
||||
for (; ; )
|
||||
{
|
||||
uint64_t next = (*mask << 1) | 1;
|
||||
clock_t next = (*mask << 1) | 1;
|
||||
if (next > maxticks)
|
||||
{
|
||||
break;
|
||||
|
@ -248,7 +230,7 @@ void weak_function up_timer_getmask(FAR uint64_t *mask)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SCHED_TICKLESS)
|
||||
#if defined(CONFIG_SCHED_TICKLESS) && !defined(CONFIG_SCHED_TICKLESS_TICK_ARGUMENT)
|
||||
int weak_function up_timer_gettime(FAR struct timespec *ts)
|
||||
{
|
||||
int ret = -EAGAIN;
|
||||
|
@ -262,6 +244,26 @@ int weak_function up_timer_gettime(FAR struct timespec *ts)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SCHED_TICKLESS_TICK_ARGUMENT) || defined(CONFIG_CLOCK_TIMEKEEPING)
|
||||
int weak_function up_timer_gettick(FAR clock_t *ticks)
|
||||
{
|
||||
int ret = -EAGAIN;
|
||||
|
||||
if (g_oneshot_lower != NULL)
|
||||
{
|
||||
struct timespec now;
|
||||
|
||||
ret = ONESHOT_CURRENT(g_oneshot_lower, &now);
|
||||
if (ret == 0)
|
||||
{
|
||||
*ticks = timespec_to_usec(&now) / USEC_PER_TICK;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_alarm_cancel
|
||||
*
|
||||
|
|
|
@ -269,27 +269,14 @@ void up_timer_set_lowerhalf(FAR struct timer_lowerhalf_s *lower)
|
|||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_CLOCK_TIMEKEEPING
|
||||
int weak_function up_timer_getcounter(FAR uint64_t *cycles)
|
||||
{
|
||||
int ret = -EAGAIN;
|
||||
|
||||
if (g_timer.lower != NULL)
|
||||
{
|
||||
*cycles = current_usec() / USEC_PER_TICK;
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void weak_function up_timer_getmask(FAR uint64_t *mask)
|
||||
void weak_function up_timer_getmask(FAR clock_t *mask)
|
||||
{
|
||||
uint32_t maxticks = g_timer.maxtimeout / USEC_PER_TICK;
|
||||
|
||||
*mask = 0;
|
||||
while (1)
|
||||
{
|
||||
uint64_t next = (*mask << 1) | 1;
|
||||
clock_t next = (*mask << 1) | 1;
|
||||
if (next > maxticks)
|
||||
{
|
||||
break;
|
||||
|
@ -300,7 +287,7 @@ void weak_function up_timer_getmask(FAR uint64_t *mask)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SCHED_TICKLESS)
|
||||
#if defined(CONFIG_SCHED_TICKLESS) && !defined(CONFIG_SCHED_TICKLESS_TICK_ARGUMENT)
|
||||
int weak_function up_timer_gettime(FAR struct timespec *ts)
|
||||
{
|
||||
int ret = -EAGAIN;
|
||||
|
@ -308,7 +295,22 @@ int weak_function up_timer_gettime(FAR struct timespec *ts)
|
|||
if (g_timer.lower != NULL)
|
||||
{
|
||||
timespec_from_usec(ts, current_usec());
|
||||
ret = 0;
|
||||
ret = OK;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SCHED_TICKLESS_TICK_ARGUMENT) || defined(CONFIG_CLOCK_TIMEKEEPING)
|
||||
int weak_function up_timer_gettick(FAR clock_t *ticks)
|
||||
{
|
||||
int ret = -EAGAIN;
|
||||
|
||||
if (g_timer.lower != NULL)
|
||||
{
|
||||
*ticks = current_usec() / USEC_PER_TICK;
|
||||
ret = OK;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -359,7 +361,7 @@ int weak_function up_timer_cancel(FAR struct timespec *ts)
|
|||
if (g_timer.lower != NULL)
|
||||
{
|
||||
timespec_from_usec(ts, update_timeout(g_timer.maxtimeout));
|
||||
ret = 0;
|
||||
ret = OK;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -399,7 +401,7 @@ int weak_function up_timer_start(FAR const struct timespec *ts)
|
|||
if (g_timer.lower != NULL)
|
||||
{
|
||||
update_timeout(timespec_to_usec(ts));
|
||||
ret = 0;
|
||||
ret = OK;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -1646,13 +1646,16 @@ void up_timer_initialize(void);
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_SCHED_TICKLESS)
|
||||
#if defined(CONFIG_SCHED_TICKLESS) && !defined(CONFIG_SCHED_TICKLESS_TICK_ARGUMENT)
|
||||
int up_timer_gettime(FAR struct timespec *ts);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SCHED_TICKLESS_TICK_ARGUMENT) || defined(CONFIG_CLOCK_TIMEKEEPING)
|
||||
int up_timer_gettick(FAR clock_t *ticks);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CLOCK_TIMEKEEPING
|
||||
int up_timer_getcounter(FAR uint64_t *cycles);
|
||||
void up_timer_getmask(FAR uint64_t *mask);
|
||||
void up_timer_getmask(FAR clock_t *mask);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -1690,7 +1693,11 @@ void up_timer_getmask(FAR uint64_t *mask);
|
|||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_SCHED_TICKLESS) && defined(CONFIG_SCHED_TICKLESS_ALARM)
|
||||
# ifndef CONFIG_SCHED_TICKLESS_TICK_ARGUMENT
|
||||
int up_alarm_cancel(FAR struct timespec *ts);
|
||||
# else
|
||||
int up_alarm_tick_cancel(FAR clock_t *ticks);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -1719,7 +1726,11 @@ int up_alarm_cancel(FAR struct timespec *ts);
|
|||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_SCHED_TICKLESS) && defined(CONFIG_SCHED_TICKLESS_ALARM)
|
||||
# ifndef CONFIG_SCHED_TICKLESS_TICK_ARGUMENT
|
||||
int up_alarm_start(FAR const struct timespec *ts);
|
||||
# else
|
||||
int up_alarm_tick_start(clock_t ticks);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -1759,7 +1770,11 @@ int up_alarm_start(FAR const struct timespec *ts);
|
|||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_SCHED_TICKLESS) && !defined(CONFIG_SCHED_TICKLESS_ALARM)
|
||||
# ifndef CONFIG_SCHED_TICKLESS_TICK_ARGUMENT
|
||||
int up_timer_cancel(FAR struct timespec *ts);
|
||||
# else
|
||||
int up_timer_tick_cancel(FAR clock_t *ticks);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -1788,7 +1803,11 @@ int up_timer_cancel(FAR struct timespec *ts);
|
|||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_SCHED_TICKLESS) && !defined(CONFIG_SCHED_TICKLESS_ALARM)
|
||||
# ifndef CONFIG_SCHED_TICKLESS_TICK_ARGUMENT
|
||||
int up_timer_start(FAR const struct timespec *ts);
|
||||
# else
|
||||
int up_timer_tick_start(clock_t ticks);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -2251,6 +2270,7 @@ void nxsched_timer_expiration(void);
|
|||
|
||||
#if defined(CONFIG_SCHED_TICKLESS) && defined(CONFIG_SCHED_TICKLESS_ALARM)
|
||||
void nxsched_alarm_expiration(FAR const struct timespec *ts);
|
||||
void nxsched_alarm_tick_expiration(clock_t ticks);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -251,6 +251,19 @@ EXTERN volatile clock_t g_system_ticks;
|
|||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#define timespec_from_tick(ts, tick) \
|
||||
do \
|
||||
{ \
|
||||
clock_t _tick = (tick); \
|
||||
(ts)->tv_sec = _tick / TICK_PER_SEC; \
|
||||
_tick -= (clock_t)(ts)->tv_sec * TICK_PER_SEC; \
|
||||
(ts)->tv_nsec = _tick * NSEC_PER_TICK; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define timespec_to_tick(ts) \
|
||||
((clock_t)(ts)->tv_sec * TICK_PER_SEC + (ts)->tv_nsec / NSEC_PER_TICK)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: clock_timespec_compare
|
||||
*
|
||||
|
|
|
@ -60,6 +60,26 @@ config SCHED_TICKLESS
|
|||
|
||||
if SCHED_TICKLESS
|
||||
|
||||
config SCHED_TICKLESS_TICK_ARGUMENT
|
||||
bool "Scheduler use tick argument"
|
||||
default n
|
||||
---help---
|
||||
Enables use of tick argument in scheduler. If enabled, then the
|
||||
board-specific logic must provide the following functions:
|
||||
|
||||
int up_timer_gettick(FAR clock_t *ticks);
|
||||
|
||||
If SCHED_TICKLESS_ALARM is enabled, then these additional interfaces are
|
||||
expected:
|
||||
|
||||
int up_alarm_tick_cancel(FAR clock_t *ticks);
|
||||
int up_alarm_tick_start(clock_t ticks);
|
||||
|
||||
Otherwise, these additional interfaces are expected:
|
||||
|
||||
int up_timer_tick_cancel(FAR clock_t *ticks);
|
||||
int up_timer_tick_start(FAR clock_t ticks);
|
||||
|
||||
config SCHED_TICKLESS_ALARM
|
||||
bool "Tickless alarm"
|
||||
default n
|
||||
|
|
|
@ -114,7 +114,16 @@ int clock_systime_timespec(FAR struct timespec *ts)
|
|||
* code. Let the platform timer do the work.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SCHED_TICKLESS_TICK_ARGUMENT
|
||||
clock_t ticks;
|
||||
int ret;
|
||||
|
||||
ret = up_timer_gettick(&ticks);
|
||||
timespec_from_tick(ts, ticks);
|
||||
return ret;
|
||||
#else
|
||||
return up_timer_gettime(ts);
|
||||
#endif
|
||||
|
||||
#elif defined(CONFIG_HAVE_LONG_LONG) && (CONFIG_USEC_PER_TICK % 1000) != 0
|
||||
/* 64-bit microsecond calculations should improve our accuracy
|
||||
|
|
|
@ -72,7 +72,7 @@ static int clock_get_current_time(FAR struct timespec *ts,
|
|||
|
||||
flags = enter_critical_section();
|
||||
|
||||
ret = up_timer_getcounter(&counter);
|
||||
ret = up_timer_gettick(&counter);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_in_critical_section;
|
||||
|
@ -123,7 +123,7 @@ int clock_timekeeping_set_wall_time(FAR const struct timespec *ts)
|
|||
|
||||
flags = enter_critical_section();
|
||||
|
||||
ret = up_timer_getcounter(&counter);
|
||||
ret = up_timer_gettick(&counter);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_in_critical_section;
|
||||
|
@ -217,7 +217,7 @@ void clock_update_wall_time(void)
|
|||
|
||||
flags = enter_critical_section();
|
||||
|
||||
ret = up_timer_getcounter(&counter);
|
||||
ret = up_timer_gettick(&counter);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_in_critical_section;
|
||||
|
@ -289,7 +289,7 @@ void clock_inittimekeeping(FAR const struct timespec *tp)
|
|||
clock_basetime(&g_clock_wall_time);
|
||||
}
|
||||
|
||||
up_timer_getcounter(&g_clock_last_counter);
|
||||
up_timer_gettick(&g_clock_last_counter);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_CLOCK_TIMEKEEPING */
|
||||
|
|
|
@ -123,7 +123,7 @@ static void nxsched_timer_start(unsigned int ticks);
|
|||
* the timer is not running.
|
||||
*/
|
||||
|
||||
static struct timespec g_stop_time;
|
||||
static clock_t g_stop_time;
|
||||
#else
|
||||
/* This is the duration of the currently active timer or, when
|
||||
* nxsched_timer_expiration() is called, the duration of interval timer
|
||||
|
@ -136,13 +136,60 @@ 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;
|
||||
static clock_t g_sched_time;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_SCHED_TICKLESS_TICK_ARGUMENT) && !defined(CONFIG_CLOCK_TIMEKEEPING)
|
||||
int up_timer_gettick(FAR clock_t *ticks)
|
||||
{
|
||||
struct timespec ts;
|
||||
int ret;
|
||||
ret = up_timer_gettime(&ts);
|
||||
*ticks = timespec_to_tick(&ts);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SCHED_TICKLESS_TICK_ARGUMENT
|
||||
# ifdef CONFIG_SCHED_TICKLESS_ALARM
|
||||
int up_alarm_tick_start(clock_t ticks)
|
||||
{
|
||||
struct timespec ts;
|
||||
timespec_from_tick(&ts, ticks);
|
||||
return up_alarm_start(&ts);
|
||||
}
|
||||
|
||||
int up_alarm_tick_cancel(FAR clock_t *ticks)
|
||||
{
|
||||
struct timespec ts;
|
||||
int ret;
|
||||
ret = up_alarm_cancel(&ts);
|
||||
*ticks = timespec_to_tick(&ts);
|
||||
return ret;
|
||||
}
|
||||
# else
|
||||
int up_timer_tick_start(clock_t ticks)
|
||||
{
|
||||
struct timespec ts;
|
||||
timespec_from_tick(&ts, ticks);
|
||||
return up_timer_start(&ts);
|
||||
}
|
||||
|
||||
int up_timer_tick_cancel(FAR clock_t *ticks)
|
||||
{
|
||||
struct timespec ts;
|
||||
int ret;
|
||||
ret = up_timer_cancel(&ts);
|
||||
*ticks = timespec_to_tick(&ts);
|
||||
return ret;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxsched_cpu_scheduler
|
||||
*
|
||||
|
@ -205,8 +252,7 @@ static uint32_t nxsched_cpu_scheduler(int cpu, uint32_t ticks,
|
|||
* committed to updating the scheduler for this TCB.
|
||||
*/
|
||||
|
||||
sporadic->eventtime = SEC2TICK(g_sched_time.tv_sec) +
|
||||
NSEC2TICK(g_sched_time.tv_nsec);
|
||||
sporadic->eventtime = g_sched_time;
|
||||
|
||||
/* Yes, check if the currently executing task has exceeded its
|
||||
* budget.
|
||||
|
@ -430,20 +476,10 @@ static unsigned int nxsched_timer_process(unsigned int ticks,
|
|||
|
||||
static void nxsched_timer_start(unsigned int ticks)
|
||||
{
|
||||
#ifdef CONFIG_HAVE_LONG_LONG
|
||||
uint64_t usecs;
|
||||
uint64_t secs;
|
||||
#else
|
||||
uint32_t usecs;
|
||||
uint32_t secs;
|
||||
#endif
|
||||
uint32_t nsecs;
|
||||
int ret;
|
||||
|
||||
if (ticks > 0)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
#ifdef CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP
|
||||
if (ticks > g_oneshot_maxticks)
|
||||
{
|
||||
|
@ -451,32 +487,12 @@ static void nxsched_timer_start(unsigned int ticks)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Convert ticks to a struct timespec that up_timer_start() can
|
||||
* understand.
|
||||
*
|
||||
* REVISIT: Calculations may not have an acceptable range if uint64_t
|
||||
* is not supported(?)
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_HAVE_LONG_LONG
|
||||
usecs = TICK2USEC((uint64_t)ticks);
|
||||
#else
|
||||
usecs = TICK2USEC(ticks);
|
||||
#endif
|
||||
secs = usecs / USEC_PER_SEC;
|
||||
nsecs = (usecs - (secs * USEC_PER_SEC)) * NSEC_PER_USEC;
|
||||
|
||||
ts.tv_sec = (time_t)secs;
|
||||
ts.tv_nsec = (long)nsecs;
|
||||
|
||||
#ifdef CONFIG_SCHED_TICKLESS_ALARM
|
||||
/* Convert the delay to a time in the future (with respect
|
||||
* to the time when last stopped the timer).
|
||||
*/
|
||||
|
||||
clock_timespec_add(&g_stop_time, &ts, &ts);
|
||||
ret = up_alarm_start(&ts);
|
||||
|
||||
ret = up_alarm_tick_start(g_stop_time + ticks);
|
||||
#else
|
||||
/* Save new timer interval */
|
||||
|
||||
|
@ -484,7 +500,7 @@ static void nxsched_timer_start(unsigned int ticks)
|
|||
|
||||
/* [Re-]start the interval timer */
|
||||
|
||||
ret = up_timer_start(&ts);
|
||||
ret = up_timer_tick_start(ticks);
|
||||
#endif
|
||||
|
||||
if (ret < 0)
|
||||
|
@ -520,51 +536,40 @@ static void nxsched_timer_start(unsigned int ticks)
|
|||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SCHED_TICKLESS_ALARM
|
||||
void nxsched_alarm_expiration(FAR const struct timespec *ts)
|
||||
void nxsched_alarm_tick_expiration(clock_t ticks)
|
||||
{
|
||||
unsigned int elapsed;
|
||||
unsigned int nexttime;
|
||||
struct timespec delta;
|
||||
|
||||
DEBUGASSERT(ts);
|
||||
|
||||
/* Calculate elapsed */
|
||||
|
||||
clock_timespec_subtract(ts, &g_stop_time, &delta);
|
||||
|
||||
#ifdef CONFIG_HAVE_LONG_LONG
|
||||
elapsed = SEC2TICK((uint64_t)delta.tv_sec);
|
||||
#else
|
||||
elapsed = SEC2TICK(delta.tv_sec);
|
||||
#endif
|
||||
elapsed += delta.tv_nsec / NSEC_PER_TICK;
|
||||
elapsed = ticks - g_stop_time;
|
||||
|
||||
/* Save the time that the alarm occurred */
|
||||
|
||||
g_stop_time.tv_sec = ts->tv_sec;
|
||||
g_stop_time.tv_nsec = ts->tv_nsec;
|
||||
g_stop_time = ticks;
|
||||
|
||||
#ifdef CONFIG_SCHED_SPORADIC
|
||||
/* Save the last time that the scheduler ran */
|
||||
|
||||
g_sched_time.tv_sec = ts->tv_sec;
|
||||
g_sched_time.tv_nsec = ts->tv_nsec;
|
||||
g_sched_time = ticks;
|
||||
#endif
|
||||
|
||||
/* Correct g_stop_time cause of the elapsed have remainder */
|
||||
|
||||
g_stop_time.tv_nsec -= delta.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 set up the next interval (or not) */
|
||||
|
||||
nexttime = nxsched_timer_process(elapsed, false);
|
||||
nxsched_timer_start(nexttime);
|
||||
}
|
||||
|
||||
void nxsched_alarm_expiration(FAR const struct timespec *ts)
|
||||
{
|
||||
clock_t ticks;
|
||||
|
||||
DEBUGASSERT(ts);
|
||||
|
||||
ticks = timespec_to_tick(ts);
|
||||
nxsched_alarm_tick_expiration(ticks);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -597,7 +602,7 @@ void nxsched_timer_expiration(void)
|
|||
#ifdef CONFIG_SCHED_SPORADIC
|
||||
/* Save the last time that the scheduler ran */
|
||||
|
||||
up_timer_gettime(&g_sched_time);
|
||||
up_timer_gettick(&g_sched_time);
|
||||
#endif
|
||||
|
||||
/* Process the timer ticks and set up the next interval (or not) */
|
||||
|
@ -633,7 +638,7 @@ void nxsched_timer_expiration(void)
|
|||
#ifdef CONFIG_SCHED_TICKLESS_ALARM
|
||||
unsigned int nxsched_cancel_timer(void)
|
||||
{
|
||||
struct timespec ts;
|
||||
clock_t ticks;
|
||||
unsigned int elapsed;
|
||||
|
||||
/* Cancel the alarm and and get the time that the alarm was cancelled.
|
||||
|
@ -642,39 +647,19 @@ unsigned int nxsched_cancel_timer(void)
|
|||
* current time.
|
||||
*/
|
||||
|
||||
ts.tv_sec = g_stop_time.tv_sec;
|
||||
ts.tv_nsec = g_stop_time.tv_nsec;
|
||||
ticks = g_stop_time;
|
||||
|
||||
up_alarm_cancel(&g_stop_time);
|
||||
up_alarm_tick_cancel(&g_stop_time);
|
||||
|
||||
#ifdef CONFIG_SCHED_SPORADIC
|
||||
/* Save the last time that the scheduler ran */
|
||||
|
||||
g_sched_time.tv_sec = g_stop_time.tv_sec;
|
||||
g_sched_time.tv_nsec = g_stop_time.tv_nsec;
|
||||
g_sched_time = g_stop_time;
|
||||
#endif
|
||||
|
||||
/* Convert this to the elapsed time */
|
||||
|
||||
clock_timespec_subtract(&g_stop_time, &ts, &ts);
|
||||
|
||||
/* Convert to ticks */
|
||||
|
||||
#ifdef CONFIG_HAVE_LONG_LONG
|
||||
elapsed = SEC2TICK((uint64_t)ts.tv_sec);
|
||||
#else
|
||||
elapsed = SEC2TICK(ts.tv_sec);
|
||||
#endif
|
||||
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--;
|
||||
}
|
||||
elapsed = g_stop_time - ticks;
|
||||
|
||||
/* Process the timer ticks and return the next interval */
|
||||
|
||||
|
@ -683,29 +668,19 @@ unsigned int nxsched_cancel_timer(void)
|
|||
#else
|
||||
unsigned int nxsched_cancel_timer(void)
|
||||
{
|
||||
struct timespec ts;
|
||||
unsigned int ticks;
|
||||
clock_t ticks;
|
||||
unsigned int elapsed;
|
||||
|
||||
/* Get the time remaining on the interval timer and cancel the timer. */
|
||||
|
||||
up_timer_cancel(&ts);
|
||||
up_timer_tick_cancel(&ticks);
|
||||
|
||||
#ifdef CONFIG_SCHED_SPORADIC
|
||||
/* Save the last time that the scheduler ran */
|
||||
|
||||
g_sched_time.tv_sec = ts.tv_sec;
|
||||
g_sched_time.tv_nsec = ts.tv_nsec;
|
||||
g_sched_time = ticks;
|
||||
#endif
|
||||
|
||||
/* Convert to ticks */
|
||||
|
||||
#ifdef CONFIG_HAVE_LONG_LONG
|
||||
ticks = SEC2TICK((uint64_t)ts.tv_sec);
|
||||
#else
|
||||
ticks = SEC2TICK(ts.tv_sec);
|
||||
#endif
|
||||
ticks += NSEC2TICK(ts.tv_nsec);
|
||||
DEBUGASSERT(ticks <= g_timer_interval);
|
||||
|
||||
/* Handle the partial timer. This will reassess all timer conditions and
|
||||
|
@ -751,7 +726,7 @@ void nxsched_resume_timer(void)
|
|||
#ifdef CONFIG_SCHED_SPORADIC
|
||||
/* Save the last time that the scheduler ran */
|
||||
|
||||
up_timer_gettime(&g_sched_time);
|
||||
up_timer_gettick(&g_sched_time);
|
||||
#endif
|
||||
|
||||
/* Reassess the next deadline (by simply processing a zero ticks expired)
|
||||
|
|
Loading…
Reference in a new issue