Browse Source

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

improve ktimer sleep
zms123456 1 year ago
parent
commit
5ca1e45020

+ 7 - 4
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);
     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

+ 23 - 14
components/drivers/ktime/src/hrtimer.c

@@ -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,
-                          _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;
     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);
 }
 }

+ 8 - 1
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 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);