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