1 /*
2  * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include "osal_time.h"
10 #include <errno.h>
11 #include <sys/time.h>
12 #include <time.h>
13 #include <unistd.h>
14 #include "securec.h"
15 #include "hdf_log.h"
16 
17 #define HDF_LOG_TAG osal_time
18 
OsalGetTime(OsalTimespec * time)19 int32_t OsalGetTime(OsalTimespec *time)
20 {
21     struct timespec ts;
22 
23     if (time == NULL) {
24         HDF_LOGE("%s invalid para", __func__);
25         return HDF_ERR_INVALID_PARAM;
26     }
27 
28     (void)memset_s(&ts, sizeof(ts), 0, sizeof(ts));
29     clock_gettime(CLOCK_MONOTONIC, &ts);
30     time->sec = (uint64_t)ts.tv_sec;
31     time->usec = (uint64_t)ts.tv_nsec / HDF_KILO_UNIT;
32 
33     return HDF_SUCCESS;
34 }
35 
OsalDiffTime(const OsalTimespec * start,const OsalTimespec * end,OsalTimespec * diff)36 int32_t OsalDiffTime(const OsalTimespec *start, const OsalTimespec *end, OsalTimespec *diff)
37 {
38     uint32_t usec = 0;
39     uint32_t sec = 0;
40     if (start == NULL || end == NULL || diff == NULL) {
41         HDF_LOGE("%s invalid para", __func__);
42         return HDF_ERR_INVALID_PARAM;
43     }
44 
45     if ((start->sec > end->sec) || ((end->sec == start->sec) && (end->usec < start->usec))) {
46         HDF_LOGE("%s start time later then end time", __func__);
47         return HDF_ERR_INVALID_PARAM;
48     }
49 
50     if (end->usec < start->usec) {
51         usec = (HDF_KILO_UNIT * HDF_KILO_UNIT);
52         sec = 1;
53     }
54 
55     if ((start->sec > UINT64_MAX - sec) || (end->usec > UINT64_MAX - usec) ||
56         (end->sec < start->sec + sec) || (end->usec + usec < start->usec)) {
57         HDF_LOGE("%s end time invalid", __func__);
58         return HDF_ERR_INVALID_PARAM;
59     }
60     diff->usec = usec + end->usec - start->usec;
61     diff->sec = end->sec - start->sec - sec;
62 
63     return HDF_SUCCESS;
64 }
65 
OsalSleep(uint32_t sec)66 void OsalSleep(uint32_t sec)
67 {
68     sleep(sec);
69 }
70 
OsalMSleep(uint32_t ms)71 void OsalMSleep(uint32_t ms)
72 {
73     int result;
74     struct timespec ts;
75 
76     ts.tv_sec = (time_t)ms / HDF_KILO_UNIT;
77     ts.tv_nsec = (time_t)HDF_KILO_UNIT * HDF_KILO_UNIT * ((long)(ms % HDF_KILO_UNIT));
78     result = nanosleep(&ts, &ts);
79     if (result != 0) {
80         HDF_LOGE("%s OsalMSleep failed %d", __func__, errno);
81     }
82 }
83 
OsalUSleep(uint32_t us)84 void OsalUSleep(uint32_t us)
85 {
86     int result;
87     struct timespec ts;
88 
89     ts.tv_sec = (time_t)us / ((long)HDF_KILO_UNIT * HDF_KILO_UNIT);
90     ts.tv_nsec = (time_t)HDF_KILO_UNIT * ((long)(us % HDF_KILO_UNIT));
91     result = nanosleep(&ts, &ts);
92     if (result != 0) {
93         HDF_LOGE("%s OsalUSleep failed %d", __func__, errno);
94     }
95 }
96 
OsalUDelay(uint32_t us)97 void OsalUDelay(uint32_t us)
98 {
99     (void)us;
100 }
101 
OsalMDelay(uint32_t ms)102 void OsalMDelay(uint32_t ms)
103 {
104     (void)ms;
105 }
106 
OsalGetSysTimeMs()107 uint64_t OsalGetSysTimeMs()
108 {
109     OsalTimespec time;
110 
111     (void)memset_s(&time, sizeof(time), 0, sizeof(time));
112     (void)OsalGetTime(&time);
113 
114     return (time.sec * HDF_KILO_UNIT + time.usec / HDF_KILO_UNIT);
115 }
116