• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3  * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice, this list of
9  *    conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12  *    of conditions and the following disclaimer in the documentation and/or other materials
13  *    provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16  *    to endorse or promote products derived from this software without specific prior written
17  *    permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include "time.h"
33 #include "stdint.h"
34 #include "stdio.h"
35 #include "sys/times.h"
36 #include "time_posix.h"
37 #include "unistd.h"
38 #ifdef LOSCFG_SECURITY_CAPABILITY
39 #include "capability_api.h"
40 #endif
41 #include "los_signal.h"
42 #ifdef LOSCFG_KERNEL_VDSO
43 #include "los_vdso.h"
44 #endif
45 #ifdef LOSCFG_SECURITY_VID
46 #include "vid_api.h"
47 #endif
48 #include "user_copy.h"
49 #include "los_process_pri.h"
50 #include "los_swtmr_pri.h"
51 #include "los_sys_pri.h"
52 
53 #define CPUCLOCK_PERTHREAD_MASK 4
54 #define CPUCLOCK_ID_OFFSET 3
55 
56 /*
57  * Do a time package defined return. This requires the error code
58  * to be placed in errno, and if it is non-zero, -1 returned as the
59  * result of the function. This also gives us a place to put any
60  * generic tidyup handling needed for things like signal delivery and
61  * cancellation.
62  */
63 #define TIME_RETURN(err) do { \
64     INT32 retVal = 0;         \
65     if ((err) != 0) {         \
66         retVal = -1;          \
67         errno = (err);        \
68     }                         \
69     return retVal;            \
70 } while (0)
71 
72 #ifdef LOSCFG_AARCH64
73 /*
74  * This two structures originally didn't exit,
75  * they added by liteos to support 64bit interfaces on 32bit platform,
76  * in 64bit platform, timeval64 define to timeval which is platform adaptive.
77  */
78 #define timeval64 timeval
79 #define timespec64 timespec
80 #endif
81 
ValidTimeval(const struct timeval * tv)82 STATIC INLINE BOOL ValidTimeval(const struct timeval *tv)
83 {
84     /* Fail a NULL pointer */
85     if (tv == NULL) {
86         return FALSE;
87     }
88 
89     /* Fail illegal microseconds values */
90     if ((tv->tv_usec < 0) || (tv->tv_usec >= OS_SYS_US_PER_SECOND) || (tv->tv_sec < 0)) {
91         return FALSE;
92     }
93 
94     return TRUE;
95 }
96 
ValidTimeval64(const struct timeval64 * tv)97 STATIC INLINE BOOL ValidTimeval64(const struct timeval64 *tv)
98 {
99     /* Fail a NULL pointer */
100     if (tv == NULL) {
101         return FALSE;
102     }
103 
104     /* Fail illegal microseconds values */
105     if ((tv->tv_usec < 0) || (tv->tv_usec >= OS_SYS_US_PER_SECOND) || (tv->tv_sec < 0)) {
106         return FALSE;
107     }
108 
109     return TRUE;
110 }
111 
ValidTimerID(UINT16 swtmrID)112 STATIC INLINE BOOL ValidTimerID(UINT16 swtmrID)
113 {
114     /* check timer id */
115     if (swtmrID >= OS_SWTMR_MAX_TIMERID) {
116         return FALSE;
117     }
118 
119     /* check owner of this timer */
120     if (OS_SWT_FROM_SID(swtmrID)->uwOwnerPid != (UINTPTR)OsCurrProcessGet()) {
121         return FALSE;
122     }
123 
124     return TRUE;
125 }
126 
127 STATIC SPIN_LOCK_INIT(g_timeSpin);
128 STATIC long long g_adjTimeLeft; /* absolute value of adjtime */
129 STATIC INT32 g_adjDirection;    /* 1, speed up; 0, slow down; */
130 
131 /* Adjust pacement, nanoseconds per SCHED_CLOCK_INTETRVAL_TICKS ticks */
132 STATIC const long long g_adjPacement = (((LOSCFG_BASE_CORE_ADJ_PER_SECOND * SCHED_CLOCK_INTETRVAL_TICKS) /
133                                         LOSCFG_BASE_CORE_TICK_PER_SECOND) * OS_SYS_NS_PER_US);
134 
135 /* accumulative time delta from continuous modify, such as adjtime */
136 STATIC struct timespec64 g_accDeltaFromAdj;
137 /* accumulative time delta from discontinuous modify, such as settimeofday */
138 STATIC struct timespec64 g_accDeltaFromSet;
139 
OsAdjTime(VOID)140 VOID OsAdjTime(VOID)
141 {
142     UINT32 intSave;
143 
144     LOS_SpinLockSave(&g_timeSpin, &intSave);
145     if (!g_adjTimeLeft) {
146         LOS_SpinUnlockRestore(&g_timeSpin, intSave);
147         return;
148     }
149 
150     if (g_adjTimeLeft > g_adjPacement) {
151         if (g_adjDirection) {
152             if ((g_accDeltaFromAdj.tv_nsec + g_adjPacement) >= OS_SYS_NS_PER_SECOND) {
153                 g_accDeltaFromAdj.tv_sec++;
154                 g_accDeltaFromAdj.tv_nsec  = (g_accDeltaFromAdj.tv_nsec + g_adjPacement) % OS_SYS_NS_PER_SECOND;
155             } else {
156                 g_accDeltaFromAdj.tv_nsec  = g_accDeltaFromAdj.tv_nsec + g_adjPacement;
157             }
158         } else {
159             if ((g_accDeltaFromAdj.tv_nsec - g_adjPacement) < 0) {
160                 g_accDeltaFromAdj.tv_sec--;
161                 g_accDeltaFromAdj.tv_nsec  = g_accDeltaFromAdj.tv_nsec - g_adjPacement + OS_SYS_NS_PER_SECOND;
162             } else {
163                 g_accDeltaFromAdj.tv_nsec  = g_accDeltaFromAdj.tv_nsec - g_adjPacement;
164             }
165         }
166 
167         g_adjTimeLeft -= g_adjPacement;
168     } else {
169         if (g_adjDirection) {
170             if ((g_accDeltaFromAdj.tv_nsec + g_adjTimeLeft) >= OS_SYS_NS_PER_SECOND) {
171                 g_accDeltaFromAdj.tv_sec++;
172                 g_accDeltaFromAdj.tv_nsec  = (g_accDeltaFromAdj.tv_nsec + g_adjTimeLeft) % OS_SYS_NS_PER_SECOND;
173             } else {
174                 g_accDeltaFromAdj.tv_nsec  = g_accDeltaFromAdj.tv_nsec + g_adjTimeLeft;
175             }
176         } else {
177             if ((g_accDeltaFromAdj.tv_nsec - g_adjTimeLeft) < 0) {
178                 g_accDeltaFromAdj.tv_sec--;
179                 g_accDeltaFromAdj.tv_nsec  = g_accDeltaFromAdj.tv_nsec - g_adjTimeLeft + OS_SYS_NS_PER_SECOND;
180             } else {
181                 g_accDeltaFromAdj.tv_nsec  = g_accDeltaFromAdj.tv_nsec - g_adjTimeLeft;
182             }
183         }
184 
185         g_adjTimeLeft = 0;
186     }
187     LOS_SpinUnlockRestore(&g_timeSpin, intSave);
188     return;
189 }
190 
191 /*
192  * Function: adjtime
193  * Description:  correct the time to synchronize the system clock.
194  * Input:     delta - The amount of time by which the clock is to be adjusted.
195  * Output: oldDelta - the amount of time remaining from any previous adjustment that has not yet been completed.
196  * Return: On success, returns 0.  On failure, -1 is returned, and errno is set to indicate the error.
197  */
adjtime(const struct timeval * delta,struct timeval * oldDelta)198 int adjtime(const struct timeval *delta, struct timeval *oldDelta)
199 {
200     UINT32 intSave;
201     LOS_SpinLockSave(&g_timeSpin, &intSave);
202     /* return the amount of time remaining from any previous adjustment that has not yet been completed. */
203     if (oldDelta != NULL) {
204         if (g_adjDirection == 1) {
205             oldDelta->tv_sec = g_adjTimeLeft / OS_SYS_NS_PER_SECOND;
206             oldDelta->tv_usec = (g_adjTimeLeft % OS_SYS_NS_PER_SECOND) / OS_SYS_NS_PER_US;
207         } else {
208             oldDelta->tv_sec = -(g_adjTimeLeft / OS_SYS_NS_PER_SECOND);
209             oldDelta->tv_usec = -((g_adjTimeLeft % OS_SYS_NS_PER_SECOND) / OS_SYS_NS_PER_US);
210         }
211     }
212 
213     if ((delta == NULL) || ((delta->tv_sec == 0) && (delta->tv_usec == 0))) {
214         LOS_SpinUnlockRestore(&g_timeSpin, intSave);
215         return 0;
216     }
217 
218     if ((delta->tv_usec > OS_SYS_US_PER_SECOND) || (delta->tv_usec < -OS_SYS_US_PER_SECOND)) {
219         LOS_SpinUnlockRestore(&g_timeSpin, intSave);
220         TIME_RETURN(EINVAL);
221     }
222 
223     /*
224      * 2: in the glibc implementation, delta must be less than or equal to (INT_MAX / 1000000 - 2) and
225      * greater than or equal to (INT_MIN / 1000000 + 2)
226      */
227     if ((delta->tv_sec < (INT_MIN / OS_SYS_US_PER_SECOND + 2)) ||
228         (delta->tv_sec > (INT_MAX / OS_SYS_US_PER_SECOND + 2))) {
229         LOS_SpinUnlockRestore(&g_timeSpin, intSave);
230         TIME_RETURN(EINVAL);
231     }
232 
233     g_adjTimeLeft = (INT64)delta->tv_sec * OS_SYS_NS_PER_SECOND + delta->tv_usec * OS_SYS_NS_PER_US;
234     if (g_adjTimeLeft > 0) {
235         g_adjDirection = 1;
236     } else {
237         g_adjDirection = 0;
238         g_adjTimeLeft = -g_adjTimeLeft;
239     }
240 
241     LOS_SpinUnlockRestore(&g_timeSpin, intSave);
242     return 0;
243 }
244 
OsTimeSpecAdd(const struct timespec64 t1,const struct timespec64 t2)245 STATIC INLINE struct timespec64 OsTimeSpecAdd(const struct timespec64 t1, const struct timespec64 t2)
246 {
247     struct timespec64 ret = {0};
248 
249     ret.tv_sec = t1.tv_sec + t2.tv_sec;
250     ret.tv_nsec = t1.tv_nsec + t2.tv_nsec;
251     if (ret.tv_nsec >= OS_SYS_NS_PER_SECOND) {
252         ret.tv_sec += 1;
253         ret.tv_nsec -= OS_SYS_NS_PER_SECOND;
254     } else if (ret.tv_nsec < 0L) {
255         ret.tv_sec -= 1;
256         ret.tv_nsec += OS_SYS_NS_PER_SECOND;
257     }
258 
259     return ret;
260 }
261 
OsTimeSpecSub(const struct timespec64 t1,const struct timespec64 t2)262 STATIC INLINE struct timespec64 OsTimeSpecSub(const struct timespec64 t1, const struct timespec64 t2)
263 {
264     struct timespec64 ret = {0};
265 
266     ret.tv_sec = t1.tv_sec - t2.tv_sec;
267     ret.tv_nsec = t1.tv_nsec - t2.tv_nsec;
268     if (ret.tv_nsec < 0) {
269         ret.tv_sec -= 1;
270         ret.tv_nsec += OS_SYS_NS_PER_SECOND;
271     }
272 
273     return ret;
274 }
275 
OsGetHwTime(struct timespec64 * hwTime)276 STATIC VOID OsGetHwTime(struct timespec64 *hwTime)
277 {
278     UINT64 nowNsec;
279 
280     nowNsec = LOS_CurrNanosec();
281     hwTime->tv_sec = nowNsec / OS_SYS_NS_PER_SECOND;
282     hwTime->tv_nsec = nowNsec - hwTime->tv_sec * OS_SYS_NS_PER_SECOND;
283 }
284 
OsSetTimeOfDay(const struct timeval64 * tv,const struct timezone * tz)285 STATIC INT32 OsSetTimeOfDay(const struct timeval64 *tv, const struct timezone *tz)
286 {
287     UINT32 intSave;
288     struct timespec64 setTime = {0};
289     struct timespec64 hwTime = {0};
290     struct timespec64 realTime = {0};
291     struct timespec64 tmp = {0};
292 
293 #ifdef LOSCFG_SECURITY_CAPABILITY
294     if (!IsCapPermit(CAP_SET_TIMEOFDAY)) {
295         TIME_RETURN(EPERM);
296     }
297 #endif
298 
299     (VOID)tz;
300     OsGetHwTime(&hwTime);
301     setTime.tv_sec = tv->tv_sec;
302     setTime.tv_nsec = tv->tv_usec * OS_SYS_NS_PER_US;
303 
304     LOS_SpinLockSave(&g_timeSpin, &intSave);
305     /* stop on-going continuous adjusement */
306     if (g_adjTimeLeft) {
307         g_adjTimeLeft = 0;
308     }
309     realTime = OsTimeSpecAdd(hwTime, g_accDeltaFromAdj);
310     realTime = OsTimeSpecAdd(realTime, g_accDeltaFromSet);
311 
312     tmp = OsTimeSpecSub(setTime, realTime);
313     g_accDeltaFromSet = OsTimeSpecAdd(g_accDeltaFromSet, tmp);
314 
315     LOS_SpinUnlockRestore(&g_timeSpin, intSave);
316 
317     return 0;
318 }
319 
settimeofday(const struct timeval * tv,const struct timezone * tz)320 int settimeofday(const struct timeval *tv, const struct timezone *tz)
321 {
322     struct timeval64 stTimeVal64 = {0};
323 
324     if (!ValidTimeval(tv)) {
325         TIME_RETURN(EINVAL);
326     }
327 
328     stTimeVal64.tv_sec = tv->tv_sec;
329     stTimeVal64.tv_usec = tv->tv_usec;
330 
331     return OsSetTimeOfDay(&stTimeVal64, tz);
332 }
333 
334 #ifndef LOSCFG_AARCH64
settimeofday64(const struct timeval64 * tv,const struct timezone * tz)335 int settimeofday64(const struct timeval64 *tv, const struct timezone *tz)
336 {
337     if (!ValidTimeval64(tv)) {
338         TIME_RETURN(EINVAL);
339     }
340 
341     return OsSetTimeOfDay(tv, tz);
342 }
343 #endif
344 
setlocalseconds(int seconds)345 int setlocalseconds(int seconds)
346 {
347     struct timeval tv = {0};
348 
349     tv.tv_sec = seconds;
350     tv.tv_usec = 0;
351 
352     return settimeofday(&tv, NULL);
353 }
354 
OsGetTimeOfDay(struct timeval64 * tv,struct timezone * tz)355 STATIC INT32 OsGetTimeOfDay(struct timeval64 *tv, struct timezone *tz)
356 {
357     UINT32 intSave;
358 
359     (VOID)tz;
360     struct timespec64 hwTime = {0};
361     struct timespec64 realTime = {0};
362 
363     OsGetHwTime(&hwTime);
364 
365     LOS_SpinLockSave(&g_timeSpin, &intSave);
366     realTime = OsTimeSpecAdd(hwTime, g_accDeltaFromAdj);
367     realTime = OsTimeSpecAdd(realTime, g_accDeltaFromSet);
368     LOS_SpinUnlockRestore(&g_timeSpin, intSave);
369 
370     tv->tv_sec = realTime.tv_sec;
371     tv->tv_usec = realTime.tv_nsec / OS_SYS_NS_PER_US;
372 
373     if (tv->tv_sec < 0) {
374         TIME_RETURN(EINVAL);
375     }
376     return 0;
377 }
378 
379 #ifndef LOSCFG_AARCH64
gettimeofday64(struct timeval64 * tv,struct timezone * tz)380 int gettimeofday64(struct timeval64 *tv, struct timezone *tz)
381 {
382     if (tv == NULL) {
383         TIME_RETURN(EINVAL);
384     }
385 
386     return OsGetTimeOfDay(tv, tz);
387 }
388 #endif
389 
390 #ifdef LOSCFG_LIBC_NEWLIB
gettimeofday(struct timeval * tv,void * _tz)391 int gettimeofday(struct timeval *tv, void *_tz)
392 #else
393 int gettimeofday(struct timeval *tv, struct timezone *tz)
394 #endif
395 {
396     struct timeval64 stTimeVal64 = {0};
397 #ifdef LOSCFG_LIBC_NEWLIB
398     struct timezone *tz = (struct timezone *)_tz;
399 #endif
400 
401     if (tv == NULL) {
402         TIME_RETURN(EINVAL);
403     }
404 
405     if (OsGetTimeOfDay(&stTimeVal64, tz) == -1) {
406         return -1;
407     }
408 
409 #ifdef LOSCFG_AARCH64
410     tv->tv_sec = stTimeVal64.tv_sec;
411     tv->tv_usec = stTimeVal64.tv_usec;
412 #else
413     if (stTimeVal64.tv_sec > (long long)LONG_MAX) {
414         return -1;
415     }
416     tv->tv_sec = (time_t)stTimeVal64.tv_sec;
417     tv->tv_usec = (suseconds_t)stTimeVal64.tv_usec;
418 #endif
419 
420     return 0;
421 }
422 
clock_settime(clockid_t clockID,const struct timespec * tp)423 int clock_settime(clockid_t clockID, const struct timespec *tp)
424 {
425     struct timeval tv = {0};
426 
427     switch (clockID) {
428         case CLOCK_REALTIME:
429             /* we only support the realtime clock currently */
430             break;
431         case CLOCK_MONOTONIC_COARSE:
432         case CLOCK_REALTIME_COARSE:
433         case CLOCK_MONOTONIC_RAW:
434         case CLOCK_PROCESS_CPUTIME_ID:
435         case CLOCK_BOOTTIME:
436         case CLOCK_REALTIME_ALARM:
437         case CLOCK_BOOTTIME_ALARM:
438         case CLOCK_TAI:
439         case CLOCK_THREAD_CPUTIME_ID:
440             TIME_RETURN(ENOTSUP);
441         case CLOCK_MONOTONIC:
442         default:
443             TIME_RETURN(EINVAL);
444     }
445 
446     if (!ValidTimeSpec(tp)) {
447         TIME_RETURN(EINVAL);
448     }
449 
450 #ifdef LOSCFG_SECURITY_CAPABILITY
451     if (!IsCapPermit(CAP_CLOCK_SETTIME)) {
452         TIME_RETURN(EPERM);
453     }
454 #endif
455 
456     tv.tv_sec = tp->tv_sec;
457     tv.tv_usec = tp->tv_nsec / OS_SYS_NS_PER_US;
458     return settimeofday(&tv, NULL);
459 }
460 
461 #ifdef LOSCFG_KERNEL_CPUP
GetTidFromClockID(clockid_t clockID)462 inline UINT32 GetTidFromClockID(clockid_t clockID)
463 {
464     // In musl/src/thread/pthread_getcpuclockid.c, we know 'clockid = (-tid - 1) * 8 + 6'
465     UINT32 tid = -(clockID - 6) / 8 - 1; // 6 8 1 inverse operation from clockID to tid
466     return tid;
467 }
468 
GetPidFromClockID(clockid_t clockID)469 inline const pid_t GetPidFromClockID(clockid_t clockID)
470 {
471     // In musl/src/time/clock_getcpuclockid.c, we know 'clockid = (-pid - 1) * 8 + 2'
472     const pid_t pid = -(clockID - 2) / 8 - 1; // 2 8 1 inverse operation from clockID to pid
473     return pid;
474 }
475 
PthreadGetCputime(clockid_t clockID,struct timespec * ats)476 static int PthreadGetCputime(clockid_t clockID, struct timespec *ats)
477 {
478     uint64_t runtime;
479     UINT32 intSave;
480     UINT32 tid = GetTidFromClockID(clockID);
481     if (OS_TID_CHECK_INVALID(tid)) {
482         return -EINVAL;
483     }
484 
485     LosTaskCB *task = OsGetTaskCB(tid);
486 
487     if (OsCurrTaskGet()->processCB != task->processCB) {
488         return -EINVAL;
489     }
490 
491     SCHEDULER_LOCK(intSave);
492     runtime = task->taskCpup.allTime;
493     SCHEDULER_UNLOCK(intSave);
494 
495     ats->tv_sec = runtime / OS_SYS_NS_PER_SECOND;
496     ats->tv_nsec = runtime % OS_SYS_NS_PER_SECOND;
497 
498     return 0;
499 }
500 
ProcessGetCputime(clockid_t clockID,struct timespec * ats)501 static int ProcessGetCputime(clockid_t clockID, struct timespec *ats)
502 {
503     UINT64 runtime;
504     UINT32 intSave;
505     const pid_t pid = GetPidFromClockID(clockID);
506     LosProcessCB *spcb = NULL;
507 
508     if (OsProcessIDUserCheckInvalid(pid) || pid < 0) {
509         return -EINVAL;
510     }
511 
512     spcb = OS_PCB_FROM_PID(pid);
513     if (OsProcessIsUnused(spcb)) {
514         return -EINVAL;
515     }
516 
517     SCHEDULER_LOCK(intSave);
518     if (spcb->processCpup == NULL) {
519         SCHEDULER_UNLOCK(intSave);
520         return -EINVAL;
521     }
522     runtime = spcb->processCpup->allTime;
523     SCHEDULER_UNLOCK(intSave);
524 
525     ats->tv_sec = runtime / OS_SYS_NS_PER_SECOND;
526     ats->tv_nsec = runtime % OS_SYS_NS_PER_SECOND;
527 
528     return 0;
529 }
530 
GetCputime(clockid_t clockID,struct timespec * tp)531 static int GetCputime(clockid_t clockID, struct timespec *tp)
532 {
533     int ret;
534 
535     if (clockID >= 0) {
536         return -EINVAL;
537     }
538 
539     if ((UINT32)clockID & CPUCLOCK_PERTHREAD_MASK) {
540         ret = PthreadGetCputime(clockID, tp);
541     } else {
542         ret = ProcessGetCputime(clockID, tp);
543     }
544 
545     return ret;
546 }
547 
CheckClock(const clockid_t clockID)548 static int CheckClock(const clockid_t clockID)
549 {
550     int error = 0;
551     const pid_t pid = GetPidFromClockID(clockID);
552 
553     if (!((UINT32)clockID & CPUCLOCK_PERTHREAD_MASK)) {
554         LosProcessCB *spcb = NULL;
555         if (OsProcessIDUserCheckInvalid(pid) || pid < 0) {
556             return -EINVAL;
557         }
558         spcb = OS_PCB_FROM_PID(pid);
559         if (OsProcessIsUnused(spcb)) {
560             error = -EINVAL;
561         }
562     } else {
563         error = -EINVAL;
564     }
565 
566     return error;
567 }
568 
CpuClockGetres(const clockid_t clockID,struct timespec * tp)569 static int CpuClockGetres(const clockid_t clockID, struct timespec *tp)
570 {
571     if (clockID > 0) {
572         return -EINVAL;
573     }
574 
575     int error = CheckClock(clockID);
576     if (!error) {
577         error = ProcessGetCputime(clockID, tp);
578     }
579 
580     return error;
581 }
582 #endif
583 
clock_gettime(clockid_t clockID,struct timespec * tp)584 int clock_gettime(clockid_t clockID, struct timespec *tp)
585 {
586     UINT32 intSave;
587     struct timespec64 tmp = {0};
588     struct timespec64 hwTime = {0};
589 
590     if (clockID > MAX_CLOCKS) {
591         goto ERROUT;
592     }
593 
594     if (tp == NULL) {
595         goto ERROUT;
596     }
597 
598     OsGetHwTime(&hwTime);
599 
600     switch (clockID) {
601         case CLOCK_MONOTONIC_RAW:
602 #ifdef LOSCFG_TIME_CONTAINER
603             tmp = OsTimeSpecAdd(hwTime, CLOCK_MONOTONIC_TIME_BASE);
604             tp->tv_sec = tmp.tv_sec;
605             tp->tv_nsec = tmp.tv_nsec;
606 #else
607             tp->tv_sec = hwTime.tv_sec;
608             tp->tv_nsec = hwTime.tv_nsec;
609 #endif
610             break;
611         case CLOCK_MONOTONIC:
612             LOS_SpinLockSave(&g_timeSpin, &intSave);
613             tmp = OsTimeSpecAdd(hwTime, g_accDeltaFromAdj);
614             LOS_SpinUnlockRestore(&g_timeSpin, intSave);
615 #ifdef LOSCFG_TIME_CONTAINER
616             tmp = OsTimeSpecAdd(tmp, CLOCK_MONOTONIC_TIME_BASE);
617 #endif
618             tp->tv_sec = tmp.tv_sec;
619             tp->tv_nsec = tmp.tv_nsec;
620             break;
621         case CLOCK_REALTIME:
622             LOS_SpinLockSave(&g_timeSpin, &intSave);
623             tmp = OsTimeSpecAdd(hwTime, g_accDeltaFromAdj);
624             tmp = OsTimeSpecAdd(tmp, g_accDeltaFromSet);
625             LOS_SpinUnlockRestore(&g_timeSpin, intSave);
626             tp->tv_sec = tmp.tv_sec;
627             tp->tv_nsec = tmp.tv_nsec;
628             break;
629         case CLOCK_MONOTONIC_COARSE:
630         case CLOCK_REALTIME_COARSE:
631         case CLOCK_THREAD_CPUTIME_ID:
632         case CLOCK_PROCESS_CPUTIME_ID:
633         case CLOCK_BOOTTIME:
634         case CLOCK_REALTIME_ALARM:
635         case CLOCK_BOOTTIME_ALARM:
636         case CLOCK_TAI:
637             TIME_RETURN(ENOTSUP);
638         default:
639         {
640 #ifdef LOSCFG_KERNEL_CPUP
641             int ret = GetCputime(clockID, tp);
642                 TIME_RETURN(-ret);
643 #else
644             TIME_RETURN(EINVAL);
645 #endif
646         }
647     }
648 
649     return 0;
650 
651 ERROUT:
652     TIME_RETURN(EINVAL);
653 }
654 
clock_getres(clockid_t clockID,struct timespec * tp)655 int clock_getres(clockid_t clockID, struct timespec *tp)
656 {
657     if (tp == NULL) {
658         TIME_RETURN(EINVAL);
659     }
660 
661     switch (clockID) {
662         case CLOCK_MONOTONIC_RAW:
663         case CLOCK_MONOTONIC:
664         case CLOCK_REALTIME:
665             /* the accessible rtc resolution */
666             tp->tv_nsec = OS_SYS_NS_PER_US; /* the precision of clock_gettime is 1us */
667             tp->tv_sec = 0;
668             break;
669         case CLOCK_MONOTONIC_COARSE:
670         case CLOCK_REALTIME_COARSE:
671             /* the clock coarse resolution, supported by vdso.
672              * the precision of clock_gettime is 1tick */
673             tp->tv_nsec = OS_SYS_NS_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND;
674             tp->tv_sec = 0;
675             break;
676         case CLOCK_THREAD_CPUTIME_ID:
677         case CLOCK_PROCESS_CPUTIME_ID:
678         case CLOCK_BOOTTIME:
679         case CLOCK_REALTIME_ALARM:
680         case CLOCK_BOOTTIME_ALARM:
681         case CLOCK_TAI:
682             TIME_RETURN(ENOTSUP);
683         default:
684 #ifdef LOSCFG_KERNEL_CPUP
685             {
686                 int ret = CpuClockGetres(clockID, tp);
687                 TIME_RETURN(-ret);
688             }
689 #else
690             TIME_RETURN(EINVAL);
691 #endif
692     }
693 
694     TIME_RETURN(0);
695 }
696 
clock_nanosleep(clockid_t clk,int flags,const struct timespec * req,struct timespec * rem)697 int clock_nanosleep(clockid_t clk, int flags, const struct timespec *req, struct timespec *rem)
698 {
699     switch (clk) {
700         case CLOCK_REALTIME:
701             if (flags == 0) {
702                 /* we only support the realtime clock currently */
703                 return nanosleep(req, rem);
704             }
705             /* fallthrough */
706         case CLOCK_MONOTONIC_COARSE:
707         case CLOCK_REALTIME_COARSE:
708         case CLOCK_MONOTONIC_RAW:
709         case CLOCK_MONOTONIC:
710         case CLOCK_PROCESS_CPUTIME_ID:
711         case CLOCK_BOOTTIME:
712         case CLOCK_REALTIME_ALARM:
713         case CLOCK_BOOTTIME_ALARM:
714         case CLOCK_TAI:
715             if (flags == 0 || flags == TIMER_ABSTIME) {
716                 TIME_RETURN(ENOTSUP);
717             }
718             /* fallthrough */
719         case CLOCK_THREAD_CPUTIME_ID:
720         default:
721             TIME_RETURN(EINVAL);
722     }
723 
724     TIME_RETURN(0);
725 }
726 
727 typedef struct {
728     int sigev_signo;
729     pid_t pid;
730     unsigned int tid;
731     union sigval sigev_value;
732 } swtmr_proc_arg;
733 
SwtmrProc(UINTPTR tmrArg)734 static VOID SwtmrProc(UINTPTR tmrArg)
735 {
736 #ifdef LOSCFG_KERNEL_VM
737     INT32 sig, ret;
738     UINT32 intSave;
739     pid_t pid;
740     siginfo_t info;
741     LosTaskCB *stcb = NULL;
742 
743     swtmr_proc_arg *arg = (swtmr_proc_arg *)tmrArg;
744     OS_GOTO_EXIT_IF(arg == NULL, EINVAL);
745 
746     sig = arg->sigev_signo;
747     pid = arg->pid;
748     OS_GOTO_EXIT_IF(!GOOD_SIGNO(sig), EINVAL);
749 
750     /* Create the siginfo structure */
751     info.si_signo = sig;
752     info.si_code = SI_TIMER;
753     info.si_value.sival_ptr = arg->sigev_value.sival_ptr;
754 
755     /* Send signals to threads or processes */
756     if (arg->tid > 0) {
757         /* Make sure that the para is valid */
758         OS_GOTO_EXIT_IF(OS_TID_CHECK_INVALID(arg->tid), EINVAL);
759         stcb = OsGetTaskCB(arg->tid);
760         ret = OsUserProcessOperatePermissionsCheck(stcb, stcb->processCB);
761         OS_GOTO_EXIT_IF(ret != LOS_OK, -ret);
762 
763         /* Dispatch the signal to thread, bypassing normal task group thread
764          * dispatch rules. */
765         SCHEDULER_LOCK(intSave);
766         ret = OsTcbDispatch(stcb, &info);
767         SCHEDULER_UNLOCK(intSave);
768         OS_GOTO_EXIT_IF(ret != LOS_OK, -ret);
769     } else {
770         /* Make sure that the para is valid */
771         OS_GOTO_EXIT_IF(pid <= 0 || OS_PID_CHECK_INVALID(pid), EINVAL);
772         /* Dispatch the signal to process */
773         SCHEDULER_LOCK(intSave);
774         OsDispatch(pid, &info, OS_USER_KILL_PERMISSION);
775         SCHEDULER_UNLOCK(intSave);
776     }
777     return;
778 EXIT:
779     PRINT_ERR("Dispatch signals failed!, ret: %d\r\n", ret);
780 #endif
781     return;
782 }
783 
timer_create(clockid_t clockID,struct sigevent * restrict evp,timer_t * restrict timerID)784 int timer_create(clockid_t clockID, struct sigevent *restrict evp, timer_t *restrict timerID)
785 {
786     UINT32 ret;
787     UINT16 swtmrID;
788 #ifdef LOSCFG_SECURITY_VID
789     UINT16 vid;
790 #endif
791 
792     if (!timerID || (clockID != CLOCK_REALTIME) || !evp) {
793         errno = EINVAL;
794         return -1;
795     }
796 
797     if ((evp->sigev_notify != SIGEV_THREAD) || evp->sigev_notify_attributes) {
798         errno = ENOTSUP;
799         return -1;
800     }
801 
802     ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_ONCE, (SWTMR_PROC_FUNC)evp->sigev_notify_function,
803                           &swtmrID, (UINTPTR)evp->sigev_value.sival_ptr);
804     if (ret != LOS_OK) {
805         errno = (ret == LOS_ERRNO_SWTMR_MAXSIZE) ? EAGAIN : EINVAL;
806         return -1;
807     }
808 
809 #ifdef LOSCFG_SECURITY_VID
810     vid = AddNodeByRid(swtmrID);
811     if (vid == MAX_INVALID_TIMER_VID) {
812         (VOID)LOS_SwtmrDelete(swtmrID);
813         return -1;
814     }
815     swtmrID = vid;
816 #endif
817     *timerID = (timer_t)(UINTPTR)swtmrID;
818     return 0;
819 }
820 
OsTimerCreate(clockid_t clockID,struct ksigevent * evp,timer_t * timerID)821 int OsTimerCreate(clockid_t clockID, struct ksigevent *evp, timer_t *timerID)
822 {
823     UINT32 ret;
824     UINT16 swtmrID;
825     swtmr_proc_arg *arg = NULL;
826     int signo;
827 #ifdef LOSCFG_SECURITY_VID
828     UINT16 vid;
829 #endif
830 
831     if ((clockID != CLOCK_REALTIME) || (timerID == NULL)) {
832         errno = EINVAL;
833         return -1;
834     }
835 
836     signo = evp ? evp->sigev_signo : SIGALRM;
837     if (signo > SIGRTMAX || signo < 1) {
838         errno = EINVAL;
839         return -1;
840     }
841     if (evp && (evp->sigev_notify != SIGEV_SIGNAL && evp->sigev_notify != SIGEV_THREAD_ID)) {
842         errno = ENOTSUP;
843         return -1;
844     }
845 
846     arg = (swtmr_proc_arg *)malloc(sizeof(swtmr_proc_arg));
847     if (arg == NULL) {
848         errno = ENOMEM;
849         return -1;
850     }
851 
852     arg->tid = evp ? evp->sigev_tid : 0;
853     arg->sigev_signo = signo;
854     arg->pid = LOS_GetCurrProcessID();
855     arg->sigev_value.sival_ptr = evp ? evp->sigev_value.sival_ptr : NULL;
856     ret = LOS_SwtmrCreate(1, LOS_SWTMR_MODE_ONCE, SwtmrProc, &swtmrID, (UINTPTR)arg);
857     if (ret != LOS_OK) {
858         errno = (ret == LOS_ERRNO_SWTMR_MAXSIZE) ? EAGAIN : EINVAL;
859         free(arg);
860         return -1;
861     }
862 
863 #ifdef LOSCFG_SECURITY_VID
864     vid = AddNodeByRid(swtmrID);
865     if (vid == MAX_INVALID_TIMER_VID) {
866         free(arg);
867         (VOID)LOS_SwtmrDelete(swtmrID);
868         return -1;
869     }
870     swtmrID = vid;
871 #endif
872     *timerID = (timer_t)(UINTPTR)swtmrID;
873     return 0;
874 }
875 
timer_delete(timer_t timerID)876 int timer_delete(timer_t timerID)
877 {
878     UINT16 swtmrID = (UINT16)(UINTPTR)timerID;
879     VOID *arg = NULL;
880     UINTPTR swtmrProc;
881 
882 #ifdef LOSCFG_SECURITY_VID
883     swtmrID = GetRidByVid(swtmrID);
884 #endif
885     if (OS_INT_ACTIVE || !ValidTimerID(swtmrID)) {
886         goto ERROUT;
887     }
888 
889     arg = (VOID *)OS_SWT_FROM_SID(swtmrID)->uwArg;
890     swtmrProc = (UINTPTR)OS_SWT_FROM_SID(swtmrID)->pfnHandler;
891     if (LOS_SwtmrDelete(swtmrID)) {
892         goto ERROUT;
893     }
894     if ((swtmrProc == (UINTPTR)SwtmrProc) && (arg != NULL)) {
895         free(arg);
896     }
897 
898 #ifdef LOSCFG_SECURITY_VID
899     RemoveNodeByVid((UINT16)(UINTPTR)timerID);
900 #endif
901     return 0;
902 
903 ERROUT:
904     errno = EINVAL;
905     return -1;
906 }
907 
timer_settime(timer_t timerID,int flags,const struct itimerspec * value,struct itimerspec * oldValue)908 int timer_settime(timer_t timerID, int flags,
909                   const struct itimerspec *value,   /* new value */
910                   struct itimerspec *oldValue)      /* old value to return, always 0 */
911 {
912     UINT16 swtmrID = (UINT16)(UINTPTR)timerID;
913     SWTMR_CTRL_S *swtmr = NULL;
914     UINT32 interval, expiry, ret;
915     UINT32 intSave;
916 
917     if (flags != 0) {
918         /* flags not supported currently */
919         errno = ENOSYS;
920         return -1;
921     }
922 
923 #ifdef LOSCFG_SECURITY_VID
924     swtmrID = GetRidByVid(swtmrID);
925 #endif
926     if ((value == NULL) || OS_INT_ACTIVE || !ValidTimerID(swtmrID)) {
927         errno = EINVAL;
928         return -1;
929     }
930 
931     if (!ValidTimeSpec(&value->it_value) || !ValidTimeSpec(&value->it_interval)) {
932         errno = EINVAL;
933         return -1;
934     }
935 
936     if (oldValue) {
937         (VOID)timer_gettime(timerID, oldValue);
938     }
939 
940     swtmr = OS_SWT_FROM_SID(swtmrID);
941     ret = LOS_SwtmrStop(swtmr->usTimerID);
942     if ((ret != LOS_OK) && (ret != LOS_ERRNO_SWTMR_NOT_STARTED)) {
943         errno = EINVAL;
944         return -1;
945     }
946 
947     expiry = OsTimeSpec2Tick(&value->it_value);
948     interval = OsTimeSpec2Tick(&value->it_interval);
949 
950     LOS_SpinLockSave(&g_swtmrSpin, &intSave);
951     swtmr->ucMode = interval ? LOS_SWTMR_MODE_OPP : LOS_SWTMR_MODE_NO_SELFDELETE;
952     swtmr->uwExpiry = expiry + !!expiry; // PS: skip the first tick because it is NOT a full tick.
953     swtmr->uwInterval = interval;
954     swtmr->uwOverrun = 0;
955     LOS_SpinUnlockRestore(&g_swtmrSpin, intSave);
956 
957     if ((value->it_value.tv_sec == 0) && (value->it_value.tv_nsec == 0)) {
958         /*
959          * 1) when expiry is 0, means timer should be stopped.
960          * 2) If timer is ticking, stopping timer is already done before.
961          * 3) If timer is created but not ticking, return 0 as well.
962          */
963         return 0;
964     }
965 
966     if (LOS_SwtmrStart(swtmr->usTimerID)) {
967         errno = EINVAL;
968         return -1;
969     }
970 
971     return 0;
972 }
973 
timer_gettime(timer_t timerID,struct itimerspec * value)974 int timer_gettime(timer_t timerID, struct itimerspec *value)
975 {
976     UINT32 tick = 0;
977     SWTMR_CTRL_S *swtmr = NULL;
978     UINT16 swtmrID = (UINT16)(UINTPTR)timerID;
979     UINT32 ret;
980 
981 #ifdef LOSCFG_SECURITY_VID
982     swtmrID = GetRidByVid(swtmrID);
983 #endif
984     if ((value == NULL) || !ValidTimerID(swtmrID)) {
985         errno = EINVAL;
986         return -1;
987     }
988 
989     swtmr = OS_SWT_FROM_SID(swtmrID);
990 
991     /* get expire time */
992     ret = LOS_SwtmrTimeGet(swtmr->usTimerID, &tick);
993     if ((ret != LOS_OK) && (ret != LOS_ERRNO_SWTMR_NOT_STARTED)) {
994         errno = EINVAL;
995         return -1;
996     }
997 
998     OsTick2TimeSpec(&value->it_value, tick);
999     OsTick2TimeSpec(&value->it_interval, (swtmr->ucMode == LOS_SWTMR_MODE_ONCE) ? 0 : swtmr->uwInterval);
1000     return 0;
1001 }
1002 
timer_getoverrun(timer_t timerID)1003 int timer_getoverrun(timer_t timerID)
1004 {
1005     UINT16 swtmrID = (UINT16)(UINTPTR)timerID;
1006     SWTMR_CTRL_S *swtmr = NULL;
1007     INT32 overRun;
1008 
1009 #ifdef LOSCFG_SECURITY_VID
1010     swtmrID = GetRidByVid(swtmrID);
1011 #endif
1012     if (!ValidTimerID(swtmrID)) {
1013         errno = EINVAL;
1014         return -1;
1015     }
1016 
1017     swtmr = OS_SWT_FROM_SID(swtmrID);
1018     if (swtmr->usTimerID >= OS_SWTMR_MAX_TIMERID) {
1019         errno = EINVAL;
1020         return -1;
1021     }
1022 
1023     overRun = (INT32)(swtmr->uwOverrun);
1024     return (overRun > DELAYTIMER_MAX) ? DELAYTIMER_MAX : overRun;
1025 }
1026 
DoNanoSleep(UINT64 nanoseconds)1027 STATIC INT32 DoNanoSleep(UINT64 nanoseconds)
1028 {
1029     UINT32 ret;
1030 
1031     ret = LOS_TaskDelay(OsNS2Tick(nanoseconds));
1032     if (ret == LOS_OK || ret == LOS_ERRNO_TSK_YIELD_NOT_ENOUGH_TASK) {
1033         return 0;
1034     }
1035     return -1;
1036 }
1037 
1038 #ifdef LOSCFG_LIBC_NEWLIB
usleep(unsigned long useconds)1039 int usleep(unsigned long useconds)
1040 #else
1041 int usleep(unsigned useconds)
1042 #endif
1043 {
1044     return DoNanoSleep((UINT64)useconds * OS_SYS_NS_PER_US);
1045 }
1046 
nanosleep(const struct timespec * rqtp,struct timespec * rmtp)1047 int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
1048 {
1049     UINT64 nanoseconds;
1050     INT32 ret = -1;
1051 
1052     (VOID)rmtp;
1053     /* expire time */
1054 
1055     if (!ValidTimeSpec(rqtp)) {
1056         errno = EINVAL;
1057         return ret;
1058     }
1059 
1060     nanoseconds = (UINT64)rqtp->tv_sec * OS_SYS_NS_PER_SECOND + rqtp->tv_nsec;
1061 
1062     return DoNanoSleep(nanoseconds);
1063 }
1064 
sleep(unsigned int seconds)1065 unsigned int sleep(unsigned int seconds)
1066 {
1067     return DoNanoSleep((UINT64)seconds * OS_SYS_NS_PER_SECOND);
1068 }
1069 
difftime(time_t time2,time_t time1)1070 double difftime(time_t time2, time_t time1)
1071 {
1072     return (double)(time2 - time1);
1073 }
1074 
clock(VOID)1075 clock_t clock(VOID)
1076 {
1077     clock_t clockMsec;
1078     UINT64 nowNsec;
1079 
1080     nowNsec = LOS_CurrNanosec();
1081     clockMsec = (clock_t)(nowNsec / (OS_SYS_NS_PER_SECOND / CLOCKS_PER_SEC));
1082 
1083     return clockMsec;
1084 }
1085 
times(struct tms * buf)1086 clock_t times(struct tms *buf)
1087 {
1088     clock_t clockTick = -1;
1089 
1090     (void)buf;
1091     set_errno(ENOSYS);
1092 
1093     return clockTick;
1094 }
1095 
setitimer(int which,const struct itimerval * value,struct itimerval * ovalue)1096 int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue)
1097 {
1098     UINT32 intSave;
1099     LosProcessCB *processCB = OsCurrProcessGet();
1100     timer_t timerID = 0;
1101     struct itimerspec spec;
1102     struct itimerspec ospec;
1103     int ret = LOS_OK;
1104 
1105     /* we only support the realtime clock timer currently */
1106     if (which != ITIMER_REAL || !value) {
1107         set_errno(EINVAL);
1108         return -1;
1109     }
1110 
1111     /* To avoid creating an invalid timer after the timer has already been create */
1112     if (processCB->timerID == (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID) {
1113         ret = OsTimerCreate(CLOCK_REALTIME, NULL, &timerID);
1114         if (ret != LOS_OK) {
1115             return ret;
1116         }
1117     }
1118 
1119     /* The initialization of this global timer must be in spinlock
1120      * OsTimerCreate cannot be located in spinlock.
1121      */
1122     SCHEDULER_LOCK(intSave);
1123     if (processCB->timerID == (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID) {
1124         processCB->timerID = timerID;
1125         SCHEDULER_UNLOCK(intSave);
1126     } else {
1127         SCHEDULER_UNLOCK(intSave);
1128         if (timerID) {
1129             timer_delete(timerID);
1130         }
1131     }
1132 
1133     if (!ValidTimeval(&value->it_value) || !ValidTimeval(&value->it_interval)) {
1134         set_errno(EINVAL);
1135         return -1;
1136     }
1137 
1138     TIMEVAL_TO_TIMESPEC(&value->it_value, &spec.it_value);
1139     TIMEVAL_TO_TIMESPEC(&value->it_interval, &spec.it_interval);
1140 
1141     ret = timer_settime(processCB->timerID, 0, &spec, ovalue ? &ospec : NULL);
1142     if (ret == LOS_OK && ovalue) {
1143         TIMESPEC_TO_TIMEVAL(&ovalue->it_value, &ospec.it_value);
1144         TIMESPEC_TO_TIMEVAL(&ovalue->it_interval, &ospec.it_interval);
1145     }
1146 
1147     return ret;
1148 }
1149 
getitimer(int which,struct itimerval * value)1150 int getitimer(int which, struct itimerval *value)
1151 {
1152     LosProcessCB *processCB = OsCurrProcessGet();
1153     struct itimerspec spec = {};
1154 
1155     int ret = LOS_OK;
1156 
1157     /* we only support the realtime clock timer currently */
1158     if (which != ITIMER_REAL || !value) {
1159         set_errno(EINVAL);
1160         return -1;
1161     }
1162 
1163     if (processCB->timerID != (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID) {
1164         ret = timer_gettime(processCB->timerID, &spec);
1165     }
1166 
1167     if (ret == LOS_OK) {
1168         TIMESPEC_TO_TIMEVAL(&value->it_value, &spec.it_value);
1169         TIMESPEC_TO_TIMEVAL(&value->it_interval, &spec.it_interval);
1170     }
1171 
1172     return ret;
1173 }
1174 
1175 #ifdef LOSCFG_KERNEL_VDSO
OsVdsoTimeGet(VdsoDataPage * vdsoDataPage)1176 VOID OsVdsoTimeGet(VdsoDataPage *vdsoDataPage)
1177 {
1178     UINT32 intSave;
1179     struct timespec64 tmp = {0};
1180     struct timespec64 hwTime = {0};
1181 
1182     if (vdsoDataPage == NULL) {
1183         return;
1184     }
1185 
1186     OsGetHwTime(&hwTime);
1187 
1188     LOS_SpinLockSave(&g_timeSpin, &intSave);
1189     tmp = OsTimeSpecAdd(hwTime, g_accDeltaFromAdj);
1190     vdsoDataPage->monoTimeSec = tmp.tv_sec;
1191     vdsoDataPage->monoTimeNsec = tmp.tv_nsec;
1192 
1193     tmp = OsTimeSpecAdd(tmp, g_accDeltaFromSet);
1194     vdsoDataPage->realTimeSec = tmp.tv_sec;
1195     vdsoDataPage->realTimeNsec = tmp.tv_nsec;
1196     LOS_SpinUnlockRestore(&g_timeSpin, intSave);
1197 }
1198 #endif
1199 
time(time_t * t)1200 time_t time(time_t *t)
1201 {
1202     struct timeval tp;
1203     int ret;
1204 
1205     /* Get the current time from the system */
1206     ret = gettimeofday(&tp, (struct timezone *)NULL);
1207     if (ret == LOS_OK) {
1208         /* Return the seconds since the epoch */
1209         if (t) {
1210             *t = tp.tv_sec;
1211         }
1212         return tp.tv_sec;
1213     }
1214     return (time_t)OS_ERROR;
1215 }
1216