1 /*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 /******************************************************************************
17 *
18 * The original Work has been changed by NXP.
19 *
20 * Copyright 2022 NXP
21 *
22 * Licensed under the Apache License, Version 2.0 (the "License");
23 * you may not use this file except in compliance with the License.
24 * You may obtain a copy of the License at
25 *
26 * http://www.apache.org/licenses/LICENSE-2.0
27 *
28 * Unless required by applicable law or agreed to in writing, software
29 * distributed under the License is distributed on an "AS IS" BASIS,
30 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31 * See the License for the specific language governing permissions and
32 * limitations under the License.
33 *
34 ******************************************************************************/
35
36 /*
37 * Asynchronous interval timer.
38 */
39 #define LOG_TAG "IntervalTimer"
40
41 #include <IntervalTimer.h>
42 #include <android-base/logging.h>
43 #include <android-base/stringprintf.h>
44
45 using android::base::StringPrintf;
46
IntervalTimer()47 IntervalTimer::IntervalTimer() {
48 mTimerId = 0;
49 mCb = NULL;
50 }
51
set(int ms,void * ptr,TIMER_FUNC cb)52 bool IntervalTimer::set(int ms, void* ptr, TIMER_FUNC cb) {
53 if (mTimerId == 0) {
54 if (cb == NULL) return false;
55
56 if (!create(ptr, cb)) return false;
57 }
58 if (cb != mCb) {
59 kill();
60 if (!create(ptr, cb)) return false;
61 }
62
63 int stat = 0;
64 struct itimerspec ts;
65 ts.it_value.tv_sec = ms / 1000;
66 ts.it_value.tv_nsec = (ms % 1000) * 1000000;
67
68 ts.it_interval.tv_sec = 0;
69 ts.it_interval.tv_nsec = 0;
70
71 stat = timer_settime(mTimerId, 0, &ts, 0);
72 if (stat == -1) LOG(ERROR) << StringPrintf("fail set timer");
73 return stat == 0;
74 }
75
~IntervalTimer()76 IntervalTimer::~IntervalTimer() { kill(); }
77
kill()78 void IntervalTimer::kill() {
79 if (mTimerId == 0) return;
80
81 timer_delete(mTimerId);
82 mTimerId = 0;
83 mCb = NULL;
84 }
85
create(void * ptr,TIMER_FUNC cb)86 bool IntervalTimer::create(void* ptr, TIMER_FUNC cb) {
87 struct sigevent se;
88 int stat = 0;
89
90 /*
91 * Set the sigevent structure to cause the signal to be
92 * delivered by creating a new thread.
93 */
94 se.sigev_notify = SIGEV_THREAD;
95 // se.sigev_value.sival_ptr = &mTimerId;
96 se.sigev_value.sival_ptr = ptr;
97 se.sigev_notify_function = cb;
98 se.sigev_notify_attributes = NULL;
99 se.sigev_signo = 0;
100 mCb = cb;
101 stat = timer_create(CLOCK_MONOTONIC, &se, &mTimerId);
102 if (stat == -1) LOG(ERROR) << StringPrintf("fail create timer");
103 return stat == 0;
104 }
105