[components][drivers]improve ktimer sleep (#8838)

improve ktimer sleep
This commit is contained in:
zms123456 2024-04-22 11:55:20 +08:00 committed by GitHub
parent f13220d911
commit 5ca1e45020
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 38 additions and 19 deletions

View File

@ -139,13 +139,16 @@ rt_inline void rt_ktime_hrtimer_keep_errno(rt_ktime_hrtimer_t timer, rt_err_t er
rt_set_errno(-err); rt_set_errno(-err);
} }
void rt_ktime_hrtimer_delay_init(struct rt_ktime_hrtimer *timer);
void rt_ktime_hrtimer_delay_detach(struct rt_ktime_hrtimer *timer);
/** /**
* @brief sleep by the cputimer cnt value * @brief sleep by the cputimer cnt value
* *
* @param cnt: the cputimer cnt value * @param cnt: the cputimer cnt value
* @return rt_err_t * @return rt_err_t
*/ */
rt_err_t rt_ktime_hrtimer_sleep(unsigned long cnt); rt_err_t rt_ktime_hrtimer_sleep(struct rt_ktime_hrtimer *timer, unsigned long cnt);
/** /**
* @brief sleep by ns * @brief sleep by ns
@ -153,7 +156,7 @@ rt_err_t rt_ktime_hrtimer_sleep(unsigned long cnt);
* @param ns: ns * @param ns: ns
* @return rt_err_t * @return rt_err_t
*/ */
rt_err_t rt_ktime_hrtimer_ndelay(unsigned long ns); rt_err_t rt_ktime_hrtimer_ndelay(struct rt_ktime_hrtimer *timer, unsigned long ns);
/** /**
* @brief sleep by us * @brief sleep by us
@ -161,7 +164,7 @@ rt_err_t rt_ktime_hrtimer_ndelay(unsigned long ns);
* @param us: us * @param us: us
* @return rt_err_t * @return rt_err_t
*/ */
rt_err_t rt_ktime_hrtimer_udelay(unsigned long us); rt_err_t rt_ktime_hrtimer_udelay(struct rt_ktime_hrtimer *timer, unsigned long us);
/** /**
* @brief sleep by ms * @brief sleep by ms
@ -169,6 +172,6 @@ rt_err_t rt_ktime_hrtimer_udelay(unsigned long us);
* @param ms: ms * @param ms: ms
* @return rt_err_t * @return rt_err_t
*/ */
rt_err_t rt_ktime_hrtimer_mdelay(unsigned long ms); rt_err_t rt_ktime_hrtimer_mdelay(struct rt_ktime_hrtimer *timer, unsigned long ms);
#endif #endif

View File

@ -356,37 +356,46 @@ rt_err_t rt_ktime_hrtimer_detach(rt_ktime_hrtimer_t timer)
/************************** delay ***************************/ /************************** delay ***************************/
rt_err_t rt_ktime_hrtimer_sleep(unsigned long cnt) void rt_ktime_hrtimer_delay_init(struct rt_ktime_hrtimer *timer)
{
rt_ktime_hrtimer_init(timer, "hrtimer_sleep", 0, RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_HARD_TIMER,
_sleep_timeout, &(timer->sem));
}
void rt_ktime_hrtimer_delay_detach(struct rt_ktime_hrtimer *timer)
{
rt_ktime_hrtimer_detach(timer);
}
rt_err_t rt_ktime_hrtimer_sleep(struct rt_ktime_hrtimer *timer, unsigned long cnt)
{ {
struct rt_ktime_hrtimer timer;
rt_err_t err; rt_err_t err;
if (cnt == 0) if (cnt == 0)
return -RT_EINVAL; return -RT_EINVAL;
rt_ktime_hrtimer_init(&timer, "hrtimer_sleep", cnt, RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_HARD_TIMER, timer->timeout_cnt = cnt + rt_ktime_cputimer_getcnt();
_sleep_timeout, &(timer.sem)); timer->init_cnt = cnt;
rt_ktime_hrtimer_start(&timer); /* reset the timeout of thread timer and start it */ rt_ktime_hrtimer_start(timer); /* reset the timeout of thread timer and start it */
err = rt_sem_take_interruptible(&(timer.sem), RT_WAITING_FOREVER); err = rt_sem_take_interruptible(&(timer->sem), RT_WAITING_FOREVER);
rt_ktime_hrtimer_keep_errno(&timer, err); rt_ktime_hrtimer_keep_errno(timer, err);
rt_ktime_hrtimer_detach(&timer);
return RT_EOK; return RT_EOK;
} }
rt_err_t rt_ktime_hrtimer_ndelay(unsigned long ns) rt_err_t rt_ktime_hrtimer_ndelay(struct rt_ktime_hrtimer *timer, unsigned long ns)
{ {
unsigned long res = rt_ktime_cputimer_getres(); unsigned long res = rt_ktime_cputimer_getres();
return rt_ktime_hrtimer_sleep((ns * RT_KTIME_RESMUL) / res); return rt_ktime_hrtimer_sleep(timer, (ns * RT_KTIME_RESMUL) / res);
} }
rt_err_t rt_ktime_hrtimer_udelay(unsigned long us) rt_err_t rt_ktime_hrtimer_udelay(struct rt_ktime_hrtimer *timer, unsigned long us)
{ {
return rt_ktime_hrtimer_ndelay(us * 1000); return rt_ktime_hrtimer_ndelay(timer, us * 1000);
} }
rt_err_t rt_ktime_hrtimer_mdelay(unsigned long ms) rt_err_t rt_ktime_hrtimer_mdelay(struct rt_ktime_hrtimer *timer, unsigned long ms)
{ {
return rt_ktime_hrtimer_ndelay(ms * 1000000); return rt_ktime_hrtimer_ndelay(timer, ms * 1000000);
} }

View File

@ -530,6 +530,9 @@ int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
{ {
struct timespec old_ts = {0}; struct timespec old_ts = {0};
struct timespec new_ts = {0}; struct timespec new_ts = {0};
struct rt_ktime_hrtimer timer;
rt_ktime_hrtimer_delay_init(&timer);
if (rqtp == RT_NULL) if (rqtp == RT_NULL)
{ {
@ -544,7 +547,7 @@ int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
} }
unsigned long ns = rqtp->tv_sec * NANOSECOND_PER_SECOND + rqtp->tv_nsec; unsigned long ns = rqtp->tv_sec * NANOSECOND_PER_SECOND + rqtp->tv_nsec;
rt_ktime_boottime_get_ns(&old_ts); rt_ktime_boottime_get_ns(&old_ts);
rt_ktime_hrtimer_ndelay(ns); rt_ktime_hrtimer_ndelay(&timer, ns);
if (rt_get_errno() == RT_EINTR) if (rt_get_errno() == RT_EINTR)
{ {
if (rmtp) if (rmtp)
@ -565,9 +568,13 @@ int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
rmtp->tv_nsec = rnsec; rmtp->tv_nsec = rnsec;
} }
} }
rt_ktime_hrtimer_delay_detach(&timer);
rt_set_errno(EINTR); rt_set_errno(EINTR);
return -1; return -1;
} }
rt_ktime_hrtimer_delay_detach(&timer);
return 0; return 0;
} }
RTM_EXPORT(nanosleep); RTM_EXPORT(nanosleep);