clock: Add clock_delay2abstick.
This commit added a macro function clock_delay2abstick to calculate the absolute tick after the delay. Signed-off-by: ouyangxiangzhen <ouyangxiangzhen@xiaomi.com>
This commit is contained in:
parent
2e8583f759
commit
64a7049dec
6 changed files with 28 additions and 49 deletions
|
|
@ -384,6 +384,28 @@ EXTERN volatile clock_t g_system_ticks;
|
|||
#define clock_time2nsec(ts) \
|
||||
((uint64_t)(ts)->tv_sec * NSEC_PER_SEC + (uint64_t)(ts)->tv_nsec)
|
||||
|
||||
/* Calculate delay+1, forcing the delay into a range that we can handle.
|
||||
*
|
||||
* NOTE that one is added to the delay. This is correct and must not be
|
||||
* changed: The contract for the use wdog_start is that the wdog will
|
||||
* delay FOR AT LEAST as long as requested, but may delay longer due to
|
||||
* variety of factors. The wdog logic has no knowledge of the the phase
|
||||
* of the system timer when it is started: The next timer interrupt may
|
||||
* occur immediately or may be delayed for almost a full cycle. In order
|
||||
* to meet the contract requirement, the requested time is also always
|
||||
* incremented by one so that the delay is always at least as long as
|
||||
* requested.
|
||||
*
|
||||
* E.g. delay+1 can prevent the insufficient sleep time if we are
|
||||
* currently near the boundary to the next tick.
|
||||
* | current_tick | current_tick + 1 | current_tick + 2 | .... |
|
||||
* | ^ Here we get the current tick
|
||||
* In this case we delay 1 tick, timer will be triggered at
|
||||
* current_tick + 1, which is not enough for at least 1 tick.
|
||||
*/
|
||||
|
||||
#define clock_delay2abstick(delay) (clock_systime_ticks() + (delay) + 1)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: clock_timespec_add
|
||||
*
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ out:
|
|||
|
||||
int nxsem_tickwait_uninterruptible(FAR sem_t *sem, uint32_t delay)
|
||||
{
|
||||
clock_t end = clock_systime_ticks() + delay + 1;
|
||||
clock_t end = clock_delay2abstick(delay);
|
||||
int ret;
|
||||
|
||||
for (; ; )
|
||||
|
|
|
|||
|
|
@ -304,15 +304,7 @@ int nxsig_clockwait(int clockid, int flags,
|
|||
|
||||
if ((flags & TIMER_ABSTIME) == 0)
|
||||
{
|
||||
/* delay+1 is to prevent the insufficient sleep time if we are
|
||||
* currently near the boundary to the next tick.
|
||||
* | current_tick | current_tick + 1 | current_tick + 2 | .... |
|
||||
* | ^ Here we get the current tick
|
||||
* In this case we delay 1 tick, timer will be triggered at
|
||||
* current_tick + 1, which is not enough for at least 1 tick.
|
||||
*/
|
||||
|
||||
expect = clock_systime_ticks() + clock_time2ticks(rqtp) + 1;
|
||||
expect = clock_delay2abstick(clock_time2ticks(rqtp));
|
||||
wd_start_abstick(&rtcb->waitdog, expect,
|
||||
nxsig_timeout, (uintptr_t)rtcb);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -316,9 +316,7 @@ int timer_settime(timer_t timerid, int flags,
|
|||
{
|
||||
/* Calculate a delay corresponding to the absolute time in 'value' */
|
||||
|
||||
clock_abstime2ticks(timer->pt_clock, &value->it_value,
|
||||
&timer->pt_expected);
|
||||
timer->pt_expected += clock_systime_ticks();
|
||||
clock_abstime2ticks(timer->pt_clock, &value->it_value, &delay);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -328,18 +326,9 @@ int timer_settime(timer_t timerid, int flags,
|
|||
*/
|
||||
|
||||
delay = clock_time2ticks(&value->it_value);
|
||||
timer->pt_expected = clock_systime_ticks() + delay;
|
||||
}
|
||||
|
||||
/* This is to prevent the insufficient sleep time if we are
|
||||
* currently near the boundary to the next tick.
|
||||
* | current_tick | current_tick + 1 | current_tick + 2 | .... |
|
||||
* | ^ Here we get the current tick
|
||||
* In this case we delay 1 tick, timer will be triggered at
|
||||
* current_tick + 1, which is not enough for at least 1 tick.
|
||||
*/
|
||||
|
||||
timer->pt_expected += 1;
|
||||
timer->pt_expected = clock_delay2abstick(delay);
|
||||
|
||||
/* Then start the watchdog */
|
||||
|
||||
|
|
|
|||
|
|
@ -416,23 +416,7 @@ int wd_start(FAR struct wdog_s *wdog, sclock_t delay,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Calculate delay+1, forcing the delay into a range that we can handle.
|
||||
*
|
||||
* NOTE that one is added to the delay. This is correct and must not be
|
||||
* changed: The contract for the use wdog_start is that the wdog will
|
||||
* delay FOR AT LEAST as long as requested, but may delay longer due to
|
||||
* variety of factors. The wdog logic has no knowledge of the the phase
|
||||
* of the system timer when it is started: The next timer interrupt may
|
||||
* occur immediately or may be delayed for almost a full cycle. In order
|
||||
* to meet the contract requirement, the requested time is also always
|
||||
* incremented by one so that the delay is always at least as long as
|
||||
* requested.
|
||||
*
|
||||
* There is extensive documentation about this time issue elsewhere.
|
||||
*/
|
||||
|
||||
return wd_start_abstick(wdog, clock_systime_ticks() + delay + 1,
|
||||
wdentry, arg);
|
||||
return wd_start_abstick(wdog, clock_delay2abstick(delay), wdentry, arg);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
|||
|
|
@ -88,15 +88,7 @@ int work_queue_period_wq(FAR struct kwork_wqueue_s *wqueue,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* delay+1 is to prevent the insufficient sleep time if we are
|
||||
* currently near the boundary to the next tick.
|
||||
* | current_tick | current_tick + 1 | current_tick + 2 | .... |
|
||||
* | ^ Here we get the current tick
|
||||
* In this case we delay 1 tick, timer will be triggered at
|
||||
* current_tick + 1, which is not enough for at least 1 tick.
|
||||
*/
|
||||
|
||||
expected = clock_systime_ticks() + delay + 1;
|
||||
expected = clock_delay2abstick(delay);
|
||||
|
||||
/* Interrupts are disabled so that this logic can be called from with
|
||||
* task logic or from interrupt handling logic.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue