diff --git a/components/libc/time/clock_time.c b/components/libc/time/clock_time.c index 3e3f2c6aa4b83b8cf95163e95114cf4285ed50fa..4c13785d3696e0cab89ca60cd8e519256d55557f 100644 --- a/components/libc/time/clock_time.c +++ b/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); diff --git a/components/lwp/lwp_syscall.c b/components/lwp/lwp_syscall.c index 89a8a928c90f0cbf1a91bcef1b8b36476ec53dc1..bff158ff0cfb9ca8e835a38841289461bd501e8d 100644 --- a/components/lwp/lwp_syscall.c +++ b/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; @@ -3833,7 +3870,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) { @@ -4294,11 +4334,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), @@ -4345,6 +4385,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) diff --git a/src/thread.c b/src/thread.c index 1bc28bbdba2ffa89b339d953db0c076639f62f00..39fd5d9783a7d7608d65f8823df7811394d70e4f 100644 --- a/src/thread.c +++ b/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 */