Skip to content

[components][drivers]improve ktimer sleep #8838

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions components/drivers/ktime/inc/ktime.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,36 +139,39 @@ rt_inline void rt_ktime_hrtimer_keep_errno(rt_ktime_hrtimer_t timer, rt_err_t er
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
*
* @param cnt: the cputimer cnt value
* @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
*
* @param ns: ns
* @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
*
* @param us: us
* @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
*
* @param ms: ms
* @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
37 changes: 23 additions & 14 deletions components/drivers/ktime/src/hrtimer.c
Original file line number Diff line number Diff line change
Expand Up @@ -356,37 +356,46 @@ rt_err_t rt_ktime_hrtimer_detach(rt_ktime_hrtimer_t timer)

/************************** 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;

if (cnt == 0)
return -RT_EINVAL;

rt_ktime_hrtimer_init(&timer, "hrtimer_sleep", cnt, RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_HARD_TIMER,
_sleep_timeout, &(timer.sem));
timer->timeout_cnt = cnt + rt_ktime_cputimer_getcnt();
timer->init_cnt = cnt;

rt_ktime_hrtimer_start(&timer); /* reset the timeout of thread timer and start it */
err = rt_sem_take_interruptible(&(timer.sem), RT_WAITING_FOREVER);
rt_ktime_hrtimer_keep_errno(&timer, err);
rt_ktime_hrtimer_start(timer); /* reset the timeout of thread timer and start it */
err = rt_sem_take_interruptible(&(timer->sem), RT_WAITING_FOREVER);
rt_ktime_hrtimer_keep_errno(timer, err);

rt_ktime_hrtimer_detach(&timer);
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();
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);
}
9 changes: 8 additions & 1 deletion components/libc/compilers/common/ctime.c
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,9 @@ int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
{
struct timespec old_ts = {0};
struct timespec new_ts = {0};
struct rt_ktime_hrtimer timer;

rt_ktime_hrtimer_delay_init(&timer);

if (rqtp == RT_NULL)
{
Expand All @@ -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;
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 (rmtp)
Expand All @@ -565,9 +568,13 @@ int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
rmtp->tv_nsec = rnsec;
}
}

rt_ktime_hrtimer_delay_detach(&timer);
rt_set_errno(EINTR);
return -1;
}

rt_ktime_hrtimer_delay_detach(&timer);
return 0;
}
RTM_EXPORT(nanosleep);
Expand Down
Loading