xref: /kernel/liteos_m/kal/posix/src/time.c (revision 3d8536b4)
13d8536b4Sopenharmony_ci/*
23d8536b4Sopenharmony_ci * Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved.
33d8536b4Sopenharmony_ci *
43d8536b4Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification,
53d8536b4Sopenharmony_ci * are permitted provided that the following conditions are met:
63d8536b4Sopenharmony_ci *
73d8536b4Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, this list of
83d8536b4Sopenharmony_ci *    conditions and the following disclaimer.
93d8536b4Sopenharmony_ci *
103d8536b4Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, this list
113d8536b4Sopenharmony_ci *    of conditions and the following disclaimer in the documentation and/or other materials
123d8536b4Sopenharmony_ci *    provided with the distribution.
133d8536b4Sopenharmony_ci *
143d8536b4Sopenharmony_ci * 3. Neither the name of the copyright holder nor the names of its contributors may be used
153d8536b4Sopenharmony_ci *    to endorse or promote products derived from this software without specific prior written
163d8536b4Sopenharmony_ci *    permission.
173d8536b4Sopenharmony_ci *
183d8536b4Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
193d8536b4Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
203d8536b4Sopenharmony_ci * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
213d8536b4Sopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
223d8536b4Sopenharmony_ci * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
233d8536b4Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
243d8536b4Sopenharmony_ci * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
253d8536b4Sopenharmony_ci * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
263d8536b4Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
273d8536b4Sopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
283d8536b4Sopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
293d8536b4Sopenharmony_ci */
303d8536b4Sopenharmony_ci
313d8536b4Sopenharmony_ci#define _GNU_SOURCE
323d8536b4Sopenharmony_ci#include <time.h>
333d8536b4Sopenharmony_ci#include <sys/time.h>
343d8536b4Sopenharmony_ci#include <stdint.h>
353d8536b4Sopenharmony_ci#include <errno.h>
363d8536b4Sopenharmony_ci#include <signal.h>
373d8536b4Sopenharmony_ci#include <unistd.h>
383d8536b4Sopenharmony_ci#include "time_internal.h"
393d8536b4Sopenharmony_ci#include "los_debug.h"
403d8536b4Sopenharmony_ci#include "los_task.h"
413d8536b4Sopenharmony_ci#include "los_swtmr.h"
423d8536b4Sopenharmony_ci#include "los_tick.h"
433d8536b4Sopenharmony_ci#include "los_context.h"
443d8536b4Sopenharmony_ci#include "los_interrupt.h"
453d8536b4Sopenharmony_ci#include "sys/times.h"
463d8536b4Sopenharmony_ci#include "rtc_time_hook.h"
473d8536b4Sopenharmony_ci
483d8536b4Sopenharmony_ci#define DELAYTIMER_MAX 0x7FFFFFFFF
493d8536b4Sopenharmony_ci
503d8536b4Sopenharmony_ci/* accumulative time delta from discontinuous modify */
513d8536b4Sopenharmony_ciSTATIC struct timespec g_accDeltaFromSet;
523d8536b4Sopenharmony_ci
533d8536b4Sopenharmony_ciSTATIC const UINT16 g_daysInMonth[2][13] = {
543d8536b4Sopenharmony_ci    /* Normal years.  */
553d8536b4Sopenharmony_ci    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
563d8536b4Sopenharmony_ci    /* Leap years.  */
573d8536b4Sopenharmony_ci    { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
583d8536b4Sopenharmony_ci};
593d8536b4Sopenharmony_ci
603d8536b4Sopenharmony_ciSTATIC const UINT8 g_montbl[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
613d8536b4Sopenharmony_ci
623d8536b4Sopenharmony_ci#if (LOSCFG_LIBC_NEWLIB == 1)
633d8536b4Sopenharmony_ci#define TIMEZONE _timezone
643d8536b4Sopenharmony_ci#else
653d8536b4Sopenharmony_ci#define TIMEZONE timezone
663d8536b4Sopenharmony_ci/*
673d8536b4Sopenharmony_ci * Time zone information, stored in seconds,
683d8536b4Sopenharmony_ci * negative values indicate the east of UTC,
693d8536b4Sopenharmony_ci * positive values indicate the west of UTC.
703d8536b4Sopenharmony_ci */
713d8536b4Sopenharmony_cilong TIMEZONE = -8 * 60 * 60; // set default to CST(UTC+8)
723d8536b4Sopenharmony_ci#endif
733d8536b4Sopenharmony_ci
743d8536b4Sopenharmony_ci/*
753d8536b4Sopenharmony_ci * store register rtc func
763d8536b4Sopenharmony_ci */
773d8536b4Sopenharmony_ciSTATIC struct RtcTimeHook g_rtcTimeFunc;
783d8536b4Sopenharmony_ci
793d8536b4Sopenharmony_ciSTATIC UINT64 g_rtcTimeBase = 0;
803d8536b4Sopenharmony_ciSTATIC UINT64 g_systickBase = 0;
813d8536b4Sopenharmony_ci
823d8536b4Sopenharmony_ciVOID LOS_RtcHookRegister(struct RtcTimeHook *cfg)
833d8536b4Sopenharmony_ci{
843d8536b4Sopenharmony_ci    if (cfg == NULL) {
853d8536b4Sopenharmony_ci        return;
863d8536b4Sopenharmony_ci    }
873d8536b4Sopenharmony_ci    g_rtcTimeFunc.RtcGetTickHook = cfg->RtcGetTickHook;
883d8536b4Sopenharmony_ci    g_rtcTimeFunc.RtcGetTimeHook = cfg->RtcGetTimeHook;
893d8536b4Sopenharmony_ci    g_rtcTimeFunc.RtcSetTimeHook = cfg->RtcSetTimeHook;
903d8536b4Sopenharmony_ci    g_rtcTimeFunc.RtcGetTimezoneHook = cfg->RtcGetTimezoneHook;
913d8536b4Sopenharmony_ci    g_rtcTimeFunc.RtcSetTimezoneHook = cfg->RtcSetTimezoneHook;
923d8536b4Sopenharmony_ci}
933d8536b4Sopenharmony_ci
943d8536b4Sopenharmony_ciint nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
953d8536b4Sopenharmony_ci{
963d8536b4Sopenharmony_ci    UINT64 nseconds;
973d8536b4Sopenharmony_ci    UINT64 tick;
983d8536b4Sopenharmony_ci    UINT32 ret;
993d8536b4Sopenharmony_ci    const UINT32 nsPerTick = OS_SYS_NS_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND;
1003d8536b4Sopenharmony_ci
1013d8536b4Sopenharmony_ci    if (!ValidTimeSpec(rqtp)) {
1023d8536b4Sopenharmony_ci        errno = EINVAL;
1033d8536b4Sopenharmony_ci        return -1;
1043d8536b4Sopenharmony_ci    }
1053d8536b4Sopenharmony_ci
1063d8536b4Sopenharmony_ci    nseconds = (UINT64)rqtp->tv_sec * OS_SYS_NS_PER_SECOND + rqtp->tv_nsec;
1073d8536b4Sopenharmony_ci
1083d8536b4Sopenharmony_ci    tick = (nseconds + nsPerTick - 1) / nsPerTick; // Round up for ticks
1093d8536b4Sopenharmony_ci
1103d8536b4Sopenharmony_ci    if (tick >= UINT32_MAX) {
1113d8536b4Sopenharmony_ci        errno = EINVAL;
1123d8536b4Sopenharmony_ci        return -1;
1133d8536b4Sopenharmony_ci    }
1143d8536b4Sopenharmony_ci
1153d8536b4Sopenharmony_ci    /* PS: skip the first tick because it is NOT a full tick. */
1163d8536b4Sopenharmony_ci    ret = LOS_TaskDelay(tick ? (UINT32)(tick + 1) : 0);
1173d8536b4Sopenharmony_ci    if (ret == LOS_OK || ret == LOS_ERRNO_TSK_YIELD_NOT_ENOUGH_TASK) {
1183d8536b4Sopenharmony_ci        if (rmtp) {
1193d8536b4Sopenharmony_ci            rmtp->tv_sec = rmtp->tv_nsec = 0;
1203d8536b4Sopenharmony_ci        }
1213d8536b4Sopenharmony_ci        return 0;
1223d8536b4Sopenharmony_ci    }
1233d8536b4Sopenharmony_ci
1243d8536b4Sopenharmony_ci    /* sleep in interrupt context or in task sched lock state */
1253d8536b4Sopenharmony_ci    errno = EINTR;
1263d8536b4Sopenharmony_ci    return -1;
1273d8536b4Sopenharmony_ci}
1283d8536b4Sopenharmony_ci
1293d8536b4Sopenharmony_ciint timer_create(clockid_t clockID, struct sigevent *restrict evp, timer_t *restrict timerID)
1303d8536b4Sopenharmony_ci{
1313d8536b4Sopenharmony_ci    UINT32 ret;
1323d8536b4Sopenharmony_ci    UINT32 swtmrID;
1333d8536b4Sopenharmony_ci
1343d8536b4Sopenharmony_ci    if (!timerID || (clockID != CLOCK_REALTIME) || !evp) {
1353d8536b4Sopenharmony_ci        errno = EINVAL;
1363d8536b4Sopenharmony_ci        return -1;
1373d8536b4Sopenharmony_ci    }
1383d8536b4Sopenharmony_ci
1393d8536b4Sopenharmony_ci    if ((evp->sigev_notify != SIGEV_THREAD) || evp->sigev_notify_attributes) {
1403d8536b4Sopenharmony_ci        errno = ENOTSUP;
1413d8536b4Sopenharmony_ci        return -1;
1423d8536b4Sopenharmony_ci    }
1433d8536b4Sopenharmony_ci
1443d8536b4Sopenharmony_ci    ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_ONCE, (SWTMR_PROC_FUNC)evp->sigev_notify_function,
1453d8536b4Sopenharmony_ci                          &swtmrID, (UINT32)(UINTPTR)evp->sigev_value.sival_ptr
1463d8536b4Sopenharmony_ci#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == 1)
1473d8536b4Sopenharmony_ci                          , OS_SWTMR_ROUSES_IGNORE, OS_SWTMR_ALIGN_INSENSITIVE
1483d8536b4Sopenharmony_ci#endif
1493d8536b4Sopenharmony_ci    );
1503d8536b4Sopenharmony_ci    if (ret != LOS_OK) {
1513d8536b4Sopenharmony_ci        errno = (ret == LOS_ERRNO_SWTMR_MAXSIZE) ? EAGAIN : EINVAL;
1523d8536b4Sopenharmony_ci        return -1;
1533d8536b4Sopenharmony_ci    }
1543d8536b4Sopenharmony_ci
1553d8536b4Sopenharmony_ci    *timerID = (timer_t)(UINTPTR)swtmrID;
1563d8536b4Sopenharmony_ci    return 0;
1573d8536b4Sopenharmony_ci}
1583d8536b4Sopenharmony_ci
1593d8536b4Sopenharmony_ciint timer_delete(timer_t timerID)
1603d8536b4Sopenharmony_ci{
1613d8536b4Sopenharmony_ci    UINT32 swtmrID = (UINT32)(UINTPTR)timerID;
1623d8536b4Sopenharmony_ci    if (LOS_SwtmrDelete(swtmrID) != LOS_OK) {
1633d8536b4Sopenharmony_ci        errno = EINVAL;
1643d8536b4Sopenharmony_ci        return -1;
1653d8536b4Sopenharmony_ci    }
1663d8536b4Sopenharmony_ci
1673d8536b4Sopenharmony_ci    return 0;
1683d8536b4Sopenharmony_ci}
1693d8536b4Sopenharmony_ci
1703d8536b4Sopenharmony_ciint timer_settime(timer_t timerID, int flags,
1713d8536b4Sopenharmony_ci                  const struct itimerspec *restrict value,
1723d8536b4Sopenharmony_ci                  struct itimerspec *restrict oldValue)
1733d8536b4Sopenharmony_ci{
1743d8536b4Sopenharmony_ci    UINT32 intSave;
1753d8536b4Sopenharmony_ci    UINT32 swtmrID = (UINT32)(UINTPTR)timerID;
1763d8536b4Sopenharmony_ci    SWTMR_CTRL_S *swtmr = NULL;
1773d8536b4Sopenharmony_ci    UINT32 interval, expiry, ret;
1783d8536b4Sopenharmony_ci
1793d8536b4Sopenharmony_ci    if (flags != 0) {
1803d8536b4Sopenharmony_ci        /* flags not supported currently */
1813d8536b4Sopenharmony_ci        errno = ENOTSUP;
1823d8536b4Sopenharmony_ci        return -1;
1833d8536b4Sopenharmony_ci    }
1843d8536b4Sopenharmony_ci
1853d8536b4Sopenharmony_ci    if (value == NULL) {
1863d8536b4Sopenharmony_ci        errno = EINVAL;
1873d8536b4Sopenharmony_ci        return -1;
1883d8536b4Sopenharmony_ci    }
1893d8536b4Sopenharmony_ci
1903d8536b4Sopenharmony_ci    if (!ValidTimeSpec(&value->it_value) || !ValidTimeSpec(&value->it_interval)) {
1913d8536b4Sopenharmony_ci        errno = EINVAL;
1923d8536b4Sopenharmony_ci        return -1;
1933d8536b4Sopenharmony_ci    }
1943d8536b4Sopenharmony_ci
1953d8536b4Sopenharmony_ci    expiry = OsTimeSpec2Tick(&value->it_value);
1963d8536b4Sopenharmony_ci    interval = OsTimeSpec2Tick(&value->it_interval);
1973d8536b4Sopenharmony_ci
1983d8536b4Sopenharmony_ci    /* if specified interval, it must be same with expiry due to the limitation of liteos-m */
1993d8536b4Sopenharmony_ci    if (interval && interval != expiry) {
2003d8536b4Sopenharmony_ci        errno = ENOTSUP;
2013d8536b4Sopenharmony_ci        return -1;
2023d8536b4Sopenharmony_ci    }
2033d8536b4Sopenharmony_ci
2043d8536b4Sopenharmony_ci    if (oldValue) {
2053d8536b4Sopenharmony_ci        (VOID)timer_gettime(timerID, oldValue);
2063d8536b4Sopenharmony_ci    }
2073d8536b4Sopenharmony_ci
2083d8536b4Sopenharmony_ci    ret = LOS_SwtmrStop(swtmrID);
2093d8536b4Sopenharmony_ci    if ((ret != LOS_OK) && (ret != LOS_ERRNO_SWTMR_NOT_STARTED)) {
2103d8536b4Sopenharmony_ci        errno = EINVAL;
2113d8536b4Sopenharmony_ci        return -1;
2123d8536b4Sopenharmony_ci    }
2133d8536b4Sopenharmony_ci
2143d8536b4Sopenharmony_ci    intSave = LOS_IntLock();
2153d8536b4Sopenharmony_ci    swtmr = OS_SWT_FROM_SID(swtmrID);
2163d8536b4Sopenharmony_ci    swtmr->ucMode = (interval ? LOS_SWTMR_MODE_PERIOD : LOS_SWTMR_MODE_NO_SELFDELETE);
2173d8536b4Sopenharmony_ci    swtmr->uwInterval = (interval ? interval : expiry);
2183d8536b4Sopenharmony_ci
2193d8536b4Sopenharmony_ci    swtmr->ucOverrun = 0;
2203d8536b4Sopenharmony_ci    LOS_IntRestore(intSave);
2213d8536b4Sopenharmony_ci
2223d8536b4Sopenharmony_ci    if ((value->it_value.tv_sec == 0) && (value->it_value.tv_nsec == 0)) {
2233d8536b4Sopenharmony_ci        /*
2243d8536b4Sopenharmony_ci         * 1) when expiry is 0, means timer should be stopped.
2253d8536b4Sopenharmony_ci         * 2) If timer is ticking, stopping timer is already done before.
2263d8536b4Sopenharmony_ci         * 3) If timer is created but not ticking, return 0 as well.
2273d8536b4Sopenharmony_ci         */
2283d8536b4Sopenharmony_ci        return 0;
2293d8536b4Sopenharmony_ci    }
2303d8536b4Sopenharmony_ci
2313d8536b4Sopenharmony_ci    if (LOS_SwtmrStart(swtmr->usTimerID) != LOS_OK) {
2323d8536b4Sopenharmony_ci        errno = EINVAL;
2333d8536b4Sopenharmony_ci        return -1;
2343d8536b4Sopenharmony_ci    }
2353d8536b4Sopenharmony_ci
2363d8536b4Sopenharmony_ci    return 0;
2373d8536b4Sopenharmony_ci}
2383d8536b4Sopenharmony_ci
2393d8536b4Sopenharmony_ciint timer_gettime(timer_t timerID, struct itimerspec *value)
2403d8536b4Sopenharmony_ci{
2413d8536b4Sopenharmony_ci    UINT32 tick = 0;
2423d8536b4Sopenharmony_ci    SWTMR_CTRL_S *swtmr = NULL;
2433d8536b4Sopenharmony_ci    UINT32 swtmrID = (UINT32)(UINTPTR)timerID;
2443d8536b4Sopenharmony_ci    UINT32 ret;
2453d8536b4Sopenharmony_ci
2463d8536b4Sopenharmony_ci    if (value == NULL) {
2473d8536b4Sopenharmony_ci        errno = EINVAL;
2483d8536b4Sopenharmony_ci        return -1;
2493d8536b4Sopenharmony_ci    }
2503d8536b4Sopenharmony_ci
2513d8536b4Sopenharmony_ci    swtmr = OS_SWT_FROM_SID(swtmrID);
2523d8536b4Sopenharmony_ci
2533d8536b4Sopenharmony_ci    /* get expire time */
2543d8536b4Sopenharmony_ci    ret = LOS_SwtmrTimeGet(swtmr->usTimerID, &tick);
2553d8536b4Sopenharmony_ci    if ((ret != LOS_OK) && (ret != LOS_ERRNO_SWTMR_NOT_STARTED)) {
2563d8536b4Sopenharmony_ci        errno = EINVAL;
2573d8536b4Sopenharmony_ci        return -1;
2583d8536b4Sopenharmony_ci    }
2593d8536b4Sopenharmony_ci    if (ret == LOS_ERRNO_SWTMR_NOT_STARTED) {
2603d8536b4Sopenharmony_ci        tick = 0;
2613d8536b4Sopenharmony_ci    }
2623d8536b4Sopenharmony_ci    OsTick2TimeSpec(&value->it_value, tick);
2633d8536b4Sopenharmony_ci    OsTick2TimeSpec(&value->it_interval, (swtmr->ucMode == LOS_SWTMR_MODE_ONCE) ? 0 : swtmr->uwInterval);
2643d8536b4Sopenharmony_ci    return 0;
2653d8536b4Sopenharmony_ci}
2663d8536b4Sopenharmony_ci
2673d8536b4Sopenharmony_ciint timer_getoverrun(timer_t timerID)
2683d8536b4Sopenharmony_ci{
2693d8536b4Sopenharmony_ci    SWTMR_CTRL_S *swtmr = NULL;
2703d8536b4Sopenharmony_ci    swtmr = OS_SWT_FROM_SID((UINT32)(UINTPTR)timerID);
2713d8536b4Sopenharmony_ci
2723d8536b4Sopenharmony_ci    if ((swtmr->ucOverrun) >= (UINT8)DELAYTIMER_MAX) {
2733d8536b4Sopenharmony_ci        return (INT32)DELAYTIMER_MAX;
2743d8536b4Sopenharmony_ci    }
2753d8536b4Sopenharmony_ci    return (int)swtmr->ucOverrun;
2763d8536b4Sopenharmony_ci}
2773d8536b4Sopenharmony_ci
2783d8536b4Sopenharmony_ciSTATIC VOID OsGetHwTime(struct timespec *hwTime)
2793d8536b4Sopenharmony_ci{
2803d8536b4Sopenharmony_ci    UINT64 cycle = LOS_SysCycleGet();
2813d8536b4Sopenharmony_ci    UINT64 nowNsec = (cycle / g_sysClock) * OS_SYS_NS_PER_SECOND +
2823d8536b4Sopenharmony_ci                     (cycle % g_sysClock) * OS_SYS_NS_PER_SECOND / g_sysClock;
2833d8536b4Sopenharmony_ci
2843d8536b4Sopenharmony_ci    hwTime->tv_sec = nowNsec / OS_SYS_NS_PER_SECOND;
2853d8536b4Sopenharmony_ci    hwTime->tv_nsec = nowNsec % OS_SYS_NS_PER_SECOND;
2863d8536b4Sopenharmony_ci}
2873d8536b4Sopenharmony_ci
2883d8536b4Sopenharmony_ciSTATIC VOID OsGetRealTime(struct timespec *realTime)
2893d8536b4Sopenharmony_ci{
2903d8536b4Sopenharmony_ci    UINT32 intSave;
2913d8536b4Sopenharmony_ci    struct timespec hwTime = {0};
2923d8536b4Sopenharmony_ci    OsGetHwTime(&hwTime);
2933d8536b4Sopenharmony_ci    intSave = LOS_IntLock();
2943d8536b4Sopenharmony_ci    realTime->tv_nsec = hwTime.tv_nsec + g_accDeltaFromSet.tv_nsec;
2953d8536b4Sopenharmony_ci    realTime->tv_sec = hwTime.tv_sec + g_accDeltaFromSet.tv_sec + (realTime->tv_nsec >= OS_SYS_NS_PER_SECOND);
2963d8536b4Sopenharmony_ci    realTime->tv_nsec %= OS_SYS_NS_PER_SECOND;
2973d8536b4Sopenharmony_ci    LOS_IntRestore(intSave);
2983d8536b4Sopenharmony_ci}
2993d8536b4Sopenharmony_ci
3003d8536b4Sopenharmony_ciSTATIC VOID OsSetRealTime(const struct timespec *realTime)
3013d8536b4Sopenharmony_ci{
3023d8536b4Sopenharmony_ci    UINT32 intSave;
3033d8536b4Sopenharmony_ci    struct timespec hwTime = {0};
3043d8536b4Sopenharmony_ci    OsGetHwTime(&hwTime);
3053d8536b4Sopenharmony_ci    intSave = LOS_IntLock();
3063d8536b4Sopenharmony_ci    g_accDeltaFromSet.tv_nsec = realTime->tv_nsec - hwTime.tv_nsec;
3073d8536b4Sopenharmony_ci    g_accDeltaFromSet.tv_sec = realTime->tv_sec - hwTime.tv_sec - (g_accDeltaFromSet.tv_nsec < 0);
3083d8536b4Sopenharmony_ci    g_accDeltaFromSet.tv_nsec = (g_accDeltaFromSet.tv_nsec + OS_SYS_NS_PER_SECOND) % OS_SYS_NS_PER_SECOND;
3093d8536b4Sopenharmony_ci    LOS_IntRestore(intSave);
3103d8536b4Sopenharmony_ci}
3113d8536b4Sopenharmony_ci
3123d8536b4Sopenharmony_ciint clock_settime(clockid_t clockID, const struct timespec *tp)
3133d8536b4Sopenharmony_ci{
3143d8536b4Sopenharmony_ci    if (!ValidTimeSpec(tp)) {
3153d8536b4Sopenharmony_ci        errno = EINVAL;
3163d8536b4Sopenharmony_ci        return -1;
3173d8536b4Sopenharmony_ci    }
3183d8536b4Sopenharmony_ci
3193d8536b4Sopenharmony_ci    switch (clockID) {
3203d8536b4Sopenharmony_ci        case CLOCK_REALTIME:
3213d8536b4Sopenharmony_ci            /* we only support the realtime clock currently */
3223d8536b4Sopenharmony_ci            OsSetRealTime(tp);
3233d8536b4Sopenharmony_ci            return 0;
3243d8536b4Sopenharmony_ci        case CLOCK_MONOTONIC_COARSE:
3253d8536b4Sopenharmony_ci        case CLOCK_REALTIME_COARSE:
3263d8536b4Sopenharmony_ci        case CLOCK_MONOTONIC_RAW:
3273d8536b4Sopenharmony_ci        case CLOCK_PROCESS_CPUTIME_ID:
3283d8536b4Sopenharmony_ci        case CLOCK_BOOTTIME:
3293d8536b4Sopenharmony_ci#ifdef CLOCK_REALTIME_ALARM
3303d8536b4Sopenharmony_ci        case CLOCK_REALTIME_ALARM:
3313d8536b4Sopenharmony_ci#endif
3323d8536b4Sopenharmony_ci#ifdef CLOCK_BOOTTIME_ALARM
3333d8536b4Sopenharmony_ci        case CLOCK_BOOTTIME_ALARM:
3343d8536b4Sopenharmony_ci#endif
3353d8536b4Sopenharmony_ci#ifdef CLOCK_SGI_CYCLE
3363d8536b4Sopenharmony_ci        case CLOCK_SGI_CYCLE:
3373d8536b4Sopenharmony_ci#endif
3383d8536b4Sopenharmony_ci#ifdef CLOCK_TAI
3393d8536b4Sopenharmony_ci        case CLOCK_TAI:
3403d8536b4Sopenharmony_ci#endif
3413d8536b4Sopenharmony_ci        case CLOCK_THREAD_CPUTIME_ID:
3423d8536b4Sopenharmony_ci            errno = ENOTSUP;
3433d8536b4Sopenharmony_ci            return -1;
3443d8536b4Sopenharmony_ci        case CLOCK_MONOTONIC:
3453d8536b4Sopenharmony_ci        default:
3463d8536b4Sopenharmony_ci            errno = EINVAL;
3473d8536b4Sopenharmony_ci            return -1;
3483d8536b4Sopenharmony_ci    }
3493d8536b4Sopenharmony_ci}
3503d8536b4Sopenharmony_ci
3513d8536b4Sopenharmony_ciint clock_gettime(clockid_t clockID, struct timespec *tp)
3523d8536b4Sopenharmony_ci{
3533d8536b4Sopenharmony_ci    if (tp == NULL) {
3543d8536b4Sopenharmony_ci        errno = EINVAL;
3553d8536b4Sopenharmony_ci        return -1;
3563d8536b4Sopenharmony_ci    }
3573d8536b4Sopenharmony_ci
3583d8536b4Sopenharmony_ci    switch (clockID) {
3593d8536b4Sopenharmony_ci        case CLOCK_MONOTONIC_RAW:
3603d8536b4Sopenharmony_ci        case CLOCK_MONOTONIC:
3613d8536b4Sopenharmony_ci        case CLOCK_MONOTONIC_COARSE:
3623d8536b4Sopenharmony_ci            OsGetHwTime(tp);
3633d8536b4Sopenharmony_ci            return 0;
3643d8536b4Sopenharmony_ci        case CLOCK_REALTIME:
3653d8536b4Sopenharmony_ci        case CLOCK_REALTIME_COARSE:
3663d8536b4Sopenharmony_ci            OsGetRealTime(tp);
3673d8536b4Sopenharmony_ci            return 0;
3683d8536b4Sopenharmony_ci        case CLOCK_THREAD_CPUTIME_ID:
3693d8536b4Sopenharmony_ci        case CLOCK_PROCESS_CPUTIME_ID:
3703d8536b4Sopenharmony_ci        case CLOCK_BOOTTIME:
3713d8536b4Sopenharmony_ci#ifdef CLOCK_REALTIME_ALARM
3723d8536b4Sopenharmony_ci        case CLOCK_REALTIME_ALARM:
3733d8536b4Sopenharmony_ci#endif
3743d8536b4Sopenharmony_ci#ifdef CLOCK_BOOTTIME_ALARM
3753d8536b4Sopenharmony_ci        case CLOCK_BOOTTIME_ALARM:
3763d8536b4Sopenharmony_ci#endif
3773d8536b4Sopenharmony_ci#ifdef CLOCK_SGI_CYCLE
3783d8536b4Sopenharmony_ci        case CLOCK_SGI_CYCLE:
3793d8536b4Sopenharmony_ci#endif
3803d8536b4Sopenharmony_ci#ifdef CLOCK_TAI
3813d8536b4Sopenharmony_ci        case CLOCK_TAI:
3823d8536b4Sopenharmony_ci#endif
3833d8536b4Sopenharmony_ci            errno = ENOTSUP;
3843d8536b4Sopenharmony_ci            return -1;
3853d8536b4Sopenharmony_ci        default:
3863d8536b4Sopenharmony_ci            errno = EINVAL;
3873d8536b4Sopenharmony_ci            return -1;
3883d8536b4Sopenharmony_ci    }
3893d8536b4Sopenharmony_ci}
3903d8536b4Sopenharmony_ci
3913d8536b4Sopenharmony_ciint clock_getres(clockid_t clockID, struct timespec *tp)
3923d8536b4Sopenharmony_ci{
3933d8536b4Sopenharmony_ci    if (tp == NULL) {
3943d8536b4Sopenharmony_ci        errno = EINVAL;
3953d8536b4Sopenharmony_ci        return -1;
3963d8536b4Sopenharmony_ci    }
3973d8536b4Sopenharmony_ci
3983d8536b4Sopenharmony_ci    switch (clockID) {
3993d8536b4Sopenharmony_ci        case CLOCK_MONOTONIC_RAW:
4003d8536b4Sopenharmony_ci        case CLOCK_MONOTONIC:
4013d8536b4Sopenharmony_ci        case CLOCK_REALTIME:
4023d8536b4Sopenharmony_ci        case CLOCK_MONOTONIC_COARSE:
4033d8536b4Sopenharmony_ci        case CLOCK_REALTIME_COARSE:
4043d8536b4Sopenharmony_ci            tp->tv_nsec = OS_SYS_NS_PER_SECOND / g_sysClock;
4053d8536b4Sopenharmony_ci            tp->tv_sec = 0;
4063d8536b4Sopenharmony_ci            return 0;
4073d8536b4Sopenharmony_ci        case CLOCK_THREAD_CPUTIME_ID:
4083d8536b4Sopenharmony_ci        case CLOCK_PROCESS_CPUTIME_ID:
4093d8536b4Sopenharmony_ci        case CLOCK_BOOTTIME:
4103d8536b4Sopenharmony_ci#ifdef CLOCK_REALTIME_ALARM
4113d8536b4Sopenharmony_ci        case CLOCK_REALTIME_ALARM:
4123d8536b4Sopenharmony_ci#endif
4133d8536b4Sopenharmony_ci#ifdef CLOCK_BOOTTIME_ALARM
4143d8536b4Sopenharmony_ci        case CLOCK_BOOTTIME_ALARM:
4153d8536b4Sopenharmony_ci#endif
4163d8536b4Sopenharmony_ci#ifdef CLOCK_SGI_CYCLE
4173d8536b4Sopenharmony_ci        case CLOCK_SGI_CYCLE:
4183d8536b4Sopenharmony_ci#endif
4193d8536b4Sopenharmony_ci#ifdef CLOCK_TAI
4203d8536b4Sopenharmony_ci        case CLOCK_TAI:
4213d8536b4Sopenharmony_ci#endif
4223d8536b4Sopenharmony_ci            errno = ENOTSUP;
4233d8536b4Sopenharmony_ci            return -1;
4243d8536b4Sopenharmony_ci        default:
4253d8536b4Sopenharmony_ci            errno = EINVAL;
4263d8536b4Sopenharmony_ci            return -1;
4273d8536b4Sopenharmony_ci    }
4283d8536b4Sopenharmony_ci}
4293d8536b4Sopenharmony_ci
4303d8536b4Sopenharmony_ciint clock_nanosleep(clockid_t clk, int flags, const struct timespec *req, struct timespec *rem)
4313d8536b4Sopenharmony_ci{
4323d8536b4Sopenharmony_ci    switch (clk) {
4333d8536b4Sopenharmony_ci        case CLOCK_REALTIME:
4343d8536b4Sopenharmony_ci            if (flags == 0) {
4353d8536b4Sopenharmony_ci                /* we only support the realtime clock currently */
4363d8536b4Sopenharmony_ci                return nanosleep(req, rem);
4373d8536b4Sopenharmony_ci            }
4383d8536b4Sopenharmony_ci            /* fallthrough */
4393d8536b4Sopenharmony_ci        case CLOCK_MONOTONIC_COARSE:
4403d8536b4Sopenharmony_ci        case CLOCK_REALTIME_COARSE:
4413d8536b4Sopenharmony_ci        case CLOCK_MONOTONIC_RAW:
4423d8536b4Sopenharmony_ci        case CLOCK_MONOTONIC:
4433d8536b4Sopenharmony_ci        case CLOCK_PROCESS_CPUTIME_ID:
4443d8536b4Sopenharmony_ci        case CLOCK_BOOTTIME:
4453d8536b4Sopenharmony_ci#ifdef CLOCK_REALTIME_ALARM
4463d8536b4Sopenharmony_ci        case CLOCK_REALTIME_ALARM:
4473d8536b4Sopenharmony_ci#endif
4483d8536b4Sopenharmony_ci#ifdef CLOCK_BOOTTIME_ALARM
4493d8536b4Sopenharmony_ci        case CLOCK_BOOTTIME_ALARM:
4503d8536b4Sopenharmony_ci#endif
4513d8536b4Sopenharmony_ci#ifdef CLOCK_SGI_CYCLE
4523d8536b4Sopenharmony_ci        case CLOCK_SGI_CYCLE:
4533d8536b4Sopenharmony_ci#endif
4543d8536b4Sopenharmony_ci#ifdef CLOCK_TAI
4553d8536b4Sopenharmony_ci        case CLOCK_TAI:
4563d8536b4Sopenharmony_ci#endif
4573d8536b4Sopenharmony_ci            if (flags == 0 || flags == TIMER_ABSTIME) {
4583d8536b4Sopenharmony_ci                return ENOTSUP;
4593d8536b4Sopenharmony_ci            }
4603d8536b4Sopenharmony_ci            /* fallthrough */
4613d8536b4Sopenharmony_ci        case CLOCK_THREAD_CPUTIME_ID:
4623d8536b4Sopenharmony_ci        default:
4633d8536b4Sopenharmony_ci            return EINVAL;
4643d8536b4Sopenharmony_ci    }
4653d8536b4Sopenharmony_ci}
4663d8536b4Sopenharmony_ci
4673d8536b4Sopenharmony_ciclock_t clock(void)
4683d8536b4Sopenharmony_ci{
4693d8536b4Sopenharmony_ci    if (g_rtcTimeFunc.RtcGetTickHook != NULL) {
4703d8536b4Sopenharmony_ci        return g_rtcTimeFunc.RtcGetTickHook();
4713d8536b4Sopenharmony_ci    }
4723d8536b4Sopenharmony_ci
4733d8536b4Sopenharmony_ci    clock_t clk;
4743d8536b4Sopenharmony_ci    struct timespec hwTime;
4753d8536b4Sopenharmony_ci    OsGetHwTime(&hwTime);
4763d8536b4Sopenharmony_ci
4773d8536b4Sopenharmony_ci    clk = hwTime.tv_sec * CLOCKS_PER_SEC;
4783d8536b4Sopenharmony_ci    clk += hwTime.tv_nsec  / (OS_SYS_NS_PER_SECOND / CLOCKS_PER_SEC);
4793d8536b4Sopenharmony_ci
4803d8536b4Sopenharmony_ci    return clk;
4813d8536b4Sopenharmony_ci}
4823d8536b4Sopenharmony_ci
4833d8536b4Sopenharmony_ciSTATIC UINT64 GetCurrentTime(VOID)
4843d8536b4Sopenharmony_ci{
4853d8536b4Sopenharmony_ci    UINT64 tickDelta = 0;
4863d8536b4Sopenharmony_ci    UINT64 currentTick;
4873d8536b4Sopenharmony_ci
4883d8536b4Sopenharmony_ci    if (g_rtcTimeFunc.RtcGetTickHook != NULL) {
4893d8536b4Sopenharmony_ci        currentTick = g_rtcTimeFunc.RtcGetTickHook();
4903d8536b4Sopenharmony_ci        if ((g_systickBase != 0) && (currentTick > g_systickBase)) {
4913d8536b4Sopenharmony_ci            tickDelta = currentTick - g_systickBase;
4923d8536b4Sopenharmony_ci        }
4933d8536b4Sopenharmony_ci    }
4943d8536b4Sopenharmony_ci    return g_rtcTimeBase + LOS_Tick2MS((UINT32)tickDelta);
4953d8536b4Sopenharmony_ci}
4963d8536b4Sopenharmony_ci
4973d8536b4Sopenharmony_citime_t time(time_t *timer)
4983d8536b4Sopenharmony_ci{
4993d8536b4Sopenharmony_ci    UINT64 usec = 0;
5003d8536b4Sopenharmony_ci    time_t sec;
5013d8536b4Sopenharmony_ci    INT32 rtcRet;
5023d8536b4Sopenharmony_ci
5033d8536b4Sopenharmony_ci    if (g_rtcTimeFunc.RtcGetTimeHook != NULL) {
5043d8536b4Sopenharmony_ci        rtcRet = g_rtcTimeFunc.RtcGetTimeHook(&usec);
5053d8536b4Sopenharmony_ci        if (rtcRet != 0) {
5063d8536b4Sopenharmony_ci            UINT64 currentTime;
5073d8536b4Sopenharmony_ci            currentTime = GetCurrentTime();
5083d8536b4Sopenharmony_ci            sec = currentTime / OS_SYS_MS_PER_SECOND;
5093d8536b4Sopenharmony_ci        } else {
5103d8536b4Sopenharmony_ci            sec = usec / OS_SYS_US_PER_SECOND;
5113d8536b4Sopenharmony_ci        }
5123d8536b4Sopenharmony_ci        if (timer != NULL) {
5133d8536b4Sopenharmony_ci            *timer = sec;
5143d8536b4Sopenharmony_ci        }
5153d8536b4Sopenharmony_ci        return sec;
5163d8536b4Sopenharmony_ci    } else {
5173d8536b4Sopenharmony_ci        struct timespec ts;
5183d8536b4Sopenharmony_ci        if (-1 == clock_gettime(CLOCK_REALTIME, &ts)) {
5193d8536b4Sopenharmony_ci            return (time_t)-1;
5203d8536b4Sopenharmony_ci        }
5213d8536b4Sopenharmony_ci
5223d8536b4Sopenharmony_ci        if (timer != NULL) {
5233d8536b4Sopenharmony_ci            *timer = ts.tv_sec;
5243d8536b4Sopenharmony_ci        }
5253d8536b4Sopenharmony_ci        return ts.tv_sec;
5263d8536b4Sopenharmony_ci    }
5273d8536b4Sopenharmony_ci}
5283d8536b4Sopenharmony_ci
5293d8536b4Sopenharmony_ci/*
5303d8536b4Sopenharmony_ci * Compute the `struct tm' representation of T,
5313d8536b4Sopenharmony_ci * offset OFFSET seconds east of UTC,
5323d8536b4Sopenharmony_ci * and store year, yday, mon, mday, wday, hour, min, sec into *TP.
5333d8536b4Sopenharmony_ci * Return nonzero if successful.
5343d8536b4Sopenharmony_ci */
5353d8536b4Sopenharmony_cistatic INT32 ConvertSecs2Utc(time_t t, INT32 offset, struct tm *tp)
5363d8536b4Sopenharmony_ci{
5373d8536b4Sopenharmony_ci    time_t days;
5383d8536b4Sopenharmony_ci    time_t rem;
5393d8536b4Sopenharmony_ci    time_t year;
5403d8536b4Sopenharmony_ci    time_t month;
5413d8536b4Sopenharmony_ci    time_t yearGuess;
5423d8536b4Sopenharmony_ci
5433d8536b4Sopenharmony_ci    days = t / SECS_PER_DAY;
5443d8536b4Sopenharmony_ci    rem = t % SECS_PER_DAY;
5453d8536b4Sopenharmony_ci    rem += offset;
5463d8536b4Sopenharmony_ci    while (rem < 0) {
5473d8536b4Sopenharmony_ci        rem += SECS_PER_DAY;
5483d8536b4Sopenharmony_ci        --days;
5493d8536b4Sopenharmony_ci    }
5503d8536b4Sopenharmony_ci    while (rem >= SECS_PER_DAY) {
5513d8536b4Sopenharmony_ci        rem -= SECS_PER_DAY;
5523d8536b4Sopenharmony_ci        ++days;
5533d8536b4Sopenharmony_ci    }
5543d8536b4Sopenharmony_ci    tp->tm_hour = rem / SECS_PER_HOUR;
5553d8536b4Sopenharmony_ci    rem %= SECS_PER_HOUR;
5563d8536b4Sopenharmony_ci    tp->tm_min = rem / SECS_PER_MIN;
5573d8536b4Sopenharmony_ci    tp->tm_sec = rem % SECS_PER_MIN;
5583d8536b4Sopenharmony_ci    /* January 1, 1970 was a Thursday.  */
5593d8536b4Sopenharmony_ci    tp->tm_wday = (BEGIN_WEEKDAY + days) % DAYS_PER_WEEK;
5603d8536b4Sopenharmony_ci    if (tp->tm_wday < 0) {
5613d8536b4Sopenharmony_ci        tp->tm_wday += DAYS_PER_WEEK;
5623d8536b4Sopenharmony_ci    }
5633d8536b4Sopenharmony_ci    year = EPOCH_YEAR;
5643d8536b4Sopenharmony_ci
5653d8536b4Sopenharmony_ci    while ((days < 0) ||
5663d8536b4Sopenharmony_ci           (days >= (IS_LEAP_YEAR (year) ? DAYS_PER_LEAP_YEAR : DAYS_PER_NORMAL_YEAR))) {
5673d8536b4Sopenharmony_ci        /* Guess a corrected year, assuming 365 days per year.  */
5683d8536b4Sopenharmony_ci        yearGuess = year + days / DAYS_PER_NORMAL_YEAR - (days % DAYS_PER_NORMAL_YEAR < 0);
5693d8536b4Sopenharmony_ci
5703d8536b4Sopenharmony_ci        /* Adjust days and year to match the guessed year.  */
5713d8536b4Sopenharmony_ci        days -= ((yearGuess - year) * DAYS_PER_NORMAL_YEAR +
5723d8536b4Sopenharmony_ci                 LEAPS_THRU_END_OF (yearGuess - 1) -
5733d8536b4Sopenharmony_ci                 LEAPS_THRU_END_OF (year - 1));
5743d8536b4Sopenharmony_ci        year = yearGuess;
5753d8536b4Sopenharmony_ci    }
5763d8536b4Sopenharmony_ci    tp->tm_year = year - TM_YEAR_BASE;
5773d8536b4Sopenharmony_ci    if (tp->tm_year != year - TM_YEAR_BASE) {
5783d8536b4Sopenharmony_ci        return 0;
5793d8536b4Sopenharmony_ci    }
5803d8536b4Sopenharmony_ci    tp->tm_yday = days;
5813d8536b4Sopenharmony_ci    const UINT16 *daysInMonth = g_daysInMonth[IS_LEAP_YEAR(year)];
5823d8536b4Sopenharmony_ci    /* valid month value is 0-11 */
5833d8536b4Sopenharmony_ci    for (month = 11; days < (long int) daysInMonth[month]; --month) {
5843d8536b4Sopenharmony_ci        continue;
5853d8536b4Sopenharmony_ci    }
5863d8536b4Sopenharmony_ci    days -= daysInMonth[month];
5873d8536b4Sopenharmony_ci    tp->tm_mon = month;
5883d8536b4Sopenharmony_ci    tp->tm_mday = days + 1;
5893d8536b4Sopenharmony_ci    tp->__tm_gmtoff = offset;
5903d8536b4Sopenharmony_ci    tp->__tm_zone = NULL;
5913d8536b4Sopenharmony_ci    tp->tm_isdst = 0;
5923d8536b4Sopenharmony_ci    return 1;
5933d8536b4Sopenharmony_ci}
5943d8536b4Sopenharmony_ci
5953d8536b4Sopenharmony_cistruct tm *gmtime_r(const time_t *timep, struct tm *result)
5963d8536b4Sopenharmony_ci{
5973d8536b4Sopenharmony_ci    if ((timep == NULL) || (result == NULL)) {
5983d8536b4Sopenharmony_ci        errno = EFAULT;
5993d8536b4Sopenharmony_ci        return NULL;
6003d8536b4Sopenharmony_ci    }
6013d8536b4Sopenharmony_ci    if (!ConvertSecs2Utc(*timep, 0, result)) {
6023d8536b4Sopenharmony_ci        errno = EINVAL;
6033d8536b4Sopenharmony_ci        return NULL;
6043d8536b4Sopenharmony_ci    }
6053d8536b4Sopenharmony_ci    return result;
6063d8536b4Sopenharmony_ci}
6073d8536b4Sopenharmony_ci
6083d8536b4Sopenharmony_cistruct tm *gmtime(const time_t *timer)
6093d8536b4Sopenharmony_ci{
6103d8536b4Sopenharmony_ci    static struct tm tm;
6113d8536b4Sopenharmony_ci    return gmtime_r(timer, &tm);
6123d8536b4Sopenharmony_ci}
6133d8536b4Sopenharmony_ci
6143d8536b4Sopenharmony_cistruct tm *localtime_r(const time_t *timep, struct tm *result)
6153d8536b4Sopenharmony_ci{
6163d8536b4Sopenharmony_ci    INT32 ret;
6173d8536b4Sopenharmony_ci
6183d8536b4Sopenharmony_ci    if ((timep == NULL) || (result == NULL)) {
6193d8536b4Sopenharmony_ci        errno = EFAULT;
6203d8536b4Sopenharmony_ci        return NULL;
6213d8536b4Sopenharmony_ci    }
6223d8536b4Sopenharmony_ci
6233d8536b4Sopenharmony_ci    if (g_rtcTimeFunc.RtcGetTimezoneHook != NULL) {
6243d8536b4Sopenharmony_ci        INT32 tempTimezone = 0;
6253d8536b4Sopenharmony_ci        g_rtcTimeFunc.RtcGetTimezoneHook(&tempTimezone);
6263d8536b4Sopenharmony_ci        ret = ConvertSecs2Utc(*timep, -tempTimezone, result);
6273d8536b4Sopenharmony_ci    } else {
6283d8536b4Sopenharmony_ci        ret = ConvertSecs2Utc(*timep, -TIMEZONE, result);
6293d8536b4Sopenharmony_ci    }
6303d8536b4Sopenharmony_ci
6313d8536b4Sopenharmony_ci    if (!ret) {
6323d8536b4Sopenharmony_ci        errno = EINVAL;
6333d8536b4Sopenharmony_ci        return NULL;
6343d8536b4Sopenharmony_ci    }
6353d8536b4Sopenharmony_ci    return result;
6363d8536b4Sopenharmony_ci}
6373d8536b4Sopenharmony_ci
6383d8536b4Sopenharmony_cistruct tm *localtime(const time_t *timer)
6393d8536b4Sopenharmony_ci{
6403d8536b4Sopenharmony_ci    static struct tm tm;
6413d8536b4Sopenharmony_ci    return localtime_r(timer, &tm);
6423d8536b4Sopenharmony_ci}
6433d8536b4Sopenharmony_ci
6443d8536b4Sopenharmony_cistatic time_t ConvertUtc2Secs(struct tm *tm)
6453d8536b4Sopenharmony_ci{
6463d8536b4Sopenharmony_ci    time_t seconds = 0;
6473d8536b4Sopenharmony_ci    INT32 month = 0;
6483d8536b4Sopenharmony_ci    UINT8 leap = 0;
6493d8536b4Sopenharmony_ci
6503d8536b4Sopenharmony_ci    INT32 year = (EPOCH_YEAR - TM_YEAR_BASE);
6513d8536b4Sopenharmony_ci    while (year < tm->tm_year) {
6523d8536b4Sopenharmony_ci        seconds += SECS_PER_NORMAL_YEAR;
6533d8536b4Sopenharmony_ci        if (IS_LEAP_YEAR(year + TM_YEAR_BASE)) {
6543d8536b4Sopenharmony_ci            seconds += SECS_PER_DAY;
6553d8536b4Sopenharmony_ci        }
6563d8536b4Sopenharmony_ci        year++;
6573d8536b4Sopenharmony_ci    }
6583d8536b4Sopenharmony_ci
6593d8536b4Sopenharmony_ci    if (IS_LEAP_YEAR(tm->tm_year + TM_YEAR_BASE)) {
6603d8536b4Sopenharmony_ci        leap = 1;
6613d8536b4Sopenharmony_ci    }
6623d8536b4Sopenharmony_ci    while (month < tm->tm_mon) {
6633d8536b4Sopenharmony_ci        if ((month == 1) && leap) {
6643d8536b4Sopenharmony_ci            seconds += (g_montbl[month] + 1) * SECS_PER_DAY;
6653d8536b4Sopenharmony_ci        } else {
6663d8536b4Sopenharmony_ci            seconds += g_montbl[month] * SECS_PER_DAY;
6673d8536b4Sopenharmony_ci        }
6683d8536b4Sopenharmony_ci        month++;
6693d8536b4Sopenharmony_ci    }
6703d8536b4Sopenharmony_ci
6713d8536b4Sopenharmony_ci    seconds += (tm->tm_mday - 1) * SECS_PER_DAY;
6723d8536b4Sopenharmony_ci    seconds += tm->tm_hour * SECS_PER_HOUR + tm->tm_min * SECS_PER_MIN + tm->tm_sec;
6733d8536b4Sopenharmony_ci
6743d8536b4Sopenharmony_ci    if (g_rtcTimeFunc.RtcGetTimezoneHook != NULL) {
6753d8536b4Sopenharmony_ci        INT32 tempTimezone = 0;
6763d8536b4Sopenharmony_ci        g_rtcTimeFunc.RtcGetTimezoneHook(&tempTimezone);
6773d8536b4Sopenharmony_ci        seconds += tempTimezone;
6783d8536b4Sopenharmony_ci    } else {
6793d8536b4Sopenharmony_ci        seconds += TIMEZONE;
6803d8536b4Sopenharmony_ci    }
6813d8536b4Sopenharmony_ci
6823d8536b4Sopenharmony_ci    return seconds;
6833d8536b4Sopenharmony_ci}
6843d8536b4Sopenharmony_ci
6853d8536b4Sopenharmony_citime_t mktime(struct tm *tmptr)
6863d8536b4Sopenharmony_ci{
6873d8536b4Sopenharmony_ci    time_t timeInSeconds;
6883d8536b4Sopenharmony_ci    if (tmptr == NULL) {
6893d8536b4Sopenharmony_ci        errno = EFAULT;
6903d8536b4Sopenharmony_ci        return (time_t)-1;
6913d8536b4Sopenharmony_ci    }
6923d8536b4Sopenharmony_ci
6933d8536b4Sopenharmony_ci    /* tm_isdst is not supported and is ignored */
6943d8536b4Sopenharmony_ci    if (tmptr->tm_year < (EPOCH_YEAR - TM_YEAR_BASE) ||
6953d8536b4Sopenharmony_ci            tmptr->__tm_gmtoff > (-TIME_ZONE_MIN * SECS_PER_MIN) ||
6963d8536b4Sopenharmony_ci            tmptr->__tm_gmtoff < (-TIME_ZONE_MAX * SECS_PER_MIN) ||
6973d8536b4Sopenharmony_ci            tmptr->tm_sec > 60 || tmptr->tm_sec < 0 ||      /* Seconds [0-60] */
6983d8536b4Sopenharmony_ci            tmptr->tm_min > 59 || tmptr->tm_min < 0 ||      /* Minutes [0-59] */
6993d8536b4Sopenharmony_ci            tmptr->tm_hour > 23 || tmptr->tm_hour < 0 ||    /* Hours [0-23] */
7003d8536b4Sopenharmony_ci            tmptr->tm_mday > 31 || tmptr->tm_mday < 1 ||    /* Day of the month [1-31] */
7013d8536b4Sopenharmony_ci            tmptr->tm_mon > 11 || tmptr->tm_mon < 0) {      /* Month [0-11] */
7023d8536b4Sopenharmony_ci        errno = EOVERFLOW;
7033d8536b4Sopenharmony_ci        return (time_t)-1;
7043d8536b4Sopenharmony_ci    }
7053d8536b4Sopenharmony_ci    timeInSeconds = ConvertUtc2Secs(tmptr);
7063d8536b4Sopenharmony_ci    /* normalize tm_wday and tm_yday */
7073d8536b4Sopenharmony_ci    if (g_rtcTimeFunc.RtcGetTimezoneHook != NULL) {
7083d8536b4Sopenharmony_ci        INT32 tempTimezone = 0;
7093d8536b4Sopenharmony_ci        g_rtcTimeFunc.RtcGetTimezoneHook(&tempTimezone);
7103d8536b4Sopenharmony_ci        ConvertSecs2Utc(timeInSeconds, -tempTimezone, tmptr);
7113d8536b4Sopenharmony_ci    } else {
7123d8536b4Sopenharmony_ci        ConvertSecs2Utc(timeInSeconds, -TIMEZONE, tmptr);
7133d8536b4Sopenharmony_ci    }
7143d8536b4Sopenharmony_ci
7153d8536b4Sopenharmony_ci    return timeInSeconds;
7163d8536b4Sopenharmony_ci}
7173d8536b4Sopenharmony_ci
7183d8536b4Sopenharmony_ciint gettimeofday(struct timeval *tv, void *ptz)
7193d8536b4Sopenharmony_ci{
7203d8536b4Sopenharmony_ci    struct timezone *tz = (struct timezone *)ptz;
7213d8536b4Sopenharmony_ci
7223d8536b4Sopenharmony_ci    if (tv != NULL) {
7233d8536b4Sopenharmony_ci        UINT64 usec = 0;
7243d8536b4Sopenharmony_ci
7253d8536b4Sopenharmony_ci        if ((g_rtcTimeFunc.RtcGetTimeHook != NULL) && (g_rtcTimeFunc.RtcGetTimeHook(&usec) == 0)) {
7263d8536b4Sopenharmony_ci            tv->tv_sec = usec / OS_SYS_US_PER_SECOND;
7273d8536b4Sopenharmony_ci            tv->tv_usec = usec % OS_SYS_US_PER_SECOND;
7283d8536b4Sopenharmony_ci        } else {
7293d8536b4Sopenharmony_ci            struct timespec ts;
7303d8536b4Sopenharmony_ci            if (-1 == clock_gettime(CLOCK_REALTIME, &ts)) {
7313d8536b4Sopenharmony_ci                return -1;
7323d8536b4Sopenharmony_ci            }
7333d8536b4Sopenharmony_ci            tv->tv_sec = ts.tv_sec;
7343d8536b4Sopenharmony_ci            tv->tv_usec = ts.tv_nsec / OS_SYS_NS_PER_US;
7353d8536b4Sopenharmony_ci        }
7363d8536b4Sopenharmony_ci    }
7373d8536b4Sopenharmony_ci
7383d8536b4Sopenharmony_ci    if (tz != NULL) {
7393d8536b4Sopenharmony_ci        if (g_rtcTimeFunc.RtcGetTimezoneHook != NULL) {
7403d8536b4Sopenharmony_ci            INT32 tempTimezone = 0;
7413d8536b4Sopenharmony_ci            g_rtcTimeFunc.RtcGetTimezoneHook(&tempTimezone);
7423d8536b4Sopenharmony_ci            tz->tz_minuteswest = tempTimezone / SECS_PER_MIN;
7433d8536b4Sopenharmony_ci        } else {
7443d8536b4Sopenharmony_ci            tz->tz_minuteswest = TIMEZONE / SECS_PER_MIN;
7453d8536b4Sopenharmony_ci        }
7463d8536b4Sopenharmony_ci
7473d8536b4Sopenharmony_ci        tz->tz_dsttime = 0;
7483d8536b4Sopenharmony_ci    }
7493d8536b4Sopenharmony_ci    return 0;
7503d8536b4Sopenharmony_ci}
7513d8536b4Sopenharmony_ci#if (LOSCFG_LIBC_NEWLIB == 1)
7523d8536b4Sopenharmony_ciFUNC_ALIAS(gettimeofday, _gettimeofday, (struct timeval *tv, void *ptz), int);
7533d8536b4Sopenharmony_ci#endif
7543d8536b4Sopenharmony_ci
7553d8536b4Sopenharmony_ciint settimeofday(const struct timeval *tv, const struct timezone *tz)
7563d8536b4Sopenharmony_ci{
7573d8536b4Sopenharmony_ci    struct timespec ts;
7583d8536b4Sopenharmony_ci
7593d8536b4Sopenharmony_ci    if ((tv == NULL) && (tz == NULL)) {
7603d8536b4Sopenharmony_ci        errno = EFAULT;
7613d8536b4Sopenharmony_ci        return -1;
7623d8536b4Sopenharmony_ci    }
7633d8536b4Sopenharmony_ci
7643d8536b4Sopenharmony_ci    if ((tv != NULL) && (tv->tv_usec >= OS_SYS_US_PER_SECOND)) {
7653d8536b4Sopenharmony_ci        errno = EINVAL;
7663d8536b4Sopenharmony_ci        return -1;
7673d8536b4Sopenharmony_ci    }
7683d8536b4Sopenharmony_ci
7693d8536b4Sopenharmony_ci    if (tz != NULL) {
7703d8536b4Sopenharmony_ci        if ((tz->tz_minuteswest >= TIME_ZONE_MIN) &&
7713d8536b4Sopenharmony_ci            (tz->tz_minuteswest <= TIME_ZONE_MAX)) {
7723d8536b4Sopenharmony_ci            TIMEZONE = tz->tz_minuteswest * SECS_PER_MIN;
7733d8536b4Sopenharmony_ci        } else {
7743d8536b4Sopenharmony_ci            errno = EINVAL;
7753d8536b4Sopenharmony_ci            return -1;
7763d8536b4Sopenharmony_ci        }
7773d8536b4Sopenharmony_ci
7783d8536b4Sopenharmony_ci        if (g_rtcTimeFunc.RtcSetTimezoneHook != NULL) {
7793d8536b4Sopenharmony_ci            g_rtcTimeFunc.RtcSetTimezoneHook(TIMEZONE);
7803d8536b4Sopenharmony_ci        }
7813d8536b4Sopenharmony_ci    }
7823d8536b4Sopenharmony_ci
7833d8536b4Sopenharmony_ci    if (tv != NULL) {
7843d8536b4Sopenharmony_ci        if (g_rtcTimeFunc.RtcSetTimeHook != NULL) {
7853d8536b4Sopenharmony_ci            UINT64 usec;
7863d8536b4Sopenharmony_ci            g_rtcTimeBase = tv->tv_sec * OS_SYS_MS_PER_SECOND + tv->tv_usec / OS_SYS_MS_PER_SECOND;
7873d8536b4Sopenharmony_ci            usec = tv->tv_sec * OS_SYS_US_PER_SECOND + tv->tv_usec;
7883d8536b4Sopenharmony_ci            if (g_rtcTimeFunc.RtcSetTimeHook(g_rtcTimeBase, &usec) < 0) {
7893d8536b4Sopenharmony_ci                return -1;
7903d8536b4Sopenharmony_ci            }
7913d8536b4Sopenharmony_ci        } else {
7923d8536b4Sopenharmony_ci            ts.tv_sec = tv->tv_sec;
7933d8536b4Sopenharmony_ci            ts.tv_nsec = tv->tv_usec * OS_SYS_NS_PER_US;
7943d8536b4Sopenharmony_ci            if (clock_settime(CLOCK_REALTIME, &ts) < 0) {
7953d8536b4Sopenharmony_ci                return -1;
7963d8536b4Sopenharmony_ci            }
7973d8536b4Sopenharmony_ci        }
7983d8536b4Sopenharmony_ci    }
7993d8536b4Sopenharmony_ci
8003d8536b4Sopenharmony_ci    if (g_rtcTimeFunc.RtcGetTickHook != NULL) {
8013d8536b4Sopenharmony_ci        g_systickBase = g_rtcTimeFunc.RtcGetTickHook();
8023d8536b4Sopenharmony_ci    }
8033d8536b4Sopenharmony_ci
8043d8536b4Sopenharmony_ci    return 0;
8053d8536b4Sopenharmony_ci}
8063d8536b4Sopenharmony_ci
8073d8536b4Sopenharmony_ciint usleep(useconds_t useconds)
8083d8536b4Sopenharmony_ci{
8093d8536b4Sopenharmony_ci    struct timespec specTime = { 0 };
8103d8536b4Sopenharmony_ci    UINT64 nanoseconds = (UINT64)useconds * OS_SYS_NS_PER_US;
8113d8536b4Sopenharmony_ci
8123d8536b4Sopenharmony_ci    specTime.tv_sec = (time_t)(nanoseconds / OS_SYS_NS_PER_SECOND);
8133d8536b4Sopenharmony_ci    specTime.tv_nsec = (long)(nanoseconds % OS_SYS_NS_PER_SECOND);
8143d8536b4Sopenharmony_ci    return nanosleep(&specTime, NULL);
8153d8536b4Sopenharmony_ci}
8163d8536b4Sopenharmony_ci
8173d8536b4Sopenharmony_ciunsigned sleep(unsigned seconds)
8183d8536b4Sopenharmony_ci{
8193d8536b4Sopenharmony_ci    struct timespec specTime = { 0 };
8203d8536b4Sopenharmony_ci    UINT64 nanoseconds = (UINT64)seconds * OS_SYS_NS_PER_SECOND;
8213d8536b4Sopenharmony_ci
8223d8536b4Sopenharmony_ci    specTime.tv_sec = (time_t)(nanoseconds / OS_SYS_NS_PER_SECOND);
8233d8536b4Sopenharmony_ci    specTime.tv_nsec = (long)(nanoseconds % OS_SYS_NS_PER_SECOND);
8243d8536b4Sopenharmony_ci    return nanosleep(&specTime, NULL);
8253d8536b4Sopenharmony_ci}
8263d8536b4Sopenharmony_ci
8273d8536b4Sopenharmony_ciclock_t times(struct tms *tms)
8283d8536b4Sopenharmony_ci{
8293d8536b4Sopenharmony_ci    clock_t clockTick = (clock_t)LOS_TickCountGet();
8303d8536b4Sopenharmony_ci
8313d8536b4Sopenharmony_ci    if (tms != NULL) {
8323d8536b4Sopenharmony_ci        tms->tms_cstime = clockTick;
8333d8536b4Sopenharmony_ci        tms->tms_cutime = clockTick;
8343d8536b4Sopenharmony_ci        tms->tms_stime  = clockTick;
8353d8536b4Sopenharmony_ci        tms->tms_utime  = clockTick;
8363d8536b4Sopenharmony_ci    }
8373d8536b4Sopenharmony_ci    return clockTick;
8383d8536b4Sopenharmony_ci}
839