1 /*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "softbus_adapter_timer.h"
17
18 #include <errno.h>
19 #include <signal.h>
20 #include <sys/stat.h>
21 #include <sys/time.h>
22 #include <time.h>
23 #include <unistd.h>
24
25 #include "comm_log.h"
26 #include "securec.h"
27 #include "softbus_def.h"
28 #include "softbus_errcode.h"
29
30 #define MS_PER_SECOND 1000
31 #define US_PER_MSECOND 1000
32 #define NS_PER_USECOND 1000
33
34 static unsigned int g_timerType;
35
36 static TimerFunc g_timerFunc = NULL;
37
HandleTimeoutAdapterFun(union sigval para)38 static void HandleTimeoutAdapterFun(union sigval para)
39 {
40 (void)para;
41 if (g_timerFunc != NULL) {
42 g_timerFunc();
43 }
44 }
45
SetTimerFunc(TimerFunc func)46 void SetTimerFunc(TimerFunc func)
47 {
48 g_timerFunc = func;
49 }
50
SoftBusCreateTimer(void ** timerId,unsigned int type)51 void *SoftBusCreateTimer(void **timerId, unsigned int type)
52 {
53 if (timerId == NULL) {
54 COMM_LOGE(COMM_ADAPTER, "timerId is null");
55 return NULL;
56 }
57 struct sigevent envent;
58 (void)memset_s(&envent, sizeof(envent), 0, sizeof(envent));
59 envent.sigev_notify = SIGEV_THREAD;
60 envent.sigev_notify_function = HandleTimeoutAdapterFun;
61 envent.sigev_notify_attributes = NULL;
62
63 g_timerType = type;
64 if (timer_create(CLOCK_REALTIME, &envent, timerId) != 0) {
65 COMM_LOGE(COMM_ADAPTER, "timer create error, errnoCode=%{public}d", errno);
66 return NULL;
67 }
68
69 return *timerId;
70 }
71
SoftBusStartTimer(void * timerId,unsigned int tickets)72 int SoftBusStartTimer(void *timerId, unsigned int tickets)
73 {
74 if (timerId == NULL) {
75 COMM_LOGE(COMM_ADAPTER, "timerId is null");
76 return SOFTBUS_ERR;
77 }
78 struct itimerspec value;
79 (void)memset_s(&value, sizeof(value), 0, sizeof(value));
80 value.it_value.tv_sec = tickets / MS_PER_SECOND;
81 value.it_value.tv_nsec = 0;
82 if (g_timerType == TIMER_TYPE_ONCE) {
83 value.it_interval.tv_sec = 0;
84 value.it_interval.tv_nsec = 0;
85 } else {
86 value.it_interval.tv_sec = tickets / MS_PER_SECOND;
87 value.it_interval.tv_nsec = 0;
88 }
89
90 if (timer_settime(timerId, 0, &value, NULL) != 0) {
91 COMM_LOGE(COMM_ADAPTER, "timer start error, errnoCode=%{public}d", errno);
92 return SOFTBUS_ERR;
93 }
94
95 return SOFTBUS_OK;
96 }
97
SoftBusDeleteTimer(void * timerId)98 int SoftBusDeleteTimer(void *timerId)
99 {
100 if (timerId == NULL) {
101 COMM_LOGE(COMM_ADAPTER, "timerId is null");
102 return SOFTBUS_ERR;
103 }
104
105 if (timer_delete(timerId) != 0) {
106 COMM_LOGE(COMM_ADAPTER, "timer delete err, errnoCode=%{public}d", errno);
107 return SOFTBUS_ERR;
108 }
109
110 return SOFTBUS_OK;
111 }
112
SoftBusSleepMs(unsigned int ms)113 int SoftBusSleepMs(unsigned int ms)
114 {
115 int ret;
116 struct timeval tm;
117 tm.tv_sec = ms / MS_PER_SECOND;
118 tm.tv_usec = (ms % MS_PER_SECOND) * US_PER_MSECOND;
119
120 do {
121 ret = select(0, NULL, NULL, NULL, &tm);
122 } while ((ret == -1) && (errno == EINTR));
123
124 return SOFTBUS_ERR;
125 }
126
SoftBusGetTime(SoftBusSysTime * sysTime)127 int32_t SoftBusGetTime(SoftBusSysTime *sysTime)
128 {
129 if (sysTime == NULL) {
130 COMM_LOGI(COMM_ADAPTER, "sysTime is null");
131 return SOFTBUS_INVALID_PARAM;
132 }
133 struct timespec time = {0};
134 (void)clock_gettime(CLOCK_MONOTONIC, &time);
135
136 sysTime->sec = time.tv_sec;
137 sysTime->usec = time.tv_nsec / NS_PER_USECOND;
138 return SOFTBUS_OK;
139 }
140
SoftBusGetSysTimeMs(void)141 uint64_t SoftBusGetSysTimeMs(void)
142 {
143 struct timeval time;
144 time.tv_sec = 0;
145 time.tv_usec = 0;
146 if (gettimeofday(&time, NULL) != 0) {
147 COMM_LOGI(COMM_ADAPTER, "get sys time fail");
148 return 0;
149 }
150 return (uint64_t)time.tv_sec * MS_PER_SECOND + (uint64_t)time.tv_usec / US_PER_MSECOND;
151 }