10d163575Sopenharmony_ci/*
20d163575Sopenharmony_ci * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
30d163575Sopenharmony_ci * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved.
40d163575Sopenharmony_ci *
50d163575Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification,
60d163575Sopenharmony_ci * are permitted provided that the following conditions are met:
70d163575Sopenharmony_ci *
80d163575Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, this list of
90d163575Sopenharmony_ci *    conditions and the following disclaimer.
100d163575Sopenharmony_ci *
110d163575Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, this list
120d163575Sopenharmony_ci *    of conditions and the following disclaimer in the documentation and/or other materials
130d163575Sopenharmony_ci *    provided with the distribution.
140d163575Sopenharmony_ci *
150d163575Sopenharmony_ci * 3. Neither the name of the copyright holder nor the names of its contributors may be used
160d163575Sopenharmony_ci *    to endorse or promote products derived from this software without specific prior written
170d163575Sopenharmony_ci *    permission.
180d163575Sopenharmony_ci *
190d163575Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
200d163575Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
210d163575Sopenharmony_ci * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
220d163575Sopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
230d163575Sopenharmony_ci * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
240d163575Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
250d163575Sopenharmony_ci * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
260d163575Sopenharmony_ci * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
270d163575Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
280d163575Sopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
290d163575Sopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
300d163575Sopenharmony_ci */
310d163575Sopenharmony_ci
320d163575Sopenharmony_ci#include "time.h"
330d163575Sopenharmony_ci#include "stdint.h"
340d163575Sopenharmony_ci#include "stdio.h"
350d163575Sopenharmony_ci#include "sys/times.h"
360d163575Sopenharmony_ci#include "time_posix.h"
370d163575Sopenharmony_ci#include "unistd.h"
380d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_CAPABILITY
390d163575Sopenharmony_ci#include "capability_api.h"
400d163575Sopenharmony_ci#endif
410d163575Sopenharmony_ci#include "los_signal.h"
420d163575Sopenharmony_ci#ifdef LOSCFG_KERNEL_VDSO
430d163575Sopenharmony_ci#include "los_vdso.h"
440d163575Sopenharmony_ci#endif
450d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_VID
460d163575Sopenharmony_ci#include "vid_api.h"
470d163575Sopenharmony_ci#endif
480d163575Sopenharmony_ci#include "user_copy.h"
490d163575Sopenharmony_ci#include "los_process_pri.h"
500d163575Sopenharmony_ci#include "los_swtmr_pri.h"
510d163575Sopenharmony_ci#include "los_sys_pri.h"
520d163575Sopenharmony_ci
530d163575Sopenharmony_ci#define CPUCLOCK_PERTHREAD_MASK 4
540d163575Sopenharmony_ci#define CPUCLOCK_ID_OFFSET 3
550d163575Sopenharmony_ci
560d163575Sopenharmony_ci/*
570d163575Sopenharmony_ci * Do a time package defined return. This requires the error code
580d163575Sopenharmony_ci * to be placed in errno, and if it is non-zero, -1 returned as the
590d163575Sopenharmony_ci * result of the function. This also gives us a place to put any
600d163575Sopenharmony_ci * generic tidyup handling needed for things like signal delivery and
610d163575Sopenharmony_ci * cancellation.
620d163575Sopenharmony_ci */
630d163575Sopenharmony_ci#define TIME_RETURN(err) do { \
640d163575Sopenharmony_ci    INT32 retVal = 0;         \
650d163575Sopenharmony_ci    if ((err) != 0) {         \
660d163575Sopenharmony_ci        retVal = -1;          \
670d163575Sopenharmony_ci        errno = (err);        \
680d163575Sopenharmony_ci    }                         \
690d163575Sopenharmony_ci    return retVal;            \
700d163575Sopenharmony_ci} while (0)
710d163575Sopenharmony_ci
720d163575Sopenharmony_ci#ifdef LOSCFG_AARCH64
730d163575Sopenharmony_ci/*
740d163575Sopenharmony_ci * This two structures originally didn't exit,
750d163575Sopenharmony_ci * they added by liteos to support 64bit interfaces on 32bit platform,
760d163575Sopenharmony_ci * in 64bit platform, timeval64 define to timeval which is platform adaptive.
770d163575Sopenharmony_ci */
780d163575Sopenharmony_ci#define timeval64 timeval
790d163575Sopenharmony_ci#define timespec64 timespec
800d163575Sopenharmony_ci#endif
810d163575Sopenharmony_ci
820d163575Sopenharmony_ciSTATIC INLINE BOOL ValidTimeval(const struct timeval *tv)
830d163575Sopenharmony_ci{
840d163575Sopenharmony_ci    /* Fail a NULL pointer */
850d163575Sopenharmony_ci    if (tv == NULL) {
860d163575Sopenharmony_ci        return FALSE;
870d163575Sopenharmony_ci    }
880d163575Sopenharmony_ci
890d163575Sopenharmony_ci    /* Fail illegal microseconds values */
900d163575Sopenharmony_ci    if ((tv->tv_usec < 0) || (tv->tv_usec >= OS_SYS_US_PER_SECOND) || (tv->tv_sec < 0)) {
910d163575Sopenharmony_ci        return FALSE;
920d163575Sopenharmony_ci    }
930d163575Sopenharmony_ci
940d163575Sopenharmony_ci    return TRUE;
950d163575Sopenharmony_ci}
960d163575Sopenharmony_ci
970d163575Sopenharmony_ciSTATIC INLINE BOOL ValidTimeval64(const struct timeval64 *tv)
980d163575Sopenharmony_ci{
990d163575Sopenharmony_ci    /* Fail a NULL pointer */
1000d163575Sopenharmony_ci    if (tv == NULL) {
1010d163575Sopenharmony_ci        return FALSE;
1020d163575Sopenharmony_ci    }
1030d163575Sopenharmony_ci
1040d163575Sopenharmony_ci    /* Fail illegal microseconds values */
1050d163575Sopenharmony_ci    if ((tv->tv_usec < 0) || (tv->tv_usec >= OS_SYS_US_PER_SECOND) || (tv->tv_sec < 0)) {
1060d163575Sopenharmony_ci        return FALSE;
1070d163575Sopenharmony_ci    }
1080d163575Sopenharmony_ci
1090d163575Sopenharmony_ci    return TRUE;
1100d163575Sopenharmony_ci}
1110d163575Sopenharmony_ci
1120d163575Sopenharmony_ciSTATIC INLINE BOOL ValidTimerID(UINT16 swtmrID)
1130d163575Sopenharmony_ci{
1140d163575Sopenharmony_ci    /* check timer id */
1150d163575Sopenharmony_ci    if (swtmrID >= OS_SWTMR_MAX_TIMERID) {
1160d163575Sopenharmony_ci        return FALSE;
1170d163575Sopenharmony_ci    }
1180d163575Sopenharmony_ci
1190d163575Sopenharmony_ci    /* check owner of this timer */
1200d163575Sopenharmony_ci    if (OS_SWT_FROM_SID(swtmrID)->uwOwnerPid != (UINTPTR)OsCurrProcessGet()) {
1210d163575Sopenharmony_ci        return FALSE;
1220d163575Sopenharmony_ci    }
1230d163575Sopenharmony_ci
1240d163575Sopenharmony_ci    return TRUE;
1250d163575Sopenharmony_ci}
1260d163575Sopenharmony_ci
1270d163575Sopenharmony_ciSTATIC SPIN_LOCK_INIT(g_timeSpin);
1280d163575Sopenharmony_ciSTATIC long long g_adjTimeLeft; /* absolute value of adjtime */
1290d163575Sopenharmony_ciSTATIC INT32 g_adjDirection;    /* 1, speed up; 0, slow down; */
1300d163575Sopenharmony_ci
1310d163575Sopenharmony_ci/* Adjust pacement, nanoseconds per SCHED_CLOCK_INTETRVAL_TICKS ticks */
1320d163575Sopenharmony_ciSTATIC const long long g_adjPacement = (((LOSCFG_BASE_CORE_ADJ_PER_SECOND * SCHED_CLOCK_INTETRVAL_TICKS) /
1330d163575Sopenharmony_ci                                        LOSCFG_BASE_CORE_TICK_PER_SECOND) * OS_SYS_NS_PER_US);
1340d163575Sopenharmony_ci
1350d163575Sopenharmony_ci/* accumulative time delta from continuous modify, such as adjtime */
1360d163575Sopenharmony_ciSTATIC struct timespec64 g_accDeltaFromAdj;
1370d163575Sopenharmony_ci/* accumulative time delta from discontinuous modify, such as settimeofday */
1380d163575Sopenharmony_ciSTATIC struct timespec64 g_accDeltaFromSet;
1390d163575Sopenharmony_ci
1400d163575Sopenharmony_ciVOID OsAdjTime(VOID)
1410d163575Sopenharmony_ci{
1420d163575Sopenharmony_ci    UINT32 intSave;
1430d163575Sopenharmony_ci
1440d163575Sopenharmony_ci    LOS_SpinLockSave(&g_timeSpin, &intSave);
1450d163575Sopenharmony_ci    if (!g_adjTimeLeft) {
1460d163575Sopenharmony_ci        LOS_SpinUnlockRestore(&g_timeSpin, intSave);
1470d163575Sopenharmony_ci        return;
1480d163575Sopenharmony_ci    }
1490d163575Sopenharmony_ci
1500d163575Sopenharmony_ci    if (g_adjTimeLeft > g_adjPacement) {
1510d163575Sopenharmony_ci        if (g_adjDirection) {
1520d163575Sopenharmony_ci            if ((g_accDeltaFromAdj.tv_nsec + g_adjPacement) >= OS_SYS_NS_PER_SECOND) {
1530d163575Sopenharmony_ci                g_accDeltaFromAdj.tv_sec++;
1540d163575Sopenharmony_ci                g_accDeltaFromAdj.tv_nsec  = (g_accDeltaFromAdj.tv_nsec + g_adjPacement) % OS_SYS_NS_PER_SECOND;
1550d163575Sopenharmony_ci            } else {
1560d163575Sopenharmony_ci                g_accDeltaFromAdj.tv_nsec  = g_accDeltaFromAdj.tv_nsec + g_adjPacement;
1570d163575Sopenharmony_ci            }
1580d163575Sopenharmony_ci        } else {
1590d163575Sopenharmony_ci            if ((g_accDeltaFromAdj.tv_nsec - g_adjPacement) < 0) {
1600d163575Sopenharmony_ci                g_accDeltaFromAdj.tv_sec--;
1610d163575Sopenharmony_ci                g_accDeltaFromAdj.tv_nsec  = g_accDeltaFromAdj.tv_nsec - g_adjPacement + OS_SYS_NS_PER_SECOND;
1620d163575Sopenharmony_ci            } else {
1630d163575Sopenharmony_ci                g_accDeltaFromAdj.tv_nsec  = g_accDeltaFromAdj.tv_nsec - g_adjPacement;
1640d163575Sopenharmony_ci            }
1650d163575Sopenharmony_ci        }
1660d163575Sopenharmony_ci
1670d163575Sopenharmony_ci        g_adjTimeLeft -= g_adjPacement;
1680d163575Sopenharmony_ci    } else {
1690d163575Sopenharmony_ci        if (g_adjDirection) {
1700d163575Sopenharmony_ci            if ((g_accDeltaFromAdj.tv_nsec + g_adjTimeLeft) >= OS_SYS_NS_PER_SECOND) {
1710d163575Sopenharmony_ci                g_accDeltaFromAdj.tv_sec++;
1720d163575Sopenharmony_ci                g_accDeltaFromAdj.tv_nsec  = (g_accDeltaFromAdj.tv_nsec + g_adjTimeLeft) % OS_SYS_NS_PER_SECOND;
1730d163575Sopenharmony_ci            } else {
1740d163575Sopenharmony_ci                g_accDeltaFromAdj.tv_nsec  = g_accDeltaFromAdj.tv_nsec + g_adjTimeLeft;
1750d163575Sopenharmony_ci            }
1760d163575Sopenharmony_ci        } else {
1770d163575Sopenharmony_ci            if ((g_accDeltaFromAdj.tv_nsec - g_adjTimeLeft) < 0) {
1780d163575Sopenharmony_ci                g_accDeltaFromAdj.tv_sec--;
1790d163575Sopenharmony_ci                g_accDeltaFromAdj.tv_nsec  = g_accDeltaFromAdj.tv_nsec - g_adjTimeLeft + OS_SYS_NS_PER_SECOND;
1800d163575Sopenharmony_ci            } else {
1810d163575Sopenharmony_ci                g_accDeltaFromAdj.tv_nsec  = g_accDeltaFromAdj.tv_nsec - g_adjTimeLeft;
1820d163575Sopenharmony_ci            }
1830d163575Sopenharmony_ci        }
1840d163575Sopenharmony_ci
1850d163575Sopenharmony_ci        g_adjTimeLeft = 0;
1860d163575Sopenharmony_ci    }
1870d163575Sopenharmony_ci    LOS_SpinUnlockRestore(&g_timeSpin, intSave);
1880d163575Sopenharmony_ci    return;
1890d163575Sopenharmony_ci}
1900d163575Sopenharmony_ci
1910d163575Sopenharmony_ci/*
1920d163575Sopenharmony_ci * Function: adjtime
1930d163575Sopenharmony_ci * Description:  correct the time to synchronize the system clock.
1940d163575Sopenharmony_ci * Input:     delta - The amount of time by which the clock is to be adjusted.
1950d163575Sopenharmony_ci * Output: oldDelta - the amount of time remaining from any previous adjustment that has not yet been completed.
1960d163575Sopenharmony_ci * Return: On success, returns 0.  On failure, -1 is returned, and errno is set to indicate the error.
1970d163575Sopenharmony_ci */
1980d163575Sopenharmony_ciint adjtime(const struct timeval *delta, struct timeval *oldDelta)
1990d163575Sopenharmony_ci{
2000d163575Sopenharmony_ci    UINT32 intSave;
2010d163575Sopenharmony_ci    LOS_SpinLockSave(&g_timeSpin, &intSave);
2020d163575Sopenharmony_ci    /* return the amount of time remaining from any previous adjustment that has not yet been completed. */
2030d163575Sopenharmony_ci    if (oldDelta != NULL) {
2040d163575Sopenharmony_ci        if (g_adjDirection == 1) {
2050d163575Sopenharmony_ci            oldDelta->tv_sec = g_adjTimeLeft / OS_SYS_NS_PER_SECOND;
2060d163575Sopenharmony_ci            oldDelta->tv_usec = (g_adjTimeLeft % OS_SYS_NS_PER_SECOND) / OS_SYS_NS_PER_US;
2070d163575Sopenharmony_ci        } else {
2080d163575Sopenharmony_ci            oldDelta->tv_sec = -(g_adjTimeLeft / OS_SYS_NS_PER_SECOND);
2090d163575Sopenharmony_ci            oldDelta->tv_usec = -((g_adjTimeLeft % OS_SYS_NS_PER_SECOND) / OS_SYS_NS_PER_US);
2100d163575Sopenharmony_ci        }
2110d163575Sopenharmony_ci    }
2120d163575Sopenharmony_ci
2130d163575Sopenharmony_ci    if ((delta == NULL) || ((delta->tv_sec == 0) && (delta->tv_usec == 0))) {
2140d163575Sopenharmony_ci        LOS_SpinUnlockRestore(&g_timeSpin, intSave);
2150d163575Sopenharmony_ci        return 0;
2160d163575Sopenharmony_ci    }
2170d163575Sopenharmony_ci
2180d163575Sopenharmony_ci    if ((delta->tv_usec > OS_SYS_US_PER_SECOND) || (delta->tv_usec < -OS_SYS_US_PER_SECOND)) {
2190d163575Sopenharmony_ci        LOS_SpinUnlockRestore(&g_timeSpin, intSave);
2200d163575Sopenharmony_ci        TIME_RETURN(EINVAL);
2210d163575Sopenharmony_ci    }
2220d163575Sopenharmony_ci
2230d163575Sopenharmony_ci    /*
2240d163575Sopenharmony_ci     * 2: in the glibc implementation, delta must be less than or equal to (INT_MAX / 1000000 - 2) and
2250d163575Sopenharmony_ci     * greater than or equal to (INT_MIN / 1000000 + 2)
2260d163575Sopenharmony_ci     */
2270d163575Sopenharmony_ci    if ((delta->tv_sec < (INT_MIN / OS_SYS_US_PER_SECOND + 2)) ||
2280d163575Sopenharmony_ci        (delta->tv_sec > (INT_MAX / OS_SYS_US_PER_SECOND + 2))) {
2290d163575Sopenharmony_ci        LOS_SpinUnlockRestore(&g_timeSpin, intSave);
2300d163575Sopenharmony_ci        TIME_RETURN(EINVAL);
2310d163575Sopenharmony_ci    }
2320d163575Sopenharmony_ci
2330d163575Sopenharmony_ci    g_adjTimeLeft = (INT64)delta->tv_sec * OS_SYS_NS_PER_SECOND + delta->tv_usec * OS_SYS_NS_PER_US;
2340d163575Sopenharmony_ci    if (g_adjTimeLeft > 0) {
2350d163575Sopenharmony_ci        g_adjDirection = 1;
2360d163575Sopenharmony_ci    } else {
2370d163575Sopenharmony_ci        g_adjDirection = 0;
2380d163575Sopenharmony_ci        g_adjTimeLeft = -g_adjTimeLeft;
2390d163575Sopenharmony_ci    }
2400d163575Sopenharmony_ci
2410d163575Sopenharmony_ci    LOS_SpinUnlockRestore(&g_timeSpin, intSave);
2420d163575Sopenharmony_ci    return 0;
2430d163575Sopenharmony_ci}
2440d163575Sopenharmony_ci
2450d163575Sopenharmony_ciSTATIC INLINE struct timespec64 OsTimeSpecAdd(const struct timespec64 t1, const struct timespec64 t2)
2460d163575Sopenharmony_ci{
2470d163575Sopenharmony_ci    struct timespec64 ret = {0};
2480d163575Sopenharmony_ci
2490d163575Sopenharmony_ci    ret.tv_sec = t1.tv_sec + t2.tv_sec;
2500d163575Sopenharmony_ci    ret.tv_nsec = t1.tv_nsec + t2.tv_nsec;
2510d163575Sopenharmony_ci    if (ret.tv_nsec >= OS_SYS_NS_PER_SECOND) {
2520d163575Sopenharmony_ci        ret.tv_sec += 1;
2530d163575Sopenharmony_ci        ret.tv_nsec -= OS_SYS_NS_PER_SECOND;
2540d163575Sopenharmony_ci    } else if (ret.tv_nsec < 0L) {
2550d163575Sopenharmony_ci        ret.tv_sec -= 1;
2560d163575Sopenharmony_ci        ret.tv_nsec += OS_SYS_NS_PER_SECOND;
2570d163575Sopenharmony_ci    }
2580d163575Sopenharmony_ci
2590d163575Sopenharmony_ci    return ret;
2600d163575Sopenharmony_ci}
2610d163575Sopenharmony_ci
2620d163575Sopenharmony_ciSTATIC INLINE struct timespec64 OsTimeSpecSub(const struct timespec64 t1, const struct timespec64 t2)
2630d163575Sopenharmony_ci{
2640d163575Sopenharmony_ci    struct timespec64 ret = {0};
2650d163575Sopenharmony_ci
2660d163575Sopenharmony_ci    ret.tv_sec = t1.tv_sec - t2.tv_sec;
2670d163575Sopenharmony_ci    ret.tv_nsec = t1.tv_nsec - t2.tv_nsec;
2680d163575Sopenharmony_ci    if (ret.tv_nsec < 0) {
2690d163575Sopenharmony_ci        ret.tv_sec -= 1;
2700d163575Sopenharmony_ci        ret.tv_nsec += OS_SYS_NS_PER_SECOND;
2710d163575Sopenharmony_ci    }
2720d163575Sopenharmony_ci
2730d163575Sopenharmony_ci    return ret;
2740d163575Sopenharmony_ci}
2750d163575Sopenharmony_ci
2760d163575Sopenharmony_ciSTATIC VOID OsGetHwTime(struct timespec64 *hwTime)
2770d163575Sopenharmony_ci{
2780d163575Sopenharmony_ci    UINT64 nowNsec;
2790d163575Sopenharmony_ci
2800d163575Sopenharmony_ci    nowNsec = LOS_CurrNanosec();
2810d163575Sopenharmony_ci    hwTime->tv_sec = nowNsec / OS_SYS_NS_PER_SECOND;
2820d163575Sopenharmony_ci    hwTime->tv_nsec = nowNsec - hwTime->tv_sec * OS_SYS_NS_PER_SECOND;
2830d163575Sopenharmony_ci}
2840d163575Sopenharmony_ci
2850d163575Sopenharmony_ciSTATIC INT32 OsSetTimeOfDay(const struct timeval64 *tv, const struct timezone *tz)
2860d163575Sopenharmony_ci{
2870d163575Sopenharmony_ci    UINT32 intSave;
2880d163575Sopenharmony_ci    struct timespec64 setTime = {0};
2890d163575Sopenharmony_ci    struct timespec64 hwTime = {0};
2900d163575Sopenharmony_ci    struct timespec64 realTime = {0};
2910d163575Sopenharmony_ci    struct timespec64 tmp = {0};
2920d163575Sopenharmony_ci
2930d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_CAPABILITY
2940d163575Sopenharmony_ci    if (!IsCapPermit(CAP_SET_TIMEOFDAY)) {
2950d163575Sopenharmony_ci        TIME_RETURN(EPERM);
2960d163575Sopenharmony_ci    }
2970d163575Sopenharmony_ci#endif
2980d163575Sopenharmony_ci
2990d163575Sopenharmony_ci    (VOID)tz;
3000d163575Sopenharmony_ci    OsGetHwTime(&hwTime);
3010d163575Sopenharmony_ci    setTime.tv_sec = tv->tv_sec;
3020d163575Sopenharmony_ci    setTime.tv_nsec = tv->tv_usec * OS_SYS_NS_PER_US;
3030d163575Sopenharmony_ci
3040d163575Sopenharmony_ci    LOS_SpinLockSave(&g_timeSpin, &intSave);
3050d163575Sopenharmony_ci    /* stop on-going continuous adjusement */
3060d163575Sopenharmony_ci    if (g_adjTimeLeft) {
3070d163575Sopenharmony_ci        g_adjTimeLeft = 0;
3080d163575Sopenharmony_ci    }
3090d163575Sopenharmony_ci    realTime = OsTimeSpecAdd(hwTime, g_accDeltaFromAdj);
3100d163575Sopenharmony_ci    realTime = OsTimeSpecAdd(realTime, g_accDeltaFromSet);
3110d163575Sopenharmony_ci
3120d163575Sopenharmony_ci    tmp = OsTimeSpecSub(setTime, realTime);
3130d163575Sopenharmony_ci    g_accDeltaFromSet = OsTimeSpecAdd(g_accDeltaFromSet, tmp);
3140d163575Sopenharmony_ci
3150d163575Sopenharmony_ci    LOS_SpinUnlockRestore(&g_timeSpin, intSave);
3160d163575Sopenharmony_ci
3170d163575Sopenharmony_ci    return 0;
3180d163575Sopenharmony_ci}
3190d163575Sopenharmony_ci
3200d163575Sopenharmony_ciint settimeofday(const struct timeval *tv, const struct timezone *tz)
3210d163575Sopenharmony_ci{
3220d163575Sopenharmony_ci    struct timeval64 stTimeVal64 = {0};
3230d163575Sopenharmony_ci
3240d163575Sopenharmony_ci    if (!ValidTimeval(tv)) {
3250d163575Sopenharmony_ci        TIME_RETURN(EINVAL);
3260d163575Sopenharmony_ci    }
3270d163575Sopenharmony_ci
3280d163575Sopenharmony_ci    stTimeVal64.tv_sec = tv->tv_sec;
3290d163575Sopenharmony_ci    stTimeVal64.tv_usec = tv->tv_usec;
3300d163575Sopenharmony_ci
3310d163575Sopenharmony_ci    return OsSetTimeOfDay(&stTimeVal64, tz);
3320d163575Sopenharmony_ci}
3330d163575Sopenharmony_ci
3340d163575Sopenharmony_ci#ifndef LOSCFG_AARCH64
3350d163575Sopenharmony_ciint settimeofday64(const struct timeval64 *tv, const struct timezone *tz)
3360d163575Sopenharmony_ci{
3370d163575Sopenharmony_ci    if (!ValidTimeval64(tv)) {
3380d163575Sopenharmony_ci        TIME_RETURN(EINVAL);
3390d163575Sopenharmony_ci    }
3400d163575Sopenharmony_ci
3410d163575Sopenharmony_ci    return OsSetTimeOfDay(tv, tz);
3420d163575Sopenharmony_ci}
3430d163575Sopenharmony_ci#endif
3440d163575Sopenharmony_ci
3450d163575Sopenharmony_ciint setlocalseconds(int seconds)
3460d163575Sopenharmony_ci{
3470d163575Sopenharmony_ci    struct timeval tv = {0};
3480d163575Sopenharmony_ci
3490d163575Sopenharmony_ci    tv.tv_sec = seconds;
3500d163575Sopenharmony_ci    tv.tv_usec = 0;
3510d163575Sopenharmony_ci
3520d163575Sopenharmony_ci    return settimeofday(&tv, NULL);
3530d163575Sopenharmony_ci}
3540d163575Sopenharmony_ci
3550d163575Sopenharmony_ciSTATIC INT32 OsGetTimeOfDay(struct timeval64 *tv, struct timezone *tz)
3560d163575Sopenharmony_ci{
3570d163575Sopenharmony_ci    UINT32 intSave;
3580d163575Sopenharmony_ci
3590d163575Sopenharmony_ci    (VOID)tz;
3600d163575Sopenharmony_ci    struct timespec64 hwTime = {0};
3610d163575Sopenharmony_ci    struct timespec64 realTime = {0};
3620d163575Sopenharmony_ci
3630d163575Sopenharmony_ci    OsGetHwTime(&hwTime);
3640d163575Sopenharmony_ci
3650d163575Sopenharmony_ci    LOS_SpinLockSave(&g_timeSpin, &intSave);
3660d163575Sopenharmony_ci    realTime = OsTimeSpecAdd(hwTime, g_accDeltaFromAdj);
3670d163575Sopenharmony_ci    realTime = OsTimeSpecAdd(realTime, g_accDeltaFromSet);
3680d163575Sopenharmony_ci    LOS_SpinUnlockRestore(&g_timeSpin, intSave);
3690d163575Sopenharmony_ci
3700d163575Sopenharmony_ci    tv->tv_sec = realTime.tv_sec;
3710d163575Sopenharmony_ci    tv->tv_usec = realTime.tv_nsec / OS_SYS_NS_PER_US;
3720d163575Sopenharmony_ci
3730d163575Sopenharmony_ci    if (tv->tv_sec < 0) {
3740d163575Sopenharmony_ci        TIME_RETURN(EINVAL);
3750d163575Sopenharmony_ci    }
3760d163575Sopenharmony_ci    return 0;
3770d163575Sopenharmony_ci}
3780d163575Sopenharmony_ci
3790d163575Sopenharmony_ci#ifndef LOSCFG_AARCH64
3800d163575Sopenharmony_ciint gettimeofday64(struct timeval64 *tv, struct timezone *tz)
3810d163575Sopenharmony_ci{
3820d163575Sopenharmony_ci    if (tv == NULL) {
3830d163575Sopenharmony_ci        TIME_RETURN(EINVAL);
3840d163575Sopenharmony_ci    }
3850d163575Sopenharmony_ci
3860d163575Sopenharmony_ci    return OsGetTimeOfDay(tv, tz);
3870d163575Sopenharmony_ci}
3880d163575Sopenharmony_ci#endif
3890d163575Sopenharmony_ci
3900d163575Sopenharmony_ci#ifdef LOSCFG_LIBC_NEWLIB
3910d163575Sopenharmony_ciint gettimeofday(struct timeval *tv, void *_tz)
3920d163575Sopenharmony_ci#else
3930d163575Sopenharmony_ciint gettimeofday(struct timeval *tv, struct timezone *tz)
3940d163575Sopenharmony_ci#endif
3950d163575Sopenharmony_ci{
3960d163575Sopenharmony_ci    struct timeval64 stTimeVal64 = {0};
3970d163575Sopenharmony_ci#ifdef LOSCFG_LIBC_NEWLIB
3980d163575Sopenharmony_ci    struct timezone *tz = (struct timezone *)_tz;
3990d163575Sopenharmony_ci#endif
4000d163575Sopenharmony_ci
4010d163575Sopenharmony_ci    if (tv == NULL) {
4020d163575Sopenharmony_ci        TIME_RETURN(EINVAL);
4030d163575Sopenharmony_ci    }
4040d163575Sopenharmony_ci
4050d163575Sopenharmony_ci    if (OsGetTimeOfDay(&stTimeVal64, tz) == -1) {
4060d163575Sopenharmony_ci        return -1;
4070d163575Sopenharmony_ci    }
4080d163575Sopenharmony_ci
4090d163575Sopenharmony_ci#ifdef LOSCFG_AARCH64
4100d163575Sopenharmony_ci    tv->tv_sec = stTimeVal64.tv_sec;
4110d163575Sopenharmony_ci    tv->tv_usec = stTimeVal64.tv_usec;
4120d163575Sopenharmony_ci#else
4130d163575Sopenharmony_ci    if (stTimeVal64.tv_sec > (long long)LONG_MAX) {
4140d163575Sopenharmony_ci        return -1;
4150d163575Sopenharmony_ci    }
4160d163575Sopenharmony_ci    tv->tv_sec = (time_t)stTimeVal64.tv_sec;
4170d163575Sopenharmony_ci    tv->tv_usec = (suseconds_t)stTimeVal64.tv_usec;
4180d163575Sopenharmony_ci#endif
4190d163575Sopenharmony_ci
4200d163575Sopenharmony_ci    return 0;
4210d163575Sopenharmony_ci}
4220d163575Sopenharmony_ci
4230d163575Sopenharmony_ciint clock_settime(clockid_t clockID, const struct timespec *tp)
4240d163575Sopenharmony_ci{
4250d163575Sopenharmony_ci    struct timeval tv = {0};
4260d163575Sopenharmony_ci
4270d163575Sopenharmony_ci    switch (clockID) {
4280d163575Sopenharmony_ci        case CLOCK_REALTIME:
4290d163575Sopenharmony_ci            /* we only support the realtime clock currently */
4300d163575Sopenharmony_ci            break;
4310d163575Sopenharmony_ci        case CLOCK_MONOTONIC_COARSE:
4320d163575Sopenharmony_ci        case CLOCK_REALTIME_COARSE:
4330d163575Sopenharmony_ci        case CLOCK_MONOTONIC_RAW:
4340d163575Sopenharmony_ci        case CLOCK_PROCESS_CPUTIME_ID:
4350d163575Sopenharmony_ci        case CLOCK_BOOTTIME:
4360d163575Sopenharmony_ci        case CLOCK_REALTIME_ALARM:
4370d163575Sopenharmony_ci        case CLOCK_BOOTTIME_ALARM:
4380d163575Sopenharmony_ci        case CLOCK_TAI:
4390d163575Sopenharmony_ci        case CLOCK_THREAD_CPUTIME_ID:
4400d163575Sopenharmony_ci            TIME_RETURN(ENOTSUP);
4410d163575Sopenharmony_ci        case CLOCK_MONOTONIC:
4420d163575Sopenharmony_ci        default:
4430d163575Sopenharmony_ci            TIME_RETURN(EINVAL);
4440d163575Sopenharmony_ci    }
4450d163575Sopenharmony_ci
4460d163575Sopenharmony_ci    if (!ValidTimeSpec(tp)) {
4470d163575Sopenharmony_ci        TIME_RETURN(EINVAL);
4480d163575Sopenharmony_ci    }
4490d163575Sopenharmony_ci
4500d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_CAPABILITY
4510d163575Sopenharmony_ci    if (!IsCapPermit(CAP_CLOCK_SETTIME)) {
4520d163575Sopenharmony_ci        TIME_RETURN(EPERM);
4530d163575Sopenharmony_ci    }
4540d163575Sopenharmony_ci#endif
4550d163575Sopenharmony_ci
4560d163575Sopenharmony_ci    tv.tv_sec = tp->tv_sec;
4570d163575Sopenharmony_ci    tv.tv_usec = tp->tv_nsec / OS_SYS_NS_PER_US;
4580d163575Sopenharmony_ci    return settimeofday(&tv, NULL);
4590d163575Sopenharmony_ci}
4600d163575Sopenharmony_ci
4610d163575Sopenharmony_ci#ifdef LOSCFG_KERNEL_CPUP
4620d163575Sopenharmony_ciinline UINT32 GetTidFromClockID(clockid_t clockID)
4630d163575Sopenharmony_ci{
4640d163575Sopenharmony_ci    // In musl/src/thread/pthread_getcpuclockid.c, we know 'clockid = (-tid - 1) * 8 + 6'
4650d163575Sopenharmony_ci    UINT32 tid = -(clockID - 6) / 8 - 1; // 6 8 1 inverse operation from clockID to tid
4660d163575Sopenharmony_ci    return tid;
4670d163575Sopenharmony_ci}
4680d163575Sopenharmony_ci
4690d163575Sopenharmony_ciinline const pid_t GetPidFromClockID(clockid_t clockID)
4700d163575Sopenharmony_ci{
4710d163575Sopenharmony_ci    // In musl/src/time/clock_getcpuclockid.c, we know 'clockid = (-pid - 1) * 8 + 2'
4720d163575Sopenharmony_ci    const pid_t pid = -(clockID - 2) / 8 - 1; // 2 8 1 inverse operation from clockID to pid
4730d163575Sopenharmony_ci    return pid;
4740d163575Sopenharmony_ci}
4750d163575Sopenharmony_ci
4760d163575Sopenharmony_cistatic int PthreadGetCputime(clockid_t clockID, struct timespec *ats)
4770d163575Sopenharmony_ci{
4780d163575Sopenharmony_ci    uint64_t runtime;
4790d163575Sopenharmony_ci    UINT32 intSave;
4800d163575Sopenharmony_ci    UINT32 tid = GetTidFromClockID(clockID);
4810d163575Sopenharmony_ci    if (OS_TID_CHECK_INVALID(tid)) {
4820d163575Sopenharmony_ci        return -EINVAL;
4830d163575Sopenharmony_ci    }
4840d163575Sopenharmony_ci
4850d163575Sopenharmony_ci    LosTaskCB *task = OsGetTaskCB(tid);
4860d163575Sopenharmony_ci
4870d163575Sopenharmony_ci    if (OsCurrTaskGet()->processCB != task->processCB) {
4880d163575Sopenharmony_ci        return -EINVAL;
4890d163575Sopenharmony_ci    }
4900d163575Sopenharmony_ci
4910d163575Sopenharmony_ci    SCHEDULER_LOCK(intSave);
4920d163575Sopenharmony_ci    runtime = task->taskCpup.allTime;
4930d163575Sopenharmony_ci    SCHEDULER_UNLOCK(intSave);
4940d163575Sopenharmony_ci
4950d163575Sopenharmony_ci    ats->tv_sec = runtime / OS_SYS_NS_PER_SECOND;
4960d163575Sopenharmony_ci    ats->tv_nsec = runtime % OS_SYS_NS_PER_SECOND;
4970d163575Sopenharmony_ci
4980d163575Sopenharmony_ci    return 0;
4990d163575Sopenharmony_ci}
5000d163575Sopenharmony_ci
5010d163575Sopenharmony_cistatic int ProcessGetCputime(clockid_t clockID, struct timespec *ats)
5020d163575Sopenharmony_ci{
5030d163575Sopenharmony_ci    UINT64 runtime;
5040d163575Sopenharmony_ci    UINT32 intSave;
5050d163575Sopenharmony_ci    const pid_t pid = GetPidFromClockID(clockID);
5060d163575Sopenharmony_ci    LosProcessCB *spcb = NULL;
5070d163575Sopenharmony_ci
5080d163575Sopenharmony_ci    if (OsProcessIDUserCheckInvalid(pid) || pid < 0) {
5090d163575Sopenharmony_ci        return -EINVAL;
5100d163575Sopenharmony_ci    }
5110d163575Sopenharmony_ci
5120d163575Sopenharmony_ci    spcb = OS_PCB_FROM_PID(pid);
5130d163575Sopenharmony_ci    if (OsProcessIsUnused(spcb)) {
5140d163575Sopenharmony_ci        return -EINVAL;
5150d163575Sopenharmony_ci    }
5160d163575Sopenharmony_ci
5170d163575Sopenharmony_ci    SCHEDULER_LOCK(intSave);
5180d163575Sopenharmony_ci    if (spcb->processCpup == NULL) {
5190d163575Sopenharmony_ci        SCHEDULER_UNLOCK(intSave);
5200d163575Sopenharmony_ci        return -EINVAL;
5210d163575Sopenharmony_ci    }
5220d163575Sopenharmony_ci    runtime = spcb->processCpup->allTime;
5230d163575Sopenharmony_ci    SCHEDULER_UNLOCK(intSave);
5240d163575Sopenharmony_ci
5250d163575Sopenharmony_ci    ats->tv_sec = runtime / OS_SYS_NS_PER_SECOND;
5260d163575Sopenharmony_ci    ats->tv_nsec = runtime % OS_SYS_NS_PER_SECOND;
5270d163575Sopenharmony_ci
5280d163575Sopenharmony_ci    return 0;
5290d163575Sopenharmony_ci}
5300d163575Sopenharmony_ci
5310d163575Sopenharmony_cistatic int GetCputime(clockid_t clockID, struct timespec *tp)
5320d163575Sopenharmony_ci{
5330d163575Sopenharmony_ci    int ret;
5340d163575Sopenharmony_ci
5350d163575Sopenharmony_ci    if (clockID >= 0) {
5360d163575Sopenharmony_ci        return -EINVAL;
5370d163575Sopenharmony_ci    }
5380d163575Sopenharmony_ci
5390d163575Sopenharmony_ci    if ((UINT32)clockID & CPUCLOCK_PERTHREAD_MASK) {
5400d163575Sopenharmony_ci        ret = PthreadGetCputime(clockID, tp);
5410d163575Sopenharmony_ci    } else {
5420d163575Sopenharmony_ci        ret = ProcessGetCputime(clockID, tp);
5430d163575Sopenharmony_ci    }
5440d163575Sopenharmony_ci
5450d163575Sopenharmony_ci    return ret;
5460d163575Sopenharmony_ci}
5470d163575Sopenharmony_ci
5480d163575Sopenharmony_cistatic int CheckClock(const clockid_t clockID)
5490d163575Sopenharmony_ci{
5500d163575Sopenharmony_ci    int error = 0;
5510d163575Sopenharmony_ci    const pid_t pid = GetPidFromClockID(clockID);
5520d163575Sopenharmony_ci
5530d163575Sopenharmony_ci    if (!((UINT32)clockID & CPUCLOCK_PERTHREAD_MASK)) {
5540d163575Sopenharmony_ci        LosProcessCB *spcb = NULL;
5550d163575Sopenharmony_ci        if (OsProcessIDUserCheckInvalid(pid) || pid < 0) {
5560d163575Sopenharmony_ci            return -EINVAL;
5570d163575Sopenharmony_ci        }
5580d163575Sopenharmony_ci        spcb = OS_PCB_FROM_PID(pid);
5590d163575Sopenharmony_ci        if (OsProcessIsUnused(spcb)) {
5600d163575Sopenharmony_ci            error = -EINVAL;
5610d163575Sopenharmony_ci        }
5620d163575Sopenharmony_ci    } else {
5630d163575Sopenharmony_ci        error = -EINVAL;
5640d163575Sopenharmony_ci    }
5650d163575Sopenharmony_ci
5660d163575Sopenharmony_ci    return error;
5670d163575Sopenharmony_ci}
5680d163575Sopenharmony_ci
5690d163575Sopenharmony_cistatic int CpuClockGetres(const clockid_t clockID, struct timespec *tp)
5700d163575Sopenharmony_ci{
5710d163575Sopenharmony_ci    if (clockID > 0) {
5720d163575Sopenharmony_ci        return -EINVAL;
5730d163575Sopenharmony_ci    }
5740d163575Sopenharmony_ci
5750d163575Sopenharmony_ci    int error = CheckClock(clockID);
5760d163575Sopenharmony_ci    if (!error) {
5770d163575Sopenharmony_ci        error = ProcessGetCputime(clockID, tp);
5780d163575Sopenharmony_ci    }
5790d163575Sopenharmony_ci
5800d163575Sopenharmony_ci    return error;
5810d163575Sopenharmony_ci}
5820d163575Sopenharmony_ci#endif
5830d163575Sopenharmony_ci
5840d163575Sopenharmony_ciint clock_gettime(clockid_t clockID, struct timespec *tp)
5850d163575Sopenharmony_ci{
5860d163575Sopenharmony_ci    UINT32 intSave;
5870d163575Sopenharmony_ci    struct timespec64 tmp = {0};
5880d163575Sopenharmony_ci    struct timespec64 hwTime = {0};
5890d163575Sopenharmony_ci
5900d163575Sopenharmony_ci    if (clockID > MAX_CLOCKS) {
5910d163575Sopenharmony_ci        goto ERROUT;
5920d163575Sopenharmony_ci    }
5930d163575Sopenharmony_ci
5940d163575Sopenharmony_ci    if (tp == NULL) {
5950d163575Sopenharmony_ci        goto ERROUT;
5960d163575Sopenharmony_ci    }
5970d163575Sopenharmony_ci
5980d163575Sopenharmony_ci    OsGetHwTime(&hwTime);
5990d163575Sopenharmony_ci
6000d163575Sopenharmony_ci    switch (clockID) {
6010d163575Sopenharmony_ci        case CLOCK_MONOTONIC_RAW:
6020d163575Sopenharmony_ci#ifdef LOSCFG_TIME_CONTAINER
6030d163575Sopenharmony_ci            tmp = OsTimeSpecAdd(hwTime, CLOCK_MONOTONIC_TIME_BASE);
6040d163575Sopenharmony_ci            tp->tv_sec = tmp.tv_sec;
6050d163575Sopenharmony_ci            tp->tv_nsec = tmp.tv_nsec;
6060d163575Sopenharmony_ci#else
6070d163575Sopenharmony_ci            tp->tv_sec = hwTime.tv_sec;
6080d163575Sopenharmony_ci            tp->tv_nsec = hwTime.tv_nsec;
6090d163575Sopenharmony_ci#endif
6100d163575Sopenharmony_ci            break;
6110d163575Sopenharmony_ci        case CLOCK_MONOTONIC:
6120d163575Sopenharmony_ci            LOS_SpinLockSave(&g_timeSpin, &intSave);
6130d163575Sopenharmony_ci            tmp = OsTimeSpecAdd(hwTime, g_accDeltaFromAdj);
6140d163575Sopenharmony_ci            LOS_SpinUnlockRestore(&g_timeSpin, intSave);
6150d163575Sopenharmony_ci#ifdef LOSCFG_TIME_CONTAINER
6160d163575Sopenharmony_ci            tmp = OsTimeSpecAdd(tmp, CLOCK_MONOTONIC_TIME_BASE);
6170d163575Sopenharmony_ci#endif
6180d163575Sopenharmony_ci            tp->tv_sec = tmp.tv_sec;
6190d163575Sopenharmony_ci            tp->tv_nsec = tmp.tv_nsec;
6200d163575Sopenharmony_ci            break;
6210d163575Sopenharmony_ci        case CLOCK_REALTIME:
6220d163575Sopenharmony_ci            LOS_SpinLockSave(&g_timeSpin, &intSave);
6230d163575Sopenharmony_ci            tmp = OsTimeSpecAdd(hwTime, g_accDeltaFromAdj);
6240d163575Sopenharmony_ci            tmp = OsTimeSpecAdd(tmp, g_accDeltaFromSet);
6250d163575Sopenharmony_ci            LOS_SpinUnlockRestore(&g_timeSpin, intSave);
6260d163575Sopenharmony_ci            tp->tv_sec = tmp.tv_sec;
6270d163575Sopenharmony_ci            tp->tv_nsec = tmp.tv_nsec;
6280d163575Sopenharmony_ci            break;
6290d163575Sopenharmony_ci        case CLOCK_MONOTONIC_COARSE:
6300d163575Sopenharmony_ci        case CLOCK_REALTIME_COARSE:
6310d163575Sopenharmony_ci        case CLOCK_THREAD_CPUTIME_ID:
6320d163575Sopenharmony_ci        case CLOCK_PROCESS_CPUTIME_ID:
6330d163575Sopenharmony_ci        case CLOCK_BOOTTIME:
6340d163575Sopenharmony_ci        case CLOCK_REALTIME_ALARM:
6350d163575Sopenharmony_ci        case CLOCK_BOOTTIME_ALARM:
6360d163575Sopenharmony_ci        case CLOCK_TAI:
6370d163575Sopenharmony_ci            TIME_RETURN(ENOTSUP);
6380d163575Sopenharmony_ci        default:
6390d163575Sopenharmony_ci        {
6400d163575Sopenharmony_ci#ifdef LOSCFG_KERNEL_CPUP
6410d163575Sopenharmony_ci            int ret = GetCputime(clockID, tp);
6420d163575Sopenharmony_ci                TIME_RETURN(-ret);
6430d163575Sopenharmony_ci#else
6440d163575Sopenharmony_ci            TIME_RETURN(EINVAL);
6450d163575Sopenharmony_ci#endif
6460d163575Sopenharmony_ci        }
6470d163575Sopenharmony_ci    }
6480d163575Sopenharmony_ci
6490d163575Sopenharmony_ci    return 0;
6500d163575Sopenharmony_ci
6510d163575Sopenharmony_ciERROUT:
6520d163575Sopenharmony_ci    TIME_RETURN(EINVAL);
6530d163575Sopenharmony_ci}
6540d163575Sopenharmony_ci
6550d163575Sopenharmony_ciint clock_getres(clockid_t clockID, struct timespec *tp)
6560d163575Sopenharmony_ci{
6570d163575Sopenharmony_ci    if (tp == NULL) {
6580d163575Sopenharmony_ci        TIME_RETURN(EINVAL);
6590d163575Sopenharmony_ci    }
6600d163575Sopenharmony_ci
6610d163575Sopenharmony_ci    switch (clockID) {
6620d163575Sopenharmony_ci        case CLOCK_MONOTONIC_RAW:
6630d163575Sopenharmony_ci        case CLOCK_MONOTONIC:
6640d163575Sopenharmony_ci        case CLOCK_REALTIME:
6650d163575Sopenharmony_ci            /* the accessible rtc resolution */
6660d163575Sopenharmony_ci            tp->tv_nsec = OS_SYS_NS_PER_US; /* the precision of clock_gettime is 1us */
6670d163575Sopenharmony_ci            tp->tv_sec = 0;
6680d163575Sopenharmony_ci            break;
6690d163575Sopenharmony_ci        case CLOCK_MONOTONIC_COARSE:
6700d163575Sopenharmony_ci        case CLOCK_REALTIME_COARSE:
6710d163575Sopenharmony_ci            /* the clock coarse resolution, supported by vdso.
6720d163575Sopenharmony_ci             * the precision of clock_gettime is 1tick */
6730d163575Sopenharmony_ci            tp->tv_nsec = OS_SYS_NS_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND;
6740d163575Sopenharmony_ci            tp->tv_sec = 0;
6750d163575Sopenharmony_ci            break;
6760d163575Sopenharmony_ci        case CLOCK_THREAD_CPUTIME_ID:
6770d163575Sopenharmony_ci        case CLOCK_PROCESS_CPUTIME_ID:
6780d163575Sopenharmony_ci        case CLOCK_BOOTTIME:
6790d163575Sopenharmony_ci        case CLOCK_REALTIME_ALARM:
6800d163575Sopenharmony_ci        case CLOCK_BOOTTIME_ALARM:
6810d163575Sopenharmony_ci        case CLOCK_TAI:
6820d163575Sopenharmony_ci            TIME_RETURN(ENOTSUP);
6830d163575Sopenharmony_ci        default:
6840d163575Sopenharmony_ci#ifdef LOSCFG_KERNEL_CPUP
6850d163575Sopenharmony_ci            {
6860d163575Sopenharmony_ci                int ret = CpuClockGetres(clockID, tp);
6870d163575Sopenharmony_ci                TIME_RETURN(-ret);
6880d163575Sopenharmony_ci            }
6890d163575Sopenharmony_ci#else
6900d163575Sopenharmony_ci            TIME_RETURN(EINVAL);
6910d163575Sopenharmony_ci#endif
6920d163575Sopenharmony_ci    }
6930d163575Sopenharmony_ci
6940d163575Sopenharmony_ci    TIME_RETURN(0);
6950d163575Sopenharmony_ci}
6960d163575Sopenharmony_ci
6970d163575Sopenharmony_ciint clock_nanosleep(clockid_t clk, int flags, const struct timespec *req, struct timespec *rem)
6980d163575Sopenharmony_ci{
6990d163575Sopenharmony_ci    switch (clk) {
7000d163575Sopenharmony_ci        case CLOCK_REALTIME:
7010d163575Sopenharmony_ci            if (flags == 0) {
7020d163575Sopenharmony_ci                /* we only support the realtime clock currently */
7030d163575Sopenharmony_ci                return nanosleep(req, rem);
7040d163575Sopenharmony_ci            }
7050d163575Sopenharmony_ci            /* fallthrough */
7060d163575Sopenharmony_ci        case CLOCK_MONOTONIC_COARSE:
7070d163575Sopenharmony_ci        case CLOCK_REALTIME_COARSE:
7080d163575Sopenharmony_ci        case CLOCK_MONOTONIC_RAW:
7090d163575Sopenharmony_ci        case CLOCK_MONOTONIC:
7100d163575Sopenharmony_ci        case CLOCK_PROCESS_CPUTIME_ID:
7110d163575Sopenharmony_ci        case CLOCK_BOOTTIME:
7120d163575Sopenharmony_ci        case CLOCK_REALTIME_ALARM:
7130d163575Sopenharmony_ci        case CLOCK_BOOTTIME_ALARM:
7140d163575Sopenharmony_ci        case CLOCK_TAI:
7150d163575Sopenharmony_ci            if (flags == 0 || flags == TIMER_ABSTIME) {
7160d163575Sopenharmony_ci                TIME_RETURN(ENOTSUP);
7170d163575Sopenharmony_ci            }
7180d163575Sopenharmony_ci            /* fallthrough */
7190d163575Sopenharmony_ci        case CLOCK_THREAD_CPUTIME_ID:
7200d163575Sopenharmony_ci        default:
7210d163575Sopenharmony_ci            TIME_RETURN(EINVAL);
7220d163575Sopenharmony_ci    }
7230d163575Sopenharmony_ci
7240d163575Sopenharmony_ci    TIME_RETURN(0);
7250d163575Sopenharmony_ci}
7260d163575Sopenharmony_ci
7270d163575Sopenharmony_citypedef struct {
7280d163575Sopenharmony_ci    int sigev_signo;
7290d163575Sopenharmony_ci    pid_t pid;
7300d163575Sopenharmony_ci    unsigned int tid;
7310d163575Sopenharmony_ci    union sigval sigev_value;
7320d163575Sopenharmony_ci} swtmr_proc_arg;
7330d163575Sopenharmony_ci
7340d163575Sopenharmony_cistatic VOID SwtmrProc(UINTPTR tmrArg)
7350d163575Sopenharmony_ci{
7360d163575Sopenharmony_ci#ifdef LOSCFG_KERNEL_VM
7370d163575Sopenharmony_ci    INT32 sig, ret;
7380d163575Sopenharmony_ci    UINT32 intSave;
7390d163575Sopenharmony_ci    pid_t pid;
7400d163575Sopenharmony_ci    siginfo_t info;
7410d163575Sopenharmony_ci    LosTaskCB *stcb = NULL;
7420d163575Sopenharmony_ci
7430d163575Sopenharmony_ci    swtmr_proc_arg *arg = (swtmr_proc_arg *)tmrArg;
7440d163575Sopenharmony_ci    OS_GOTO_EXIT_IF(arg == NULL, EINVAL);
7450d163575Sopenharmony_ci
7460d163575Sopenharmony_ci    sig = arg->sigev_signo;
7470d163575Sopenharmony_ci    pid = arg->pid;
7480d163575Sopenharmony_ci    OS_GOTO_EXIT_IF(!GOOD_SIGNO(sig), EINVAL);
7490d163575Sopenharmony_ci
7500d163575Sopenharmony_ci    /* Create the siginfo structure */
7510d163575Sopenharmony_ci    info.si_signo = sig;
7520d163575Sopenharmony_ci    info.si_code = SI_TIMER;
7530d163575Sopenharmony_ci    info.si_value.sival_ptr = arg->sigev_value.sival_ptr;
7540d163575Sopenharmony_ci
7550d163575Sopenharmony_ci    /* Send signals to threads or processes */
7560d163575Sopenharmony_ci    if (arg->tid > 0) {
7570d163575Sopenharmony_ci        /* Make sure that the para is valid */
7580d163575Sopenharmony_ci        OS_GOTO_EXIT_IF(OS_TID_CHECK_INVALID(arg->tid), EINVAL);
7590d163575Sopenharmony_ci        stcb = OsGetTaskCB(arg->tid);
7600d163575Sopenharmony_ci        ret = OsUserProcessOperatePermissionsCheck(stcb, stcb->processCB);
7610d163575Sopenharmony_ci        OS_GOTO_EXIT_IF(ret != LOS_OK, -ret);
7620d163575Sopenharmony_ci
7630d163575Sopenharmony_ci        /* Dispatch the signal to thread, bypassing normal task group thread
7640d163575Sopenharmony_ci         * dispatch rules. */
7650d163575Sopenharmony_ci        SCHEDULER_LOCK(intSave);
7660d163575Sopenharmony_ci        ret = OsTcbDispatch(stcb, &info);
7670d163575Sopenharmony_ci        SCHEDULER_UNLOCK(intSave);
7680d163575Sopenharmony_ci        OS_GOTO_EXIT_IF(ret != LOS_OK, -ret);
7690d163575Sopenharmony_ci    } else {
7700d163575Sopenharmony_ci        /* Make sure that the para is valid */
7710d163575Sopenharmony_ci        OS_GOTO_EXIT_IF(pid <= 0 || OS_PID_CHECK_INVALID(pid), EINVAL);
7720d163575Sopenharmony_ci        /* Dispatch the signal to process */
7730d163575Sopenharmony_ci        SCHEDULER_LOCK(intSave);
7740d163575Sopenharmony_ci        OsDispatch(pid, &info, OS_USER_KILL_PERMISSION);
7750d163575Sopenharmony_ci        SCHEDULER_UNLOCK(intSave);
7760d163575Sopenharmony_ci    }
7770d163575Sopenharmony_ci    return;
7780d163575Sopenharmony_ciEXIT:
7790d163575Sopenharmony_ci    PRINT_ERR("Dispatch signals failed!, ret: %d\r\n", ret);
7800d163575Sopenharmony_ci#endif
7810d163575Sopenharmony_ci    return;
7820d163575Sopenharmony_ci}
7830d163575Sopenharmony_ci
7840d163575Sopenharmony_ciint timer_create(clockid_t clockID, struct sigevent *restrict evp, timer_t *restrict timerID)
7850d163575Sopenharmony_ci{
7860d163575Sopenharmony_ci    UINT32 ret;
7870d163575Sopenharmony_ci    UINT16 swtmrID;
7880d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_VID
7890d163575Sopenharmony_ci    UINT16 vid;
7900d163575Sopenharmony_ci#endif
7910d163575Sopenharmony_ci
7920d163575Sopenharmony_ci    if (!timerID || (clockID != CLOCK_REALTIME) || !evp) {
7930d163575Sopenharmony_ci        errno = EINVAL;
7940d163575Sopenharmony_ci        return -1;
7950d163575Sopenharmony_ci    }
7960d163575Sopenharmony_ci
7970d163575Sopenharmony_ci    if ((evp->sigev_notify != SIGEV_THREAD) || evp->sigev_notify_attributes) {
7980d163575Sopenharmony_ci        errno = ENOTSUP;
7990d163575Sopenharmony_ci        return -1;
8000d163575Sopenharmony_ci    }
8010d163575Sopenharmony_ci
8020d163575Sopenharmony_ci    ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_ONCE, (SWTMR_PROC_FUNC)evp->sigev_notify_function,
8030d163575Sopenharmony_ci                          &swtmrID, (UINTPTR)evp->sigev_value.sival_ptr);
8040d163575Sopenharmony_ci    if (ret != LOS_OK) {
8050d163575Sopenharmony_ci        errno = (ret == LOS_ERRNO_SWTMR_MAXSIZE) ? EAGAIN : EINVAL;
8060d163575Sopenharmony_ci        return -1;
8070d163575Sopenharmony_ci    }
8080d163575Sopenharmony_ci
8090d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_VID
8100d163575Sopenharmony_ci    vid = AddNodeByRid(swtmrID);
8110d163575Sopenharmony_ci    if (vid == MAX_INVALID_TIMER_VID) {
8120d163575Sopenharmony_ci        (VOID)LOS_SwtmrDelete(swtmrID);
8130d163575Sopenharmony_ci        return -1;
8140d163575Sopenharmony_ci    }
8150d163575Sopenharmony_ci    swtmrID = vid;
8160d163575Sopenharmony_ci#endif
8170d163575Sopenharmony_ci    *timerID = (timer_t)(UINTPTR)swtmrID;
8180d163575Sopenharmony_ci    return 0;
8190d163575Sopenharmony_ci}
8200d163575Sopenharmony_ci
8210d163575Sopenharmony_ciint OsTimerCreate(clockid_t clockID, struct ksigevent *evp, timer_t *timerID)
8220d163575Sopenharmony_ci{
8230d163575Sopenharmony_ci    UINT32 ret;
8240d163575Sopenharmony_ci    UINT16 swtmrID;
8250d163575Sopenharmony_ci    swtmr_proc_arg *arg = NULL;
8260d163575Sopenharmony_ci    int signo;
8270d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_VID
8280d163575Sopenharmony_ci    UINT16 vid;
8290d163575Sopenharmony_ci#endif
8300d163575Sopenharmony_ci
8310d163575Sopenharmony_ci    if ((clockID != CLOCK_REALTIME) || (timerID == NULL)) {
8320d163575Sopenharmony_ci        errno = EINVAL;
8330d163575Sopenharmony_ci        return -1;
8340d163575Sopenharmony_ci    }
8350d163575Sopenharmony_ci
8360d163575Sopenharmony_ci    signo = evp ? evp->sigev_signo : SIGALRM;
8370d163575Sopenharmony_ci    if (signo > SIGRTMAX || signo < 1) {
8380d163575Sopenharmony_ci        errno = EINVAL;
8390d163575Sopenharmony_ci        return -1;
8400d163575Sopenharmony_ci    }
8410d163575Sopenharmony_ci    if (evp && (evp->sigev_notify != SIGEV_SIGNAL && evp->sigev_notify != SIGEV_THREAD_ID)) {
8420d163575Sopenharmony_ci        errno = ENOTSUP;
8430d163575Sopenharmony_ci        return -1;
8440d163575Sopenharmony_ci    }
8450d163575Sopenharmony_ci
8460d163575Sopenharmony_ci    arg = (swtmr_proc_arg *)malloc(sizeof(swtmr_proc_arg));
8470d163575Sopenharmony_ci    if (arg == NULL) {
8480d163575Sopenharmony_ci        errno = ENOMEM;
8490d163575Sopenharmony_ci        return -1;
8500d163575Sopenharmony_ci    }
8510d163575Sopenharmony_ci
8520d163575Sopenharmony_ci    arg->tid = evp ? evp->sigev_tid : 0;
8530d163575Sopenharmony_ci    arg->sigev_signo = signo;
8540d163575Sopenharmony_ci    arg->pid = LOS_GetCurrProcessID();
8550d163575Sopenharmony_ci    arg->sigev_value.sival_ptr = evp ? evp->sigev_value.sival_ptr : NULL;
8560d163575Sopenharmony_ci    ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_ONCE, SwtmrProc, &swtmrID, (UINTPTR)arg);
8570d163575Sopenharmony_ci    if (ret != LOS_OK) {
8580d163575Sopenharmony_ci        errno = (ret == LOS_ERRNO_SWTMR_MAXSIZE) ? EAGAIN : EINVAL;
8590d163575Sopenharmony_ci        free(arg);
8600d163575Sopenharmony_ci        return -1;
8610d163575Sopenharmony_ci    }
8620d163575Sopenharmony_ci
8630d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_VID
8640d163575Sopenharmony_ci    vid = AddNodeByRid(swtmrID);
8650d163575Sopenharmony_ci    if (vid == MAX_INVALID_TIMER_VID) {
8660d163575Sopenharmony_ci        free(arg);
8670d163575Sopenharmony_ci        (VOID)LOS_SwtmrDelete(swtmrID);
8680d163575Sopenharmony_ci        return -1;
8690d163575Sopenharmony_ci    }
8700d163575Sopenharmony_ci    swtmrID = vid;
8710d163575Sopenharmony_ci#endif
8720d163575Sopenharmony_ci    *timerID = (timer_t)(UINTPTR)swtmrID;
8730d163575Sopenharmony_ci    return 0;
8740d163575Sopenharmony_ci}
8750d163575Sopenharmony_ci
8760d163575Sopenharmony_ciint timer_delete(timer_t timerID)
8770d163575Sopenharmony_ci{
8780d163575Sopenharmony_ci    UINT16 swtmrID = (UINT16)(UINTPTR)timerID;
8790d163575Sopenharmony_ci    VOID *arg = NULL;
8800d163575Sopenharmony_ci    UINTPTR swtmrProc;
8810d163575Sopenharmony_ci
8820d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_VID
8830d163575Sopenharmony_ci    swtmrID = GetRidByVid(swtmrID);
8840d163575Sopenharmony_ci#endif
8850d163575Sopenharmony_ci    if (OS_INT_ACTIVE || !ValidTimerID(swtmrID)) {
8860d163575Sopenharmony_ci        goto ERROUT;
8870d163575Sopenharmony_ci    }
8880d163575Sopenharmony_ci
8890d163575Sopenharmony_ci    arg = (VOID *)OS_SWT_FROM_SID(swtmrID)->uwArg;
8900d163575Sopenharmony_ci    swtmrProc = (UINTPTR)OS_SWT_FROM_SID(swtmrID)->pfnHandler;
8910d163575Sopenharmony_ci    if (LOS_SwtmrDelete(swtmrID)) {
8920d163575Sopenharmony_ci        goto ERROUT;
8930d163575Sopenharmony_ci    }
8940d163575Sopenharmony_ci    if ((swtmrProc == (UINTPTR)SwtmrProc) && (arg != NULL)) {
8950d163575Sopenharmony_ci        free(arg);
8960d163575Sopenharmony_ci    }
8970d163575Sopenharmony_ci
8980d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_VID
8990d163575Sopenharmony_ci    RemoveNodeByVid((UINT16)(UINTPTR)timerID);
9000d163575Sopenharmony_ci#endif
9010d163575Sopenharmony_ci    return 0;
9020d163575Sopenharmony_ci
9030d163575Sopenharmony_ciERROUT:
9040d163575Sopenharmony_ci    errno = EINVAL;
9050d163575Sopenharmony_ci    return -1;
9060d163575Sopenharmony_ci}
9070d163575Sopenharmony_ci
9080d163575Sopenharmony_ciint timer_settime(timer_t timerID, int flags,
9090d163575Sopenharmony_ci                  const struct itimerspec *value,   /* new value */
9100d163575Sopenharmony_ci                  struct itimerspec *oldValue)      /* old value to return, always 0 */
9110d163575Sopenharmony_ci{
9120d163575Sopenharmony_ci    UINT16 swtmrID = (UINT16)(UINTPTR)timerID;
9130d163575Sopenharmony_ci    SWTMR_CTRL_S *swtmr = NULL;
9140d163575Sopenharmony_ci    UINT32 interval, expiry, ret;
9150d163575Sopenharmony_ci    UINT32 intSave;
9160d163575Sopenharmony_ci
9170d163575Sopenharmony_ci    if (flags != 0) {
9180d163575Sopenharmony_ci        /* flags not supported currently */
9190d163575Sopenharmony_ci        errno = ENOSYS;
9200d163575Sopenharmony_ci        return -1;
9210d163575Sopenharmony_ci    }
9220d163575Sopenharmony_ci
9230d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_VID
9240d163575Sopenharmony_ci    swtmrID = GetRidByVid(swtmrID);
9250d163575Sopenharmony_ci#endif
9260d163575Sopenharmony_ci    if ((value == NULL) || OS_INT_ACTIVE || !ValidTimerID(swtmrID)) {
9270d163575Sopenharmony_ci        errno = EINVAL;
9280d163575Sopenharmony_ci        return -1;
9290d163575Sopenharmony_ci    }
9300d163575Sopenharmony_ci
9310d163575Sopenharmony_ci    if (!ValidTimeSpec(&value->it_value) || !ValidTimeSpec(&value->it_interval)) {
9320d163575Sopenharmony_ci        errno = EINVAL;
9330d163575Sopenharmony_ci        return -1;
9340d163575Sopenharmony_ci    }
9350d163575Sopenharmony_ci
9360d163575Sopenharmony_ci    if (oldValue) {
9370d163575Sopenharmony_ci        (VOID)timer_gettime(timerID, oldValue);
9380d163575Sopenharmony_ci    }
9390d163575Sopenharmony_ci
9400d163575Sopenharmony_ci    swtmr = OS_SWT_FROM_SID(swtmrID);
9410d163575Sopenharmony_ci    ret = LOS_SwtmrStop(swtmr->usTimerID);
9420d163575Sopenharmony_ci    if ((ret != LOS_OK) && (ret != LOS_ERRNO_SWTMR_NOT_STARTED)) {
9430d163575Sopenharmony_ci        errno = EINVAL;
9440d163575Sopenharmony_ci        return -1;
9450d163575Sopenharmony_ci    }
9460d163575Sopenharmony_ci
9470d163575Sopenharmony_ci    expiry = OsTimeSpec2Tick(&value->it_value);
9480d163575Sopenharmony_ci    interval = OsTimeSpec2Tick(&value->it_interval);
9490d163575Sopenharmony_ci
9500d163575Sopenharmony_ci    LOS_SpinLockSave(&g_swtmrSpin, &intSave);
9510d163575Sopenharmony_ci    swtmr->ucMode = interval ? LOS_SWTMR_MODE_OPP : LOS_SWTMR_MODE_NO_SELFDELETE;
9520d163575Sopenharmony_ci    swtmr->uwExpiry = expiry + !!expiry; // PS: skip the first tick because it is NOT a full tick.
9530d163575Sopenharmony_ci    swtmr->uwInterval = interval;
9540d163575Sopenharmony_ci    swtmr->uwOverrun = 0;
9550d163575Sopenharmony_ci    LOS_SpinUnlockRestore(&g_swtmrSpin, intSave);
9560d163575Sopenharmony_ci
9570d163575Sopenharmony_ci    if ((value->it_value.tv_sec == 0) && (value->it_value.tv_nsec == 0)) {
9580d163575Sopenharmony_ci        /*
9590d163575Sopenharmony_ci         * 1) when expiry is 0, means timer should be stopped.
9600d163575Sopenharmony_ci         * 2) If timer is ticking, stopping timer is already done before.
9610d163575Sopenharmony_ci         * 3) If timer is created but not ticking, return 0 as well.
9620d163575Sopenharmony_ci         */
9630d163575Sopenharmony_ci        return 0;
9640d163575Sopenharmony_ci    }
9650d163575Sopenharmony_ci
9660d163575Sopenharmony_ci    if (LOS_SwtmrStart(swtmr->usTimerID)) {
9670d163575Sopenharmony_ci        errno = EINVAL;
9680d163575Sopenharmony_ci        return -1;
9690d163575Sopenharmony_ci    }
9700d163575Sopenharmony_ci
9710d163575Sopenharmony_ci    return 0;
9720d163575Sopenharmony_ci}
9730d163575Sopenharmony_ci
9740d163575Sopenharmony_ciint timer_gettime(timer_t timerID, struct itimerspec *value)
9750d163575Sopenharmony_ci{
9760d163575Sopenharmony_ci    UINT32 tick = 0;
9770d163575Sopenharmony_ci    SWTMR_CTRL_S *swtmr = NULL;
9780d163575Sopenharmony_ci    UINT16 swtmrID = (UINT16)(UINTPTR)timerID;
9790d163575Sopenharmony_ci    UINT32 ret;
9800d163575Sopenharmony_ci
9810d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_VID
9820d163575Sopenharmony_ci    swtmrID = GetRidByVid(swtmrID);
9830d163575Sopenharmony_ci#endif
9840d163575Sopenharmony_ci    if ((value == NULL) || !ValidTimerID(swtmrID)) {
9850d163575Sopenharmony_ci        errno = EINVAL;
9860d163575Sopenharmony_ci        return -1;
9870d163575Sopenharmony_ci    }
9880d163575Sopenharmony_ci
9890d163575Sopenharmony_ci    swtmr = OS_SWT_FROM_SID(swtmrID);
9900d163575Sopenharmony_ci
9910d163575Sopenharmony_ci    /* get expire time */
9920d163575Sopenharmony_ci    ret = LOS_SwtmrTimeGet(swtmr->usTimerID, &tick);
9930d163575Sopenharmony_ci    if ((ret != LOS_OK) && (ret != LOS_ERRNO_SWTMR_NOT_STARTED)) {
9940d163575Sopenharmony_ci        errno = EINVAL;
9950d163575Sopenharmony_ci        return -1;
9960d163575Sopenharmony_ci    }
9970d163575Sopenharmony_ci
9980d163575Sopenharmony_ci    OsTick2TimeSpec(&value->it_value, tick);
9990d163575Sopenharmony_ci    OsTick2TimeSpec(&value->it_interval, (swtmr->ucMode == LOS_SWTMR_MODE_ONCE) ? 0 : swtmr->uwInterval);
10000d163575Sopenharmony_ci    return 0;
10010d163575Sopenharmony_ci}
10020d163575Sopenharmony_ci
10030d163575Sopenharmony_ciint timer_getoverrun(timer_t timerID)
10040d163575Sopenharmony_ci{
10050d163575Sopenharmony_ci    UINT16 swtmrID = (UINT16)(UINTPTR)timerID;
10060d163575Sopenharmony_ci    SWTMR_CTRL_S *swtmr = NULL;
10070d163575Sopenharmony_ci    INT32 overRun;
10080d163575Sopenharmony_ci
10090d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_VID
10100d163575Sopenharmony_ci    swtmrID = GetRidByVid(swtmrID);
10110d163575Sopenharmony_ci#endif
10120d163575Sopenharmony_ci    if (!ValidTimerID(swtmrID)) {
10130d163575Sopenharmony_ci        errno = EINVAL;
10140d163575Sopenharmony_ci        return -1;
10150d163575Sopenharmony_ci    }
10160d163575Sopenharmony_ci
10170d163575Sopenharmony_ci    swtmr = OS_SWT_FROM_SID(swtmrID);
10180d163575Sopenharmony_ci    if (swtmr->usTimerID >= OS_SWTMR_MAX_TIMERID) {
10190d163575Sopenharmony_ci        errno = EINVAL;
10200d163575Sopenharmony_ci        return -1;
10210d163575Sopenharmony_ci    }
10220d163575Sopenharmony_ci
10230d163575Sopenharmony_ci    overRun = (INT32)(swtmr->uwOverrun);
10240d163575Sopenharmony_ci    return (overRun > DELAYTIMER_MAX) ? DELAYTIMER_MAX : overRun;
10250d163575Sopenharmony_ci}
10260d163575Sopenharmony_ci
10270d163575Sopenharmony_ciSTATIC INT32 DoNanoSleep(UINT64 nanoseconds)
10280d163575Sopenharmony_ci{
10290d163575Sopenharmony_ci    UINT32 ret;
10300d163575Sopenharmony_ci
10310d163575Sopenharmony_ci    ret = LOS_TaskDelay(OsNS2Tick(nanoseconds));
10320d163575Sopenharmony_ci    if (ret == LOS_OK || ret == LOS_ERRNO_TSK_YIELD_NOT_ENOUGH_TASK) {
10330d163575Sopenharmony_ci        return 0;
10340d163575Sopenharmony_ci    }
10350d163575Sopenharmony_ci    return -1;
10360d163575Sopenharmony_ci}
10370d163575Sopenharmony_ci
10380d163575Sopenharmony_ci#ifdef LOSCFG_LIBC_NEWLIB
10390d163575Sopenharmony_ciint usleep(unsigned long useconds)
10400d163575Sopenharmony_ci#else
10410d163575Sopenharmony_ciint usleep(unsigned useconds)
10420d163575Sopenharmony_ci#endif
10430d163575Sopenharmony_ci{
10440d163575Sopenharmony_ci    return DoNanoSleep((UINT64)useconds * OS_SYS_NS_PER_US);
10450d163575Sopenharmony_ci}
10460d163575Sopenharmony_ci
10470d163575Sopenharmony_ciint nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
10480d163575Sopenharmony_ci{
10490d163575Sopenharmony_ci    UINT64 nanoseconds;
10500d163575Sopenharmony_ci    INT32 ret = -1;
10510d163575Sopenharmony_ci
10520d163575Sopenharmony_ci    (VOID)rmtp;
10530d163575Sopenharmony_ci    /* expire time */
10540d163575Sopenharmony_ci
10550d163575Sopenharmony_ci    if (!ValidTimeSpec(rqtp)) {
10560d163575Sopenharmony_ci        errno = EINVAL;
10570d163575Sopenharmony_ci        return ret;
10580d163575Sopenharmony_ci    }
10590d163575Sopenharmony_ci
10600d163575Sopenharmony_ci    nanoseconds = (UINT64)rqtp->tv_sec * OS_SYS_NS_PER_SECOND + rqtp->tv_nsec;
10610d163575Sopenharmony_ci
10620d163575Sopenharmony_ci    return DoNanoSleep(nanoseconds);
10630d163575Sopenharmony_ci}
10640d163575Sopenharmony_ci
10650d163575Sopenharmony_ciunsigned int sleep(unsigned int seconds)
10660d163575Sopenharmony_ci{
10670d163575Sopenharmony_ci    return DoNanoSleep((UINT64)seconds * OS_SYS_NS_PER_SECOND);
10680d163575Sopenharmony_ci}
10690d163575Sopenharmony_ci
10700d163575Sopenharmony_cidouble difftime(time_t time2, time_t time1)
10710d163575Sopenharmony_ci{
10720d163575Sopenharmony_ci    return (double)(time2 - time1);
10730d163575Sopenharmony_ci}
10740d163575Sopenharmony_ci
10750d163575Sopenharmony_ciclock_t clock(VOID)
10760d163575Sopenharmony_ci{
10770d163575Sopenharmony_ci    clock_t clockMsec;
10780d163575Sopenharmony_ci    UINT64 nowNsec;
10790d163575Sopenharmony_ci
10800d163575Sopenharmony_ci    nowNsec = LOS_CurrNanosec();
10810d163575Sopenharmony_ci    clockMsec = (clock_t)(nowNsec / (OS_SYS_NS_PER_SECOND / CLOCKS_PER_SEC));
10820d163575Sopenharmony_ci
10830d163575Sopenharmony_ci    return clockMsec;
10840d163575Sopenharmony_ci}
10850d163575Sopenharmony_ci
10860d163575Sopenharmony_ciclock_t times(struct tms *buf)
10870d163575Sopenharmony_ci{
10880d163575Sopenharmony_ci    clock_t clockTick = -1;
10890d163575Sopenharmony_ci
10900d163575Sopenharmony_ci    (void)buf;
10910d163575Sopenharmony_ci    set_errno(ENOSYS);
10920d163575Sopenharmony_ci
10930d163575Sopenharmony_ci    return clockTick;
10940d163575Sopenharmony_ci}
10950d163575Sopenharmony_ci
10960d163575Sopenharmony_ciint setitimer(int which, const struct itimerval *value, struct itimerval *ovalue)
10970d163575Sopenharmony_ci{
10980d163575Sopenharmony_ci    UINT32 intSave;
10990d163575Sopenharmony_ci    LosProcessCB *processCB = OsCurrProcessGet();
11000d163575Sopenharmony_ci    timer_t timerID = 0;
11010d163575Sopenharmony_ci    struct itimerspec spec;
11020d163575Sopenharmony_ci    struct itimerspec ospec;
11030d163575Sopenharmony_ci    int ret = LOS_OK;
11040d163575Sopenharmony_ci
11050d163575Sopenharmony_ci    /* we only support the realtime clock timer currently */
11060d163575Sopenharmony_ci    if (which != ITIMER_REAL || !value) {
11070d163575Sopenharmony_ci        set_errno(EINVAL);
11080d163575Sopenharmony_ci        return -1;
11090d163575Sopenharmony_ci    }
11100d163575Sopenharmony_ci
11110d163575Sopenharmony_ci    /* To avoid creating an invalid timer after the timer has already been create */
11120d163575Sopenharmony_ci    if (processCB->timerID == (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID) {
11130d163575Sopenharmony_ci        ret = OsTimerCreate(CLOCK_REALTIME, NULL, &timerID);
11140d163575Sopenharmony_ci        if (ret != LOS_OK) {
11150d163575Sopenharmony_ci            return ret;
11160d163575Sopenharmony_ci        }
11170d163575Sopenharmony_ci    }
11180d163575Sopenharmony_ci
11190d163575Sopenharmony_ci    /* The initialization of this global timer must be in spinlock
11200d163575Sopenharmony_ci     * OsTimerCreate cannot be located in spinlock.
11210d163575Sopenharmony_ci     */
11220d163575Sopenharmony_ci    SCHEDULER_LOCK(intSave);
11230d163575Sopenharmony_ci    if (processCB->timerID == (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID) {
11240d163575Sopenharmony_ci        processCB->timerID = timerID;
11250d163575Sopenharmony_ci        SCHEDULER_UNLOCK(intSave);
11260d163575Sopenharmony_ci    } else {
11270d163575Sopenharmony_ci        SCHEDULER_UNLOCK(intSave);
11280d163575Sopenharmony_ci        if (timerID) {
11290d163575Sopenharmony_ci            timer_delete(timerID);
11300d163575Sopenharmony_ci        }
11310d163575Sopenharmony_ci    }
11320d163575Sopenharmony_ci
11330d163575Sopenharmony_ci    if (!ValidTimeval(&value->it_value) || !ValidTimeval(&value->it_interval)) {
11340d163575Sopenharmony_ci        set_errno(EINVAL);
11350d163575Sopenharmony_ci        return -1;
11360d163575Sopenharmony_ci    }
11370d163575Sopenharmony_ci
11380d163575Sopenharmony_ci    TIMEVAL_TO_TIMESPEC(&value->it_value, &spec.it_value);
11390d163575Sopenharmony_ci    TIMEVAL_TO_TIMESPEC(&value->it_interval, &spec.it_interval);
11400d163575Sopenharmony_ci
11410d163575Sopenharmony_ci    ret = timer_settime(processCB->timerID, 0, &spec, ovalue ? &ospec : NULL);
11420d163575Sopenharmony_ci    if (ret == LOS_OK && ovalue) {
11430d163575Sopenharmony_ci        TIMESPEC_TO_TIMEVAL(&ovalue->it_value, &ospec.it_value);
11440d163575Sopenharmony_ci        TIMESPEC_TO_TIMEVAL(&ovalue->it_interval, &ospec.it_interval);
11450d163575Sopenharmony_ci    }
11460d163575Sopenharmony_ci
11470d163575Sopenharmony_ci    return ret;
11480d163575Sopenharmony_ci}
11490d163575Sopenharmony_ci
11500d163575Sopenharmony_ciint getitimer(int which, struct itimerval *value)
11510d163575Sopenharmony_ci{
11520d163575Sopenharmony_ci    LosProcessCB *processCB = OsCurrProcessGet();
11530d163575Sopenharmony_ci    struct itimerspec spec = {};
11540d163575Sopenharmony_ci
11550d163575Sopenharmony_ci    int ret = LOS_OK;
11560d163575Sopenharmony_ci
11570d163575Sopenharmony_ci    /* we only support the realtime clock timer currently */
11580d163575Sopenharmony_ci    if (which != ITIMER_REAL || !value) {
11590d163575Sopenharmony_ci        set_errno(EINVAL);
11600d163575Sopenharmony_ci        return -1;
11610d163575Sopenharmony_ci    }
11620d163575Sopenharmony_ci
11630d163575Sopenharmony_ci    if (processCB->timerID != (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID) {
11640d163575Sopenharmony_ci        ret = timer_gettime(processCB->timerID, &spec);
11650d163575Sopenharmony_ci    }
11660d163575Sopenharmony_ci
11670d163575Sopenharmony_ci    if (ret == LOS_OK) {
11680d163575Sopenharmony_ci        TIMESPEC_TO_TIMEVAL(&value->it_value, &spec.it_value);
11690d163575Sopenharmony_ci        TIMESPEC_TO_TIMEVAL(&value->it_interval, &spec.it_interval);
11700d163575Sopenharmony_ci    }
11710d163575Sopenharmony_ci
11720d163575Sopenharmony_ci    return ret;
11730d163575Sopenharmony_ci}
11740d163575Sopenharmony_ci
11750d163575Sopenharmony_ci#ifdef LOSCFG_KERNEL_VDSO
11760d163575Sopenharmony_ciVOID OsVdsoTimeGet(VdsoDataPage *vdsoDataPage)
11770d163575Sopenharmony_ci{
11780d163575Sopenharmony_ci    UINT32 intSave;
11790d163575Sopenharmony_ci    struct timespec64 tmp = {0};
11800d163575Sopenharmony_ci    struct timespec64 hwTime = {0};
11810d163575Sopenharmony_ci
11820d163575Sopenharmony_ci    if (vdsoDataPage == NULL) {
11830d163575Sopenharmony_ci        return;
11840d163575Sopenharmony_ci    }
11850d163575Sopenharmony_ci
11860d163575Sopenharmony_ci    OsGetHwTime(&hwTime);
11870d163575Sopenharmony_ci
11880d163575Sopenharmony_ci    LOS_SpinLockSave(&g_timeSpin, &intSave);
11890d163575Sopenharmony_ci    tmp = OsTimeSpecAdd(hwTime, g_accDeltaFromAdj);
11900d163575Sopenharmony_ci    vdsoDataPage->monoTimeSec = tmp.tv_sec;
11910d163575Sopenharmony_ci    vdsoDataPage->monoTimeNsec = tmp.tv_nsec;
11920d163575Sopenharmony_ci
11930d163575Sopenharmony_ci    tmp = OsTimeSpecAdd(tmp, g_accDeltaFromSet);
11940d163575Sopenharmony_ci    vdsoDataPage->realTimeSec = tmp.tv_sec;
11950d163575Sopenharmony_ci    vdsoDataPage->realTimeNsec = tmp.tv_nsec;
11960d163575Sopenharmony_ci    LOS_SpinUnlockRestore(&g_timeSpin, intSave);
11970d163575Sopenharmony_ci}
11980d163575Sopenharmony_ci#endif
11990d163575Sopenharmony_ci
12000d163575Sopenharmony_citime_t time(time_t *t)
12010d163575Sopenharmony_ci{
12020d163575Sopenharmony_ci    struct timeval tp;
12030d163575Sopenharmony_ci    int ret;
12040d163575Sopenharmony_ci
12050d163575Sopenharmony_ci    /* Get the current time from the system */
12060d163575Sopenharmony_ci    ret = gettimeofday(&tp, (struct timezone *)NULL);
12070d163575Sopenharmony_ci    if (ret == LOS_OK) {
12080d163575Sopenharmony_ci        /* Return the seconds since the epoch */
12090d163575Sopenharmony_ci        if (t) {
12100d163575Sopenharmony_ci            *t = tp.tv_sec;
12110d163575Sopenharmony_ci        }
12120d163575Sopenharmony_ci        return tp.tv_sec;
12130d163575Sopenharmony_ci    }
12140d163575Sopenharmony_ci    return (time_t)OS_ERROR;
12150d163575Sopenharmony_ci}
1216