Browse Source

!617 还原原生定时器的支持
Merge pull request !617 from zhkag/rt-smart

bernard 2 years ago
parent
commit
8cfa2f628f
3 changed files with 58 additions and 12 deletions
  1. 6 6
      components/libc/time/clock_time.c
  2. 50 5
      components/lwp/lwp_syscall.c
  3. 2 1
      src/thread.c

+ 6 - 6
components/libc/time/clock_time.c

@@ -203,7 +203,7 @@ int clock_nanosleep(clockid_t clockid, int flags, const struct timespec *rqtp, s
     {
     case CLOCK_REALTIME:
     {
-        rt_tick_t tick;
+        rt_tick_t tick, tick_old = rt_tick_get();
         if (flags & TIMER_ABSTIME == TIMER_ABSTIME)
         {
             tick = (rqtp->tv_sec - _timevalue.tv_sec) * RT_TICK_PER_SECOND + (rqtp->tv_nsec - _timevalue.tv_usec) * (RT_TICK_PER_SECOND / NANOSECOND_PER_SECOND);
@@ -220,7 +220,7 @@ int clock_nanosleep(clockid_t clockid, int flags, const struct timespec *rqtp, s
         {
             if (rmtp)
             {
-                tick = rt_tick_get() - tick;
+                tick = tick_old + tick - rt_tick_get();
                 /* get the passed time */
                 rmtp->tv_sec = tick / RT_TICK_PER_SECOND;
                 rmtp->tv_nsec = (tick % RT_TICK_PER_SECOND) * (NANOSECOND_PER_SECOND / RT_TICK_PER_SECOND);
@@ -250,7 +250,7 @@ int clock_nanosleep(clockid_t clockid, int flags, const struct timespec *rqtp, s
         {
             if (rmtp)
             {
-                uint64_t rmtp_cpu_tick = clock_cpu_gettime() - tick * (NANOSECOND_PER_SECOND / RT_TICK_PER_SECOND);
+                uint64_t rmtp_cpu_tick = cpu_tick_old + cpu_tick - clock_cpu_gettime();
                 rmtp->tv_sec = ((int)(rmtp_cpu_tick * unit)) / NANOSECOND_PER_SECOND;
                 rmtp->tv_nsec = ((int)(rmtp_cpu_tick * unit)) % NANOSECOND_PER_SECOND;
             }
@@ -292,7 +292,7 @@ int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
     {
         if (rmtp)
         {
-            uint64_t rmtp_cpu_tick = clock_cpu_gettime() - tick * (NANOSECOND_PER_SECOND / RT_TICK_PER_SECOND);
+            uint64_t rmtp_cpu_tick = cpu_tick_old + cpu_tick - clock_cpu_gettime();
             rmtp->tv_sec = ((int)(rmtp_cpu_tick * unit)) / NANOSECOND_PER_SECOND;
             rmtp->tv_nsec = ((int)(rmtp_cpu_tick * unit)) % NANOSECOND_PER_SECOND;
         }
@@ -302,7 +302,7 @@ int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
     else
         while (clock_cpu_gettime() - cpu_tick_old < cpu_tick);
 #else
-    rt_tick_t tick;
+    rt_tick_t tick, tick_old = rt_tick_get();
     tick = rqtp->tv_sec * RT_TICK_PER_SECOND + ((uint64_t)rqtp->tv_nsec * RT_TICK_PER_SECOND) / NANOSECOND_PER_SECOND;
     rt_thread_delay(tick);
 
@@ -310,7 +310,7 @@ int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
     {
         if (rmtp)
         {
-            tick = rt_tick_get() - tick;
+            tick = tick_old + tick - rt_tick_get();
             /* get the passed time */
             rmtp->tv_sec = tick / RT_TICK_PER_SECOND;
             rmtp->tv_nsec = (tick % RT_TICK_PER_SECOND) * (NANOSECOND_PER_SECOND / RT_TICK_PER_SECOND);

+ 50 - 5
components/lwp/lwp_syscall.c

@@ -921,7 +921,10 @@ int sys_nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
     lwp_get_from_user(&rqtp_k, (void *)rqtp, sizeof rqtp_k);
     ret = nanosleep(&rqtp_k, &rmtp_k);
     if ((ret != -1 || rt_get_errno() == EINTR) && rmtp && lwp_user_accessable((void *)rmtp, sizeof *rmtp))
+    {
         lwp_put_to_user(rmtp, (void *)&rmtp_k, sizeof rmtp_k);
+        return -EINTR;
+    }
 #else
     if (rmtp)
     {
@@ -1231,6 +1234,40 @@ static void timer_timeout_callback(void *parameter)
     rt_sem_release(sem);
 }
 
+rt_timer_t sys_rt_timer_create(const char *name,
+                               void *data,
+                               rt_tick_t time,
+                               rt_uint8_t flag)
+{
+    rt_timer_t timer = rt_timer_create(name, timer_timeout_callback, (void *)data, time, flag);
+    if (lwp_user_object_add(lwp_self(), (rt_object_t)timer) != 0)
+    {
+        rt_timer_delete(timer);
+        timer = NULL;
+    }
+    return timer;
+}
+
+rt_err_t sys_rt_timer_delete(rt_timer_t timer)
+{
+    return lwp_user_object_delete(lwp_self(), (rt_object_t)timer);
+}
+
+rt_err_t sys_rt_timer_start(rt_timer_t timer)
+{
+    return rt_timer_start(timer);
+}
+
+rt_err_t sys_rt_timer_stop(rt_timer_t timer)
+{
+    return rt_timer_stop(timer);
+}
+
+rt_err_t sys_rt_timer_control(rt_timer_t timer, int cmd, void *arg)
+{
+    return rt_timer_control(timer, cmd, arg);
+}
+
 rt_err_t sys_timer_create(clockid_t clockid, struct sigevent *restrict sevp, timer_t *restrict timerid)
 {
     int ret = 0;
@@ -3871,7 +3908,10 @@ int sys_clock_nanosleep(clockid_t clk, int flags, const struct timespec *rqtp, s
     lwp_get_from_user(&rqtp_k, (void *)rqtp, sizeof rqtp_k);
     ret = clock_nanosleep(clk, flags, &rqtp_k, &rmtp_k);
     if ((ret != -1 || rt_get_errno() == EINTR) && rmtp && lwp_user_accessable((void *)rmtp, sizeof *rmtp))
+    {
         lwp_put_to_user(rmtp, (void *)&rmtp_k, sizeof rmtp_k);
+        return -EINTR;
+    }
 #else
     if (rmtp)
     {
@@ -4392,11 +4432,11 @@ const static void* func_table[] =
 #endif
     SYSCALL_SIGN(sys_waitpid),          /* 110 */
 
-    SYSCALL_SIGN(sys_timer_create),
-    SYSCALL_SIGN(sys_timer_delete),
-    SYSCALL_SIGN(sys_timer_settime),
-    SYSCALL_SIGN(sys_timer_gettime),
-    SYSCALL_SIGN(sys_timer_getoverrun),  /* 115 */
+    SYSCALL_SIGN(sys_rt_timer_create),
+    SYSCALL_SIGN(sys_rt_timer_delete),
+    SYSCALL_SIGN(sys_rt_timer_start),
+    SYSCALL_SIGN(sys_rt_timer_stop),
+    SYSCALL_SIGN(sys_rt_timer_control),  /* 115 */
     SYSCALL_SIGN(sys_getcwd),
     SYSCALL_SIGN(sys_chdir),
     SYSCALL_SIGN(sys_unlink),
@@ -4443,6 +4483,11 @@ const static void* func_table[] =
     SYSCALL_SIGN(sys_setaffinity),
     SYSCALL_SIGN(sys_fsync),
     SYSCALL_SIGN(sys_clock_nanosleep),
+    SYSCALL_SIGN(sys_timer_create),
+    SYSCALL_SIGN(sys_timer_delete),
+    SYSCALL_SIGN(sys_timer_settime),
+    SYSCALL_SIGN(sys_timer_gettime),
+    SYSCALL_SIGN(sys_timer_getoverrun),
 };
 
 const void *lwp_get_sys_api(rt_uint32_t number)

+ 2 - 1
src/thread.c

@@ -561,7 +561,8 @@ rt_err_t rt_thread_sleep(rt_tick_t tick)
 
         /* enable interrupt */
         rt_hw_interrupt_enable(temp);
-
+        
+        thread->error = -RT_EINTR;
         rt_schedule();
 
         /* clear error number of this thread to RT_EOK */