1/* 2 * Copyright (c) 2021-2022 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 "power_mgr_timer_util.h" 17 18#include <common.h> 19#include <errno.h> 20#include <securec.h> 21#include <signal.h> 22#include <stdint.h> 23#include <string.h> 24 25#include "hilog_wrapper.h" 26#include "power_mgr_time_util.h" 27 28typedef struct { 29 PowerTimer timerId; 30 BOOL isRunning; 31 int64_t whenMsec; 32 int64_t intervalMsec; 33 PowerTimerCallback timerCb; 34 void *data; 35} PowerTimerInfo; 36 37static inline PowerTimerInfo *GetPowerTimerInfo(PowerTimer *timer) 38{ 39 return GET_OBJECT(timer, PowerTimerInfo, timerId); 40} 41 42static void SetTimeSpec(struct timespec *ts, int64_t msec) 43{ 44 ts->tv_sec = MsecToSec(msec); 45 msec -= SecToMsec(ts->tv_sec); 46 ts->tv_nsec = MsecToNsec(msec); 47} 48 49static BOOL StartTimer(PowerTimer timer, int64_t whenMsec, int64_t intervalMsec) 50{ 51 struct itimerspec ts; 52 SetTimeSpec(&ts.it_value, whenMsec); 53 SetTimeSpec(&ts.it_interval, intervalMsec); 54 int32_t ret = timer_settime(timer, 0, &ts, NULL); 55 if (ret < 0) { 56 POWER_HILOGE("Failed to start timer"); 57 return FALSE; 58 } 59 return TRUE; 60} 61 62static void TimerHandle(union sigval v) 63{ 64 PowerTimerInfo *info = (PowerTimerInfo *)v.sival_ptr; 65 if (info == NULL) { 66 POWER_HILOGE("Invalid timer info"); 67 return; 68 } 69 if (info->timerCb != NULL) { 70 info->timerCb(info->data); 71 } 72} 73 74PowerTimer *PowerMgrCreateTimer(int64_t whenMsec, int64_t intervalMsec, PowerTimerCallback cb) 75{ 76 PowerTimerInfo *info = (PowerTimerInfo *)malloc(sizeof(PowerTimerInfo)); 77 if (info == NULL) { 78 POWER_HILOGE("Failed allocate timer info"); 79 return NULL; 80 } 81 (void)memset_s(info, sizeof(PowerTimerInfo), 0, sizeof(PowerTimerInfo)); 82 info->isRunning = FALSE; 83 info->whenMsec = whenMsec; 84 info->intervalMsec = intervalMsec; 85 info->timerCb = cb; 86 87 struct sigevent evp; 88 (void)memset_s(&evp, sizeof(evp), 0, sizeof(evp)); 89 evp.sigev_value.sival_ptr = info; 90 evp.sigev_notify = SIGEV_THREAD; 91 evp.sigev_notify_function = TimerHandle; 92 int32_t ret = timer_create(CLOCK_REALTIME, &evp, &info->timerId); 93 if (ret < 0) { 94 POWER_HILOGE("Failed to create timer"); 95 free(info); 96 return NULL; 97 } 98 POWER_HILOGD("Succeed to create timer, id: %p", info->timerId); 99 100 return &info->timerId; 101} 102 103BOOL PowerMgrResetTimer(PowerTimer *timer, int64_t whenMsec, int64_t intervalMsec) 104{ 105 if (timer == NULL) { 106 POWER_HILOGE("Invalid timer"); 107 return FALSE; 108 } 109 PowerMgrStopTimer(timer); 110 PowerTimerInfo *info = GetPowerTimerInfo(timer); 111 info->whenMsec = whenMsec; 112 info->intervalMsec = intervalMsec; 113 return TRUE; 114} 115 116BOOL PowerMgrStartTimer(PowerTimer *timer, void *privateData) 117{ 118 if (timer == NULL) { 119 POWER_HILOGE("Invalid timer"); 120 return FALSE; 121 } 122 123 PowerTimerInfo *info = GetPowerTimerInfo(timer); 124 info->data = privateData; 125 info->isRunning = TRUE; 126 return StartTimer(info->timerId, info->whenMsec, info->intervalMsec); 127} 128 129BOOL PowerMgrRestartTimer(PowerTimer *timer, void *privateData) 130{ 131 if (timer == NULL) { 132 POWER_HILOGE("Invalid timer"); 133 return FALSE; 134 } 135 136 return PowerMgrStartTimer(timer, privateData); 137} 138 139BOOL PowerMgrStopTimer(PowerTimer *timer) 140{ 141 if (timer == NULL) { 142 POWER_HILOGE("Invalid timer"); 143 return FALSE; 144 } 145 146 PowerTimerInfo *info = GetPowerTimerInfo(timer); 147 info->isRunning = FALSE; 148 return StartTimer(info->timerId, 0, 0); 149} 150 151void PowerMgrDestroyTimer(PowerTimer *timer) 152{ 153 if (timer == NULL) { 154 POWER_HILOGE("Invalid timer"); 155 return; 156 } 157 158 PowerTimerInfo *info = GetPowerTimerInfo(timer); 159 int32_t ret = timer_delete(info->timerId); 160 POWER_HILOGD("Destory timer: %d", ret); 161 free(info); 162} 163