xref: /commonlibrary/utils_lite/kal/timer/src/kal.c (revision 0e98b08f)
1/*
2 * Copyright (c) 2020 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 "kal.h"
17#include <stdio.h>
18#include <stdlib.h>
19#include <time.h>
20
21#define KAL_TASK_NAME_LEN 32
22#define LOSCFG_BASE_CORE_MS_PER_SECOND 1000
23#define OS_SYS_NS_PER_SECOND 1000000000
24
25typedef struct {
26    timer_t timerPtr;
27    KalTimerType type;
28    unsigned int millisec;
29    KalTimerProc func;
30    union sigval arg;
31    int isRunning;
32} KalTimer;
33
34static void KalFunction(union sigval kalTimer)
35{
36    KalTimer* tmpPtr = (KalTimer *)(kalTimer.sival_ptr);
37    if (tmpPtr->type == KAL_TIMER_ONCE) {
38        tmpPtr->isRunning = 0;
39    }
40    tmpPtr->func(tmpPtr->arg);
41}
42
43static void KalMs2TimeSpec(struct timespec* tp, unsigned int ms)
44{
45    tp->tv_sec = ms / LOSCFG_BASE_CORE_MS_PER_SECOND;
46    ms -= tp->tv_sec * LOSCFG_BASE_CORE_MS_PER_SECOND;
47    tp->tv_nsec = (long)(((unsigned long long)ms * OS_SYS_NS_PER_SECOND) / LOSCFG_BASE_CORE_MS_PER_SECOND);
48}
49
50KalTimerId KalTimerCreate(KalTimerProc func, KalTimerType type, void* arg, unsigned int millisec)
51{
52    struct sigevent evp = {0};
53    timer_t timer;
54    if ((func == NULL) || ((type != KAL_TIMER_ONCE) && (type != KAL_TIMER_PERIODIC))) {
55        return NULL;
56    }
57    KalTimer* kalTimer = (KalTimer *)malloc(sizeof(KalTimer));
58    if (kalTimer == NULL) {
59        return NULL;
60    }
61    kalTimer->func = func;
62    kalTimer->arg.sival_ptr = arg;
63    kalTimer->type = type;
64    evp.sigev_notify = SIGEV_THREAD;
65    evp.sigev_notify_function = KalFunction;
66    evp.sigev_value.sival_ptr = kalTimer;
67    int ret = timer_create(CLOCK_REALTIME, &evp, &timer);
68    if (ret != 0) {
69        free(kalTimer);
70        return NULL;
71    }
72    kalTimer->timerPtr = timer;
73    kalTimer->millisec = millisec;
74    kalTimer->isRunning = 0;
75    return (KalTimerId)kalTimer;
76}
77
78KalErrCode KalTimerStart(KalTimerId timerId)
79{
80    if (timerId == NULL) {
81        return KAL_ERR_PARA;
82    }
83    struct itimerspec ts = {0};
84    KalTimer* tmpPtr = (KalTimer *)timerId;
85    KalMs2TimeSpec(&ts.it_value, tmpPtr->millisec);
86    if (tmpPtr->type == KAL_TIMER_PERIODIC) {
87        KalMs2TimeSpec(&ts.it_interval, tmpPtr->millisec);
88    }
89    int ret = timer_settime(tmpPtr->timerPtr, 0, &ts, NULL);
90    if (ret != 0) {
91        return KAL_ERR_PARA;
92    }
93    if (tmpPtr->millisec != 0) {
94        tmpPtr->isRunning = 1;
95    }
96    return KAL_OK;
97}
98
99KalErrCode KalTimerChange(KalTimerId timerId, unsigned int millisec)
100{
101    if (timerId == NULL) {
102        return KAL_ERR_PARA;
103    }
104    KalTimer* tmpPtr = (KalTimer *)timerId;
105    struct itimerspec ts = {0};
106    tmpPtr->millisec = millisec;
107    if (tmpPtr->isRunning == 1) {
108        KalMs2TimeSpec(&ts.it_value, millisec);
109        if (tmpPtr->type == KAL_TIMER_PERIODIC) {
110            KalMs2TimeSpec(&ts.it_interval, millisec);
111        }
112        int ret = timer_settime(tmpPtr->timerPtr, 0, &ts, NULL);
113        if (ret != 0) {
114            tmpPtr->isRunning = 0;
115            return KAL_ERR_INNER;
116        }
117        if (millisec == 0) {
118            tmpPtr->isRunning = 0;
119        }
120    }
121    return KAL_OK;
122}
123
124KalErrCode KalTimerStop(KalTimerId timerId)
125{
126    if (timerId == NULL) {
127        return KAL_ERR_PARA;
128    }
129    KalTimer* tmpPtr = (KalTimer *)timerId;
130    struct itimerspec ts = {0};
131    int ret = timer_settime(tmpPtr->timerPtr, 0, &ts, NULL);
132    if (ret != 0) {
133        return KAL_ERR_INNER;
134    }
135    tmpPtr->isRunning = 0;
136    return KAL_OK;
137}
138
139KalErrCode KalTimerDelete(KalTimerId timerId)
140{
141    if (timerId == NULL) {
142        return KAL_ERR_PARA;
143    }
144    KalTimer* tmpPtr = (KalTimer *)timerId;
145    int ret = timer_delete(tmpPtr->timerPtr);
146    free(timerId);
147    return (ret != 0) ? KAL_ERR_INNER : KAL_OK;
148}
149
150unsigned int KalTimerIsRunning(KalTimerId timerId)
151{
152    if (timerId == NULL) {
153        return 0;
154    }
155    return ((KalTimer *)timerId)->isRunning;
156}