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