From 7f1807f5d52a39db4538ca6d44e36e91518c429d Mon Sep 17 00:00:00 2001 From: zhkag Date: Wed, 16 Nov 2022 10:03:47 +0000 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=20timer=20=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/libc/time/clock_time.c | 327 ++++++++++++++++++++++++++---- components/libc/time/clock_time.h | 15 ++ components/lwp/lwp_syscall.c | 89 +++++--- include/rtdef.h | 1 + src/timer.c | 4 + 5 files changed, 372 insertions(+), 64 deletions(-) diff --git a/components/libc/time/clock_time.c b/components/libc/time/clock_time.c index 9411835c23..56563aa23f 100644 --- a/components/libc/time/clock_time.c +++ b/components/libc/time/clock_time.c @@ -12,6 +12,7 @@ #include #include #include "clock_time.h" +#include "lwp.h" static struct timeval _timevalue; int clock_time_system_init() @@ -82,7 +83,7 @@ int clock_getres(clockid_t clockid, struct timespec *res) if (res == RT_NULL) { rt_set_errno(EINVAL); - return -1; + return -RT_ERROR; } switch (clockid) @@ -101,7 +102,7 @@ int clock_getres(clockid_t clockid, struct timespec *res) #endif default: - ret = -1; + ret = -RT_ERROR; rt_set_errno(EINVAL); break; } @@ -117,7 +118,7 @@ int clock_gettime(clockid_t clockid, struct timespec *tp) if (tp == RT_NULL) { rt_set_errno(EINVAL); - return -1; + return -RT_ERROR; } switch (clockid) @@ -149,7 +150,7 @@ int clock_gettime(clockid_t clockid, struct timespec *tp) #endif default: rt_set_errno(EINVAL); - ret = -1; + ret = -RT_ERROR; } return ret; @@ -166,7 +167,7 @@ int clock_settime(clockid_t clockid, const struct timespec *tp) { rt_set_errno(EINVAL); - return -1; + return -RT_ERROR; } /* get second */ @@ -186,7 +187,7 @@ int clock_settime(clockid_t clockid, const struct timespec *tp) rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &second); } else - return -1; + return -RT_ERROR; return 0; } @@ -194,10 +195,10 @@ RTM_EXPORT(clock_settime); int clock_nanosleep(clockid_t clockid, int flags, const struct timespec *rqtp, struct timespec *rmtp) { - if (rqtp->tv_sec < 0 || rqtp->tv_nsec < 0 || rqtp->tv_nsec >= 1000000000) + if (rqtp->tv_sec < 0 || rqtp->tv_nsec < 0 || rqtp->tv_nsec >= NANOSECOND_PER_SECOND) { rt_set_errno(EINVAL); - return -1; + return -RT_ERROR; } switch (clockid) { @@ -206,20 +207,27 @@ int clock_nanosleep(clockid_t clockid, int flags, const struct timespec *rqtp, s rt_tick_t tick; if (flags & TIMER_ABSTIME == TIMER_ABSTIME) { - tick = (rqtp->tv_sec - _timevalue.tv_sec) * RT_TICK_PER_SECOND + ((uint64_t)(rqtp->tv_nsec - _timevalue.tv_usec) * RT_TICK_PER_SECOND) / 1000000000; + tick = (rqtp->tv_sec - _timevalue.tv_sec) * RT_TICK_PER_SECOND + (rqtp->tv_nsec - _timevalue.tv_usec) * (RT_TICK_PER_SECOND / NANOSECOND_PER_SECOND); rt_tick_t rt_tick = rt_tick_get(); tick = tick < rt_tick ? 0 : tick - rt_tick; } else { - tick = rqtp->tv_sec * RT_TICK_PER_SECOND + ((uint64_t)(rqtp->tv_nsec) * RT_TICK_PER_SECOND) / 1000000000; + tick = rqtp->tv_sec * RT_TICK_PER_SECOND + ((uint64_t)(rqtp->tv_nsec) * RT_TICK_PER_SECOND) / NANOSECOND_PER_SECOND; } rt_thread_delay(tick); - if (rmtp) + + if (rt_get_errno() == -RT_EINTR) { - tick = rt_tick_get() - tick; - rmtp->tv_sec = tick / RT_TICK_PER_SECOND; - rmtp->tv_nsec = (tick % RT_TICK_PER_SECOND) * (1000000000 / RT_TICK_PER_SECOND); + if (rmtp) + { + tick = rt_tick_get() - tick; + /* 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); + } + rt_set_errno(EINTR); + return -RT_ERROR; } } break; @@ -233,26 +241,31 @@ int clock_nanosleep(clockid_t clockid, int flags, const struct timespec *rqtp, s rt_tick_t tick; float unit = clock_cpu_getres(); - cpu_tick = (rqtp->tv_sec * NANOSECOND_PER_SECOND + ((uint64_t)rqtp->tv_nsec * NANOSECOND_PER_SECOND) / 1000000000) / unit; + cpu_tick = (rqtp->tv_sec * NANOSECOND_PER_SECOND + rqtp->tv_nsec * (NANOSECOND_PER_SECOND / NANOSECOND_PER_SECOND)) / unit; if (flags & TIMER_ABSTIME == TIMER_ABSTIME) cpu_tick = cpu_tick < cpu_tick_old ? 0 : cpu_tick - cpu_tick_old; - tick = cpu_tick / (NANOSECOND_PER_SECOND / RT_TICK_PER_SECOND); + tick = (unit * cpu_tick) / (NANOSECOND_PER_SECOND / RT_TICK_PER_SECOND); rt_thread_delay(tick); - if (rmtp) + if (rt_get_errno() == -RT_EINTR) { - uint64_t rmtp_cpu_tick = clock_cpu_gettime() - tick * (NANOSECOND_PER_SECOND / RT_TICK_PER_SECOND); - rmtp->tv_sec = ((int)(rmtp_cpu_tick * unit)) / NANOSECOND_PER_SECOND; - rmtp->tv_nsec = ((int)(rmtp_cpu_tick * unit)) % NANOSECOND_PER_SECOND; + if (rmtp) + { + uint64_t rmtp_cpu_tick = clock_cpu_gettime() - tick * (NANOSECOND_PER_SECOND / RT_TICK_PER_SECOND); + rmtp->tv_sec = ((int)(rmtp_cpu_tick * unit)) / NANOSECOND_PER_SECOND; + rmtp->tv_nsec = ((int)(rmtp_cpu_tick * unit)) % NANOSECOND_PER_SECOND; + } + rt_set_errno(EINTR); + return -RT_ERROR; } - - while (clock_cpu_gettime() - cpu_tick_old < cpu_tick); + else + while (clock_cpu_gettime() - cpu_tick_old < cpu_tick); } break; #endif default: rt_set_errno(EINVAL); - return -1; + return -RT_ERROR; } return 0; @@ -261,10 +274,10 @@ RTM_EXPORT(clock_nanosleep); int nanosleep(const struct timespec *rqtp, struct timespec *rmtp) { - if (rqtp->tv_sec < 0 || rqtp->tv_nsec < 0 || rqtp->tv_nsec >= 1000000000) + if (rqtp->tv_sec < 0 || rqtp->tv_nsec < 0 || rqtp->tv_nsec >= NANOSECOND_PER_SECOND) { rt_set_errno(EINVAL); - return -1; + return -RT_ERROR; } #ifdef RT_USING_CPUTIME uint64_t cpu_tick, cpu_tick_old; @@ -272,31 +285,265 @@ int nanosleep(const struct timespec *rqtp, struct timespec *rmtp) rt_tick_t tick; float unit = clock_cpu_getres(); - cpu_tick = (rqtp->tv_sec * NANOSECOND_PER_SECOND + ((uint64_t)rqtp->tv_nsec * NANOSECOND_PER_SECOND) / 1000000000)/unit; - tick = cpu_tick / (NANOSECOND_PER_SECOND / RT_TICK_PER_SECOND); + cpu_tick = (rqtp->tv_sec * NANOSECOND_PER_SECOND + ((uint64_t)rqtp->tv_nsec * NANOSECOND_PER_SECOND) / NANOSECOND_PER_SECOND)/unit; + tick = (unit * cpu_tick) / (NANOSECOND_PER_SECOND / RT_TICK_PER_SECOND); rt_thread_delay(tick); - if (rmtp) + if (rt_get_errno() == -RT_EINTR) { - uint64_t rmtp_cpu_tick = clock_cpu_gettime() - tick * (NANOSECOND_PER_SECOND / RT_TICK_PER_SECOND); - rmtp->tv_sec = ((int)(rmtp_cpu_tick * unit)) / NANOSECOND_PER_SECOND; - rmtp->tv_nsec = ((int)(rmtp_cpu_tick * unit)) % NANOSECOND_PER_SECOND; + if (rmtp) + { + uint64_t rmtp_cpu_tick = clock_cpu_gettime() - tick * (NANOSECOND_PER_SECOND / RT_TICK_PER_SECOND); + rmtp->tv_sec = ((int)(rmtp_cpu_tick * unit)) / NANOSECOND_PER_SECOND; + rmtp->tv_nsec = ((int)(rmtp_cpu_tick * unit)) % NANOSECOND_PER_SECOND; + } + rt_set_errno(EINTR); + return -RT_ERROR; } - - while (clock_cpu_gettime() - cpu_tick_old < cpu_tick); + else + while (clock_cpu_gettime() - cpu_tick_old < cpu_tick); #else rt_tick_t tick; - tick = rqtp->tv_sec * RT_TICK_PER_SECOND + ((uint64_t)rqtp->tv_nsec * RT_TICK_PER_SECOND) / 1000000000; + tick = rqtp->tv_sec * RT_TICK_PER_SECOND + ((uint64_t)rqtp->tv_nsec * RT_TICK_PER_SECOND) / NANOSECOND_PER_SECOND; rt_thread_delay(tick); - if (rmtp) + if (rt_get_errno() == -RT_EINTR) { - tick = rt_tick_get() - tick; - /* get the passed time */ - rmtp->tv_sec = tick / RT_TICK_PER_SECOND; - rmtp->tv_nsec = (tick % RT_TICK_PER_SECOND) * (1000000000 / RT_TICK_PER_SECOND); + if (rmtp) + { + tick = rt_tick_get() - tick; + /* 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); + } + rt_set_errno(EINTR); + return -RT_ERROR; } #endif return 0; } -RTM_EXPORT(nanosleep); \ No newline at end of file +RTM_EXPORT(nanosleep); + +static void rtthread_timer_wrapper(void *timerobj) +{ + struct timer_obj *timer; + + timer = (struct timer_obj *)timerobj; + sys_kill(timer->pid, timer->sigev_signo); + + if (timer->reload == 0U) + { + timer->status = NOT_ACTIVE; + } + + // if (timer->sigev_notify_function != RT_NULL) + // { + // (timer->sigev_notify_function)(timer->val); + // } + + timer->reload = (timer->interval.tv_sec * RT_TICK_PER_SECOND) + (timer->interval.tv_nsec * RT_TICK_PER_SECOND) / NANOSECOND_PER_SECOND; + rt_timer_control(&timer->timer, RT_TIMER_CTRL_SET_TIME, &(timer->reload)); +} + +int timer_create(clockid_t clockid, struct sigevent *evp, timer_t *timerid) +{ + static int num = 0; + struct timer_obj *timer; + char timername[RT_NAME_MAX] = {0}; + + if (clockid > CLOCK_TAI || evp->sigev_notify != SIGEV_NONE && evp->sigev_notify != SIGEV_SIGNAL) + { + rt_set_errno(EINVAL); + return -RT_ERROR; + } + + timer = rt_malloc(sizeof(struct timer_obj)); + if (timer == RT_NULL) + { + rt_set_errno(ENOMEM); + return -RT_ENOMEM; + } + + rt_snprintf(timername, RT_NAME_MAX, "psx_tm%02d", num++); + num %= 100; + timer->sigev_signo = evp->sigev_signo; + timer->pid = lwp_self()->pid; + timer->sigev_notify_function = evp->sigev_notify_function; + timer->val = evp->sigev_value; + timer->interval.tv_sec = 0; + timer->interval.tv_nsec = 0; + timer->reload = 0U; + timer->status = NOT_ACTIVE; + + if (evp->sigev_notify == SIGEV_NONE) + { + rt_timer_init(&timer->timer, timername, RT_NULL, RT_NULL, 0, RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER); + } + else + { + rt_timer_init(&timer->timer, timername, rtthread_timer_wrapper, timer, 0, RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER); + } + + *timerid = (timer_t)((uintptr_t)timer >> 1); + + return RT_EOK; +} +RTM_EXPORT(timer_create); + +int timer_delete(timer_t timerid) +{ + struct timer_obj *timer = (struct timer_obj *)((uintptr_t)timerid << 1); + + if (timer == RT_NULL || rt_object_get_type(&timer->timer.parent) != RT_Object_Class_Timer) + { + rt_set_errno(EINVAL); + return -RT_ERROR; + } + + if (timer->status == ACTIVE) + { + timer->status = NOT_ACTIVE; + rt_timer_stop(&timer->timer); + } + rt_timer_detach(&timer->timer); + rt_free(timer); + return RT_EOK; +} +RTM_EXPORT(timer_delete); + +int timer_getoverrun(timer_t timerid) +{ + struct timer_obj *timer = (struct timer_obj *)((uintptr_t)timerid << 1); + rt_set_errno(ENOSYS); + return -RT_ERROR; +} + +int timer_gettime(timer_t timerid, struct itimerspec *its) +{ + struct timer_obj *timer = (struct timer_obj *)((uintptr_t)timerid << 1); + rt_tick_t remaining; + rt_uint32_t seconds, nanoseconds; + + if (timer == NULL || rt_object_get_type(&timer->timer.parent) != RT_Object_Class_Timer) + { + rt_set_errno(EINVAL); + return -RT_ERROR; + } + + if (its == NULL) + { + rt_set_errno(EFAULT); + return -RT_ERROR; + } + + if (timer->status == ACTIVE) + { + rt_tick_t remain_tick; + + rt_timer_control(&timer->timer, RT_TIMER_CTRL_GET_REMAIN_TIME, &remain_tick); + + /* 'remain_tick' is minimum-unit in the RT-Thread' timer, + * so the seconds, nanoseconds will be calculated by 'remain_tick'. + */ + remaining = remain_tick - rt_tick_get(); + + /* calculate 'second' */ + seconds = remaining / RT_TICK_PER_SECOND; + + /* calculate 'nanosecond'; To avoid lost of accuracy, because "RT_TICK_PER_SECOND" maybe 100, 1000, 1024 and so on. + * + * remain_tick millisecond remain_tick * MILLISECOND_PER_SECOND + * ------------------------- = -------------------------- ---> millisecond = ------------------------------------------- + * RT_TICK_PER_SECOND MILLISECOND_PER_SECOND RT_TICK_PER_SECOND + * + * remain_tick * MILLISECOND_PER_SECOND remain_tick * MILLISECOND_PER_SECOND * MICROSECOND_PER_SECOND + * millisecond = ---------------------------------------- ---> nanosecond = ------------------------------------------------------------------- + * RT_TICK_PER_SECOND RT_TICK_PER_SECOND + * + */ + nanoseconds = (((remaining % RT_TICK_PER_SECOND) * MILLISECOND_PER_SECOND) * MICROSECOND_PER_SECOND) / RT_TICK_PER_SECOND; + + its->it_value.tv_sec = (rt_int32_t)seconds; + its->it_value.tv_nsec = (rt_int32_t)nanoseconds; + } + else + { + /* Timer is disarmed */ + its->it_value.tv_sec = 0; + its->it_value.tv_nsec = 0; + } + + /* The interval last set by timer_settime() */ + its->it_interval = timer->interval; + return RT_EOK; +} +RTM_EXPORT(timer_gettime); + +int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, + struct itimerspec *ovalue) +{ + struct timer_obj *timer = (struct timer_obj *)((uintptr_t)timerid << 1); + if (timer == NULL || + rt_object_get_type(&timer->timer.parent) != RT_Object_Class_Timer || + value->it_interval.tv_nsec < 0 || + value->it_interval.tv_nsec >= NANOSECOND_PER_SECOND || + value->it_interval.tv_sec < 0 || + value->it_value.tv_nsec < 0 || + value->it_value.tv_nsec >= NANOSECOND_PER_SECOND || + value->it_value.tv_sec < 0) + { + rt_set_errno(EINVAL); + return -RT_ERROR; + } + + /* Save time to expire and old reload value. */ + if (ovalue != NULL) + { + timer_gettime(timerid, ovalue); + } + + /* Stop the timer if the value is 0 */ + if ((value->it_value.tv_sec == 0) && (value->it_value.tv_nsec == 0)) + { + if (timer->status == ACTIVE) + { + rt_timer_stop(&timer->timer); + } + + timer->status = NOT_ACTIVE; + return RT_EOK; + } + + if (flags & TIMER_ABSTIME == TIMER_ABSTIME) + { + rt_int64_t ts = ((value->it_value.tv_sec - _timevalue.tv_sec) * RT_TICK_PER_SECOND); + rt_int64_t tns = (value->it_value.tv_nsec - _timevalue.tv_usec) * (RT_TICK_PER_SECOND / NANOSECOND_PER_SECOND); + rt_int64_t reload = ts + tns; + rt_tick_t rt_tick = rt_tick_get(); + timer->reload = reload < rt_tick ? 0 : reload - rt_tick; + } + else + timer->reload = (value->it_value.tv_sec * RT_TICK_PER_SECOND) + value->it_value.tv_nsec * (RT_TICK_PER_SECOND / NANOSECOND_PER_SECOND); + timer->interval.tv_sec = value->it_interval.tv_sec; + timer->interval.tv_nsec = value->it_interval.tv_nsec; + timer->value.tv_sec = value->it_value.tv_sec; + timer->value.tv_nsec = value->it_value.tv_nsec; + + if (timer->status == ACTIVE) + { + rt_timer_stop(&timer->timer); + } + + timer->status = ACTIVE; + + if ((value->it_interval.tv_sec == 0) && (value->it_interval.tv_nsec == 0)) + rt_timer_control(&timer->timer, RT_TIMER_CTRL_SET_ONESHOT, RT_NULL); + else + rt_timer_control(&timer->timer, RT_TIMER_CTRL_SET_PERIODIC, RT_NULL); + + rt_timer_control(&timer->timer, RT_TIMER_CTRL_SET_TIME, &(timer->reload)); + rt_timer_start(&timer->timer); + + return RT_EOK; +} +RTM_EXPORT(timer_settime); \ No newline at end of file diff --git a/components/libc/time/clock_time.h b/components/libc/time/clock_time.h index 0909d79613..90e8acb063 100644 --- a/components/libc/time/clock_time.h +++ b/components/libc/time/clock_time.h @@ -41,6 +41,21 @@ extern "C" { #define CLOCK_MONOTONIC 4 #endif +#define ACTIVE 1 +#define NOT_ACTIVE 0 +struct timer_obj +{ + struct rt_timer timer; + void (*sigev_notify_function)(union sigval val); + union sigval val; + struct timespec interval; /* Reload value */ + struct timespec value; /* Reload value */ + rt_uint32_t reload; /* Reload value in ms */ + rt_uint32_t status; + int sigev_signo; + pid_t pid; +}; + int clock_getres (clockid_t clockid, struct timespec *res); int clock_gettime (clockid_t clockid, struct timespec *tp); int clock_settime (clockid_t clockid, const struct timespec *tp); diff --git a/components/lwp/lwp_syscall.c b/components/lwp/lwp_syscall.c index 8f7faf2d7c..89a8a928c9 100644 --- a/components/lwp/lwp_syscall.c +++ b/components/lwp/lwp_syscall.c @@ -920,7 +920,7 @@ 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 && rmtp && lwp_user_accessable((void *)rmtp, sizeof *rmtp)) + 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); #else if (rmtp) @@ -1231,38 +1231,79 @@ static void timer_timeout_callback(void *parameter) rt_sem_release(sem); } -rt_timer_t sys_timer_create(const char *name, - void *data, - rt_tick_t time, - rt_uint8_t flag) +rt_err_t sys_timer_create(clockid_t clockid, struct sigevent *restrict sevp, timer_t *restrict timerid) { - 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) + int ret = 0; +#ifdef RT_USING_USERSPACE + struct sigevent sevp_k; + timer_t timerid_k; + struct sigevent evp_default; + if (sevp == NULL) { - rt_timer_delete(timer); - timer = NULL; + sevp_k.sigev_notify = SIGEV_SIGNAL; + sevp_k.sigev_signo = SIGALRM; + sevp = &sevp_k; + } + else + lwp_get_from_user(&sevp_k, (void *)sevp, sizeof sevp_k); + lwp_get_from_user(&timerid_k, (void *)timerid, sizeof timerid_k); + ret = timer_create(clockid, &sevp_k, &timerid_k); + if (ret != -RT_ERROR){ + lwp_put_to_user(sevp, (void *)&sevp_k, sizeof sevp_k); + lwp_put_to_user(timerid, (void *)&timerid_k, sizeof timerid_k); } - return timer; +#else + ret = timer_create(clockid, sevp, timerid); +#endif + return (ret < 0 ? GET_ERRNO() : ret); } -rt_err_t sys_timer_delete(rt_timer_t timer) +rt_err_t sys_timer_delete(timer_t timerid) { - return lwp_user_object_delete(lwp_self(), (rt_object_t)timer); + int ret = timer_delete(timerid); + return (ret < 0 ? GET_ERRNO() : ret); } -rt_err_t sys_timer_start(rt_timer_t timer) +rt_err_t sys_timer_settime(timer_t timerid, int flags, + const struct itimerspec *restrict new_value, + struct itimerspec *restrict old_value) { - return rt_timer_start(timer); + int ret = 0; +#ifdef RT_USING_USERSPACE + struct itimerspec new_value_k; + struct itimerspec old_value_k; + + lwp_get_from_user(&new_value_k, (void *)new_value, sizeof new_value_k); + lwp_get_from_user(&old_value_k, (void *)timerid, sizeof old_value_k); + ret = timer_settime(timerid, flags, &new_value_k, &old_value_k); + lwp_put_to_user(old_value, (void *)&old_value_k, sizeof old_value_k); + +#else + ret = timer_settime(timerid, flags, new_value, old_value); +#endif + return (ret < 0 ? GET_ERRNO() : ret); } -rt_err_t sys_timer_stop(rt_timer_t timer) +rt_err_t sys_timer_gettime(timer_t timerid, struct itimerspec *curr_value) { - return rt_timer_stop(timer); + int ret = 0; +#ifdef RT_USING_USERSPACE + + struct itimerspec curr_value_k; + lwp_get_from_user(&curr_value_k, (void *)curr_value, sizeof curr_value_k); + ret = timer_gettime(timerid, &curr_value_k); + lwp_put_to_user(curr_value, (void *)&curr_value_k, sizeof curr_value_k); +#else + ret = timer_gettime(timerid, curr_value); +#endif + return (ret < 0 ? GET_ERRNO() : ret); } -rt_err_t sys_timer_control(rt_timer_t timer, int cmd, void *arg) +rt_err_t sys_timer_getoverrun(timer_t timerid) { - return rt_timer_control(timer, cmd, arg); + int ret = 0; + ret = timer_getoverrun(timerid); + return (ret < 0 ? GET_ERRNO() : ret); } rt_thread_t sys_thread_create(void *arg[]) @@ -1579,7 +1620,7 @@ static int lwp_copy_files(struct rt_lwp *dst, struct rt_lwp *src) dfs_fd_unlock(); return 0; } - return -1; + return -RT_ERROR; } int _sys_fork(void) @@ -1848,7 +1889,7 @@ static char *_load_script(const char *filename, struct lwp_args_info *args) { void *page = NULL; char *new_page; - int fd = -1; + int fd = -RT_ERROR; int len; char interp[INTERP_BUF_SIZE]; char *cp; @@ -3791,7 +3832,7 @@ 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 && rmtp && lwp_user_accessable((void *)rmtp, sizeof *rmtp)) + 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); #else if (rmtp) @@ -4255,9 +4296,9 @@ const static void* func_table[] = SYSCALL_SIGN(sys_timer_create), SYSCALL_SIGN(sys_timer_delete), - SYSCALL_SIGN(sys_timer_start), - SYSCALL_SIGN(sys_timer_stop), - SYSCALL_SIGN(sys_timer_control), /* 115 */ + SYSCALL_SIGN(sys_timer_settime), + SYSCALL_SIGN(sys_timer_gettime), + SYSCALL_SIGN(sys_timer_getoverrun), /* 115 */ SYSCALL_SIGN(sys_getcwd), SYSCALL_SIGN(sys_chdir), SYSCALL_SIGN(sys_unlink), diff --git a/include/rtdef.h b/include/rtdef.h index 4f56793c0f..060e5c6e45 100644 --- a/include/rtdef.h +++ b/include/rtdef.h @@ -462,6 +462,7 @@ struct rt_object_information #define RT_TIMER_CTRL_SET_FUNC 0x6 /**< set timer timeout func */ #define RT_TIMER_CTRL_GET_PARM 0x7 /**< get timer parameter */ #define RT_TIMER_CTRL_SET_PARM 0x8 /**< get timer parameter */ +#define RT_TIMER_CTRL_GET_REMAIN_TIME 0x9 /**< get timer remain time */ #ifndef RT_TIMER_SKIP_LIST_LEVEL #define RT_TIMER_SKIP_LIST_LEVEL 1 diff --git a/src/timer.c b/src/timer.c index 838d1c2d1f..2014b05eb8 100644 --- a/src/timer.c +++ b/src/timer.c @@ -529,6 +529,10 @@ rt_err_t rt_timer_control(rt_timer_t timer, int cmd, void *arg) timer->parameter = arg; break; + case RT_TIMER_CTRL_GET_REMAIN_TIME: + *(rt_tick_t *)arg = timer->timeout_tick; + break; + default: break; } -- Gitee