diff options
| author | Meco Man <[email protected]> | 2021-02-12 01:30:41 +0800 |
|---|---|---|
| committer | Meco Man <[email protected]> | 2021-02-12 01:30:41 +0800 |
| commit | 291fe36139788cf31bd5c6cdb2ac3919dfa0b0cb (patch) | |
| tree | 3afe6c1bf30ff9b588dc81e70d419b80b242e716 /components/libc/compilers | |
| parent | f0805a7973ffe62e459da7748cbada62bccf98b9 (diff) | |
[pthread][libc] move 'clock_time' to libc
Diffstat (limited to 'components/libc/compilers')
| -rw-r--r-- | components/libc/compilers/common/sys/time.h | 33 | ||||
| -rw-r--r-- | components/libc/compilers/common/time.c | 163 |
2 files changed, 195 insertions, 1 deletions
diff --git a/components/libc/compilers/common/sys/time.h b/components/libc/compilers/common/sys/time.h index 599b8b5262..34ca9427b9 100644 --- a/components/libc/compilers/common/sys/time.h +++ b/components/libc/compilers/common/sys/time.h @@ -10,6 +10,7 @@ #ifndef _SYS_TIME_H_ #define _SYS_TIME_H_ +#include <rtconfig.h> #include <time.h> #ifdef __cplusplus @@ -53,6 +54,38 @@ time_t timegm(struct tm * const t); int gettimeofday(struct timeval *tv, struct timezone *tz); int settimeofday(const struct timeval *tv, const struct timezone *tz); +#ifdef RT_USING_PTHREADS +/* posix clock and timer */ +#define MILLISECOND_PER_SECOND 1000UL +#define MICROSECOND_PER_SECOND 1000000UL +#define NANOSECOND_PER_SECOND 1000000000UL + +#define MILLISECOND_PER_TICK (MILLISECOND_PER_SECOND / RT_TICK_PER_SECOND) +#define MICROSECOND_PER_TICK (MICROSECOND_PER_SECOND / RT_TICK_PER_SECOND) +#define NANOSECOND_PER_TICK (NANOSECOND_PER_SECOND / RT_TICK_PER_SECOND) + +#ifndef CLOCK_REALTIME +#define CLOCK_REALTIME 1 +#endif + +#define CLOCK_CPUTIME_ID 2 + +#ifndef CLOCK_PROCESS_CPUTIME_ID +#define CLOCK_PROCESS_CPUTIME_ID CLOCK_CPUTIME_ID +#endif +#ifndef CLOCK_THREAD_CPUTIME_ID +#define CLOCK_THREAD_CPUTIME_ID CLOCK_CPUTIME_ID +#endif + +#ifndef CLOCK_MONOTONIC +#define CLOCK_MONOTONIC 4 +#endif + +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); +#endif /*RT_USING_PTHREADS*/ + #ifdef __cplusplus } #endif diff --git a/components/libc/compilers/common/time.c b/components/libc/compilers/common/time.c index a980f742fb..d7048acc4a 100644 --- a/components/libc/compilers/common/time.c +++ b/components/libc/compilers/common/time.c @@ -14,6 +14,9 @@ * 2021-02-11 Meco Man fix bug #3183 - align days[] and months[] to 4 bytes * add difftime() * 2021-02-12 Meco Man add errno + * 2012-12-08 Bernard <clock_time.c> fix the issue of _timevalue.tv_usec initialization, + * which found by Rob <[email protected]> + * 2021-02-12 Meco Man move all of the functions located in <clock_time.c> to this file */ #include <sys/time.h> @@ -26,7 +29,7 @@ #define SPD 24*60*60 /* days per month -- nonleap! */ -const short __spm[13] = +static const short __spm[13] = { 0, (31), @@ -97,12 +100,14 @@ struct tm *gmtime_r(const time_t *timep, struct tm *r) r->tm_isdst = 0; return r; } +RTM_EXPORT(gmtime_r); struct tm* gmtime(const time_t* t) { static struct tm tmp; return gmtime_r(t, &tmp); } +RTM_EXPORT(gmtime); /*TODO: timezone */ struct tm* localtime_r(const time_t* t, struct tm* r) @@ -114,18 +119,21 @@ struct tm* localtime_r(const time_t* t, struct tm* r) local_tz = *t + utc_plus * 3600; return gmtime_r(&local_tz, r); } +RTM_EXPORT(localtime_r); struct tm* localtime(const time_t* t) { static struct tm tmp; return localtime_r(t, &tmp); } +RTM_EXPORT(localtime); /* TODO: timezone */ time_t mktime(struct tm * const t) { return timegm(t); } +RTM_EXPORT(mktime); char* asctime_r(const struct tm *t, char *buf) { @@ -147,28 +155,33 @@ char* asctime_r(const struct tm *t, char *buf) buf[24] = '\n'; return buf; } +RTM_EXPORT(asctime_r); char* asctime(const struct tm *timeptr) { static char buf[25]; return asctime_r(timeptr, buf); } +RTM_EXPORT(asctime); char *ctime_r (const time_t * tim_p, char * result) { struct tm tm; return asctime_r (localtime_r (tim_p, &tm), result); } +RTM_EXPORT(ctime_r); char* ctime(const time_t *tim_p) { return asctime (localtime (tim_p)); } +RTM_EXPORT(ctime); double difftime (time_t tim1, time_t tim2) { return (double)(tim1 - tim2); } +RTM_EXPORT(difftime); /** * Returns the current time. @@ -216,11 +229,13 @@ RT_WEAK time_t time(time_t *t) return time_now; } +RTM_EXPORT(time); RT_WEAK clock_t clock(void) { return rt_tick_get(); } +RTM_EXPORT(clock); int stime(const time_t *t) { @@ -246,6 +261,7 @@ int stime(const time_t *t) return -1; #endif /* RT_USING_RTC */ } +RTM_EXPORT(stime); time_t timegm(struct tm * const t) { @@ -320,6 +336,7 @@ time_t timegm(struct tm * const t) i = 60; return ((day + t->tm_hour) * i + t->tm_min) * i + t->tm_sec; } +RTM_EXPORT(timegm); /* TODO: timezone */ int gettimeofday(struct timeval *tv, struct timezone *tz) @@ -338,6 +355,7 @@ int gettimeofday(struct timeval *tv, struct timezone *tz) return -1; } } +RTM_EXPORT(gettimeofday); /* TODO: timezone */ int settimeofday(const struct timeval *tv, const struct timezone *tz) @@ -352,3 +370,146 @@ int settimeofday(const struct timeval *tv, const struct timezone *tz) return -1; } } +RTM_EXPORT(settimeofday); + +#ifdef RT_USING_PTHREADS +static struct timeval _timevalue; +static int clock_time_system_init() +{ + time_t time; + rt_tick_t tick; + rt_device_t device; + + time = 0; + device = rt_device_find("rtc"); + if (device != RT_NULL) + { + /* get realtime seconds */ + rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time); + } + + /* get tick */ + tick = rt_tick_get(); + + _timevalue.tv_usec = (tick%RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK; + _timevalue.tv_sec = time - tick/RT_TICK_PER_SECOND - 1; + + return 0; +} +INIT_COMPONENT_EXPORT(clock_time_system_init); + +int clock_getres(clockid_t clockid, struct timespec *res) +{ + int ret = 0; + + if (res == RT_NULL) + { + rt_set_errno(EINVAL); + return -1; + } + + switch (clockid) + { + case CLOCK_REALTIME: + res->tv_sec = 0; + res->tv_nsec = NANOSECOND_PER_SECOND/RT_TICK_PER_SECOND; + break; + +#ifdef RT_USING_CPUTIME + case CLOCK_CPUTIME_ID: + res->tv_sec = 0; + res->tv_nsec = clock_cpu_getres(); + break; +#endif + + default: + ret = -1; + rt_set_errno(EINVAL); + break; + } + + return ret; +} +RTM_EXPORT(clock_getres); + +int clock_gettime(clockid_t clockid, struct timespec *tp) +{ + int ret = 0; + + if (tp == RT_NULL) + { + rt_set_errno(EINVAL); + return -1; + } + + switch (clockid) + { + case CLOCK_REALTIME: + { + /* get tick */ + int tick = rt_tick_get(); + + tp->tv_sec = _timevalue.tv_sec + tick / RT_TICK_PER_SECOND; + tp->tv_nsec = (_timevalue.tv_usec + (tick % RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK) * 1000; + } + break; + +#ifdef RT_USING_CPUTIME + case CLOCK_CPUTIME_ID: + { + float unit = 0; + long long cpu_tick; + + unit = clock_cpu_getres(); + cpu_tick = clock_cpu_gettime(); + + tp->tv_sec = ((int)(cpu_tick * unit)) / NANOSECOND_PER_SECOND; + tp->tv_nsec = ((int)(cpu_tick * unit)) % NANOSECOND_PER_SECOND; + } + break; +#endif + default: + rt_set_errno(EINVAL); + ret = -1; + } + + return ret; +} +RTM_EXPORT(clock_gettime); + +int clock_settime(clockid_t clockid, const struct timespec *tp) +{ + int second; + rt_tick_t tick; + rt_device_t device; + + if ((clockid != CLOCK_REALTIME) || (tp == RT_NULL)) + { + rt_set_errno(EINVAL); + + return -1; + } + + /* get second */ + second = tp->tv_sec; + /* get tick */ + tick = rt_tick_get(); + + /* update timevalue */ + _timevalue.tv_usec = MICROSECOND_PER_SECOND - (tick % RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK; + _timevalue.tv_sec = second - tick/RT_TICK_PER_SECOND - 1; + + /* update for RTC device */ + device = rt_device_find("rtc"); + if (device != RT_NULL) + { + /* set realtime seconds */ + rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &second); + } + else + return -1; + + return 0; +} +RTM_EXPORT(clock_settime); +#endif /*RT_USING_PTHREADS*/ |
