diff --git a/components/drivers/ktime/inc/ktime.h b/components/drivers/ktime/inc/ktime.h index 44e2578bcf..7ddb9e6584 100644 --- a/components/drivers/ktime/inc/ktime.h +++ b/components/drivers/ktime/inc/ktime.h @@ -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); } +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 @@ -153,7 +156,7 @@ rt_err_t rt_ktime_hrtimer_sleep(unsigned long cnt); * @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 @@ -161,7 +164,7 @@ rt_err_t rt_ktime_hrtimer_ndelay(unsigned long ns); * @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 @@ -169,6 +172,6 @@ rt_err_t rt_ktime_hrtimer_udelay(unsigned long us); * @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 diff --git a/components/drivers/ktime/src/hrtimer.c b/components/drivers/ktime/src/hrtimer.c index f22f39e128..184ee94fd0 100644 --- a/components/drivers/ktime/src/hrtimer.c +++ b/components/drivers/ktime/src/hrtimer.c @@ -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); } diff --git a/components/libc/compilers/common/ctime.c b/components/libc/compilers/common/ctime.c index c6602698ff..79d7010034 100644 --- a/components/libc/compilers/common/ctime.c +++ b/components/libc/compilers/common/ctime.c @@ -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) { @@ -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) @@ -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);