diff --git a/compat/posix/src/time.c b/compat/posix/src/time.c index 97a82ae03c4029b747280c97f8950b39df7304a1..010a68a90ce5366ade8cf87b67ff24799130c0a0 100644 --- a/compat/posix/src/time.c +++ b/compat/posix/src/time.c @@ -50,6 +50,8 @@ #include "los_swtmr_pri.h" #include "los_sys_pri.h" +#define CPUCLOCK_PERTHREAD_MASK 4 +#define CPUCLOCK_ID_OFFSET 3 /* * Do a time package defined return. This requires the error code @@ -450,13 +452,85 @@ int clock_settime(clockid_t clockID, const struct timespec *tp) return settimeofday(&tv, NULL); } +static int PthreadGetCputime(clockid_t clockID, struct timespec *ats) +{ + uint64_t runtime; + UINT32 intSave; + UINT32 tid = ((UINT32) ~((clockID) >> CPUCLOCK_ID_OFFSET)); + + if (OS_TID_CHECK_INVALID(tid)) { + return -ESRCH; + } + LosTaskCB *task = OsGetTaskCB(tid); + + if (OsCurrTaskGet()->processID != task->processID) { + return -EINVAL; + } + +#ifdef LOSCFG_KERNEL_CPUP + SCHEDULER_LOCK(intSave); + runtime = task->taskCpup.allTime; + SCHEDULER_UNLOCK(intSave); +#endif + + ats->tv_sec = runtime / OS_SYS_NS_PER_SECOND; + ats->tv_nsec = runtime % OS_SYS_NS_PER_SECOND; + + return 0; +} + +static int ProcessGetCputime(clockid_t clockID, struct timespec *ats) +{ + UINT64 runtime; + UINT32 intSave; + const pid_t pid = ((pid_t) ~((clockID) >> CPUCLOCK_ID_OFFSET)); + LosProcessCB *spcb = NULL; + + if (OsProcessIDUserCheckInvalid(pid) || pid < 0) { + return -EINVAL; + } + + spcb = OS_PCB_FROM_PID(pid); + if (OsProcessIsUnused(spcb)) { + return -EINVAL; + } + +#ifdef LOSCFG_KERNEL_CPUP + SCHEDULER_LOCK(intSave); + runtime = spcb->processCpup.allTime; + SCHEDULER_UNLOCK(intSave); +#endif + + ats->tv_sec = runtime / OS_SYS_NS_PER_SECOND; + ats->tv_nsec = runtime % OS_SYS_NS_PER_SECOND; + + return 0; +} + +static int GetCputime(clockid_t clockID, struct timespec *tp) +{ + int ret; + + if (clockID >= 0) { + return -EINVAL; + } + + if ((UINT32)clockID & CPUCLOCK_PERTHREAD_MASK) { + ret = PthreadGetCputime(clockID, tp); + } else { + ret = ProcessGetCputime(clockID, tp); + } + + return ret; +} + int clock_gettime(clockid_t clockID, struct timespec *tp) { UINT32 intSave; struct timespec64 tmp = {0}; struct timespec64 hwTime = {0}; - if ((clockID > MAX_CLOCKS) || (clockID < CLOCK_REALTIME)) { + if (clockID > MAX_CLOCKS) { goto ERROUT; } @@ -497,7 +571,10 @@ int clock_gettime(clockid_t clockID, struct timespec *tp) case CLOCK_TAI: TIME_RETURN(ENOTSUP); default: - goto ERROUT; + { + int ret = GetCputime(clockID, tp); + TIME_RETURN(-ret); + } } return 0; @@ -506,6 +583,37 @@ ERROUT: TIME_RETURN(EINVAL); } +static int CheckClock(const clockid_t clockID) +{ + int error = 0; + const pid_t pid = ((pid_t) ~((clockID) >> CPUCLOCK_ID_OFFSET)); + + if (!((UINT32)clockID & CPUCLOCK_PERTHREAD_MASK)) { + LosProcessCB *spcb = NULL; + if (OsProcessIDUserCheckInvalid(pid) || pid < 0) { + return -EINVAL; + } + spcb = OS_PCB_FROM_PID(pid); + if (OsProcessIsUnused(spcb)) { + error = -EINVAL; + } + } else { + error = -EINVAL; + } + + return error; +} + +static int CpuClockGetres(const clockid_t clockID, struct timespec *tp) +{ + int error = CheckClock(clockID); + if (!error) { + error = ProcessGetCputime(clockID, tp); + } + + return error; +} + int clock_getres(clockid_t clockID, struct timespec *tp) { if (tp == NULL) { @@ -536,7 +644,10 @@ int clock_getres(clockid_t clockID, struct timespec *tp) case CLOCK_TAI: TIME_RETURN(ENOTSUP); default: - TIME_RETURN(EINVAL); + { + int ret = CpuClockGetres(clockID, tp); + TIME_RETURN(-ret); + } } TIME_RETURN(0); diff --git a/testsuites/unittest/time/clock/time_clock_test.cpp b/testsuites/unittest/time/clock/time_clock_test.cpp index 0d73d34bd5535a0c9f6ffb2841ee4cb967f5368d..43655d17bc146d8026235631500199f9b34b059c 100644 --- a/testsuites/unittest/time/clock/time_clock_test.cpp +++ b/testsuites/unittest/time/clock/time_clock_test.cpp @@ -133,7 +133,9 @@ HWTEST_F(TimeClockTest, ClockTest009, TestSize.Level0) { ClockTest009(); } +#endif +#if defined(LOSCFG_USER_TEST_FULL) /* * * @tc.name: ClockTest010 * @tc.desc: function for TimeClockTest @@ -145,5 +147,27 @@ HWTEST_F(TimeClockTest, ClockTest010, TestSize.Level0) ClockTest010(); } +/* * + * @tc.name: ClockTest011 + * @tc.desc: test pthread_getcpuclockid:get pthread time + * @tc.type: FUNC + * @tc.require: AR000E0QAB + */ +HWTEST_F(TimeClockTest, ClockTest011, TestSize.Level0) +{ + ClockTest011(); +} + +/* * + * @tc.name: ClockTest012 + * @tc.desc: test clock_getcpuclockid:get process time + * @tc.type: FUNC + * @tc.require: AR000E0QAB + */ +HWTEST_F(TimeClockTest, ClockTest012, TestSize.Level0) +{ + ClockTest012(); +} + #endif } // namespace OHOS diff --git a/testsuites/unittest/time/timer/time_timer_test.cpp b/testsuites/unittest/time/timer/time_timer_test.cpp index d25aaa3b79a03b565138dbaec15a076f5e4898a4..187ea91149f72ab6ab2c1d4daab331e01d1b7c4f 100644 --- a/testsuites/unittest/time/timer/time_timer_test.cpp +++ b/testsuites/unittest/time/timer/time_timer_test.cpp @@ -82,10 +82,31 @@ HWTEST_F(TimeTimerTest, TimerTest003, TestSize.Level0) * @tc.type: FUNC * @tc.require: AR000EEMQ9 */ -/* HWTEST_F(TimeTimerTest, TimerTest004, TestSize.Level0) +/*HWTEST_F(TimeTimerTest, TimerTest004, TestSize.Level0) { - TimerTest004(); -} */ + TimerTest004(); // TODO: musl sigaction handler have only one param. +}*/ +/* * + * @tc.name: TIME_TEST_TZSET_001 + * @tc.desc: function for TIME_TEST_TZSET_001 + * @tc.type: FUNC + * @tc.require: AR000EEMQ9 + */ +HWTEST_F(TimeTimerTest, TIME_TEST_TZSET_001, TestSize.Level0) +{ + TIME_TEST_TZSET_001(); +} + +/* * + * @tc.name: TIME_TEST_TZSET_002 + * @tc.desc: function for TimeTimerTest + * @tc.type: FUNC + * @tc.require: AR000EEMQ9 + */ +HWTEST_F(TimeTimerTest, TIME_TEST_TZSET_002, TestSize.Level0) +{ + TIME_TEST_TZSET_002(); +} #endif } // namespace OHOS