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