mirror of
https://github.com/apache/nuttx.git
synced 2026-05-27 03:05:40 +08:00
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:
committed by
Xiang Xiao
parent
2e8583f759
commit
64a7049dec
@@ -384,6 +384,28 @@ EXTERN volatile clock_t g_system_ticks;
|
|||||||
#define clock_time2nsec(ts) \
|
#define clock_time2nsec(ts) \
|
||||||
((uint64_t)(ts)->tv_sec * NSEC_PER_SEC + (uint64_t)(ts)->tv_nsec)
|
((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
|
* Name: clock_timespec_add
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ out:
|
|||||||
|
|
||||||
int nxsem_tickwait_uninterruptible(FAR sem_t *sem, uint32_t delay)
|
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;
|
int ret;
|
||||||
|
|
||||||
for (; ; )
|
for (; ; )
|
||||||
|
|||||||
@@ -304,15 +304,7 @@ int nxsig_clockwait(int clockid, int flags,
|
|||||||
|
|
||||||
if ((flags & TIMER_ABSTIME) == 0)
|
if ((flags & TIMER_ABSTIME) == 0)
|
||||||
{
|
{
|
||||||
/* delay+1 is to prevent the insufficient sleep time if we are
|
expect = clock_delay2abstick(clock_time2ticks(rqtp));
|
||||||
* 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;
|
|
||||||
wd_start_abstick(&rtcb->waitdog, expect,
|
wd_start_abstick(&rtcb->waitdog, expect,
|
||||||
nxsig_timeout, (uintptr_t)rtcb);
|
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' */
|
/* Calculate a delay corresponding to the absolute time in 'value' */
|
||||||
|
|
||||||
clock_abstime2ticks(timer->pt_clock, &value->it_value,
|
clock_abstime2ticks(timer->pt_clock, &value->it_value, &delay);
|
||||||
&timer->pt_expected);
|
|
||||||
timer->pt_expected += clock_systime_ticks();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -328,18 +326,9 @@ int timer_settime(timer_t timerid, int flags,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
delay = clock_time2ticks(&value->it_value);
|
delay = clock_time2ticks(&value->it_value);
|
||||||
timer->pt_expected = clock_systime_ticks() + delay;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is to prevent the insufficient sleep time if we are
|
timer->pt_expected = clock_delay2abstick(delay);
|
||||||
* 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;
|
|
||||||
|
|
||||||
/* Then start the watchdog */
|
/* Then start the watchdog */
|
||||||
|
|
||||||
|
|||||||
+1
-17
@@ -416,23 +416,7 @@ int wd_start(FAR struct wdog_s *wdog, sclock_t delay,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate delay+1, forcing the delay into a range that we can handle.
|
return wd_start_abstick(wdog, clock_delay2abstick(delay), wdentry, arg);
|
||||||
*
|
|
||||||
* 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|||||||
@@ -88,15 +88,7 @@ int work_queue_period_wq(FAR struct kwork_wqueue_s *wqueue,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* delay+1 is to prevent the insufficient sleep time if we are
|
expected = clock_delay2abstick(delay);
|
||||||
* 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;
|
|
||||||
|
|
||||||
/* Interrupts are disabled so that this logic can be called from with
|
/* Interrupts are disabled so that this logic can be called from with
|
||||||
* task logic or from interrupt handling logic.
|
* task logic or from interrupt handling logic.
|
||||||
|
|||||||
Reference in New Issue
Block a user