Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2020-2021 Project CHIP Authors
4 : * Copyright (c) 2016-2017 Nest Labs, Inc.
5 : *
6 : * Licensed under the Apache License, Version 2.0 (the "License");
7 : * you may not use this file except in compliance with the License.
8 : * You may obtain a copy of the License at
9 : *
10 : * http://www.apache.org/licenses/LICENSE-2.0
11 : *
12 : * Unless required by applicable law or agreed to in writing, software
13 : * distributed under the License is distributed on an "AS IS" BASIS,
14 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 : * See the License for the specific language governing permissions and
16 : * limitations under the License.
17 : */
18 :
19 : /**
20 : * @file
21 : * This file defines the member functions and private data for
22 : * the chip::System::Timer class, which is used for
23 : * representing an in-progress one-shot timer.
24 : */
25 :
26 : // Include module header
27 : #include <system/SystemTimer.h>
28 :
29 : // Include local headers
30 : #include <string.h>
31 :
32 : #include <system/SystemError.h>
33 : #include <system/SystemFaultInjection.h>
34 : #include <system/SystemLayer.h>
35 :
36 : #include <lib/support/CodeUtils.h>
37 :
38 : namespace chip {
39 : namespace System {
40 :
41 6643061 : TimerList::Node * TimerList::Add(TimerList::Node * add)
42 : {
43 6643061 : VerifyOrDie(add != mEarliestTimer);
44 6643061 : if (mEarliestTimer == nullptr || (add->AwakenTime() < mEarliestTimer->AwakenTime()))
45 : {
46 6489735 : add->mNextTimer = mEarliestTimer;
47 6489735 : mEarliestTimer = add;
48 : }
49 : else
50 : {
51 153326 : TimerList::Node * lTimer = mEarliestTimer;
52 328459 : while (lTimer->mNextTimer)
53 : {
54 277562 : VerifyOrDie(lTimer->mNextTimer != add);
55 277562 : if (add->AwakenTime() < lTimer->mNextTimer->AwakenTime())
56 : {
57 : // found the insert location.
58 102429 : break;
59 : }
60 175133 : lTimer = lTimer->mNextTimer;
61 : }
62 153326 : add->mNextTimer = lTimer->mNextTimer;
63 153326 : lTimer->mNextTimer = add;
64 : }
65 6643061 : return mEarliestTimer;
66 : }
67 :
68 2 : TimerList::Node * TimerList::Remove(TimerList::Node * remove)
69 : {
70 2 : if (mEarliestTimer != nullptr && remove != nullptr)
71 : {
72 1 : if (remove == mEarliestTimer)
73 : {
74 1 : mEarliestTimer = remove->mNextTimer;
75 : }
76 : else
77 : {
78 0 : TimerList::Node * lTimer = mEarliestTimer;
79 :
80 0 : while (lTimer->mNextTimer)
81 : {
82 0 : if (remove == lTimer->mNextTimer)
83 : {
84 0 : lTimer->mNextTimer = remove->mNextTimer;
85 0 : break;
86 : }
87 :
88 0 : lTimer = lTimer->mNextTimer;
89 : }
90 : }
91 :
92 1 : remove->mNextTimer = nullptr;
93 : }
94 2 : return mEarliestTimer;
95 : }
96 :
97 6699085 : TimerList::Node * TimerList::Remove(TimerCompleteCallback aOnComplete, void * aAppState)
98 : {
99 6699085 : TimerList::Node * previous = nullptr;
100 7471963 : for (TimerList::Node * timer = mEarliestTimer; timer != nullptr; timer = timer->mNextTimer)
101 : {
102 7404214 : if (timer->GetCallback().GetOnComplete() == aOnComplete && timer->GetCallback().GetAppState() == aAppState)
103 : {
104 6631336 : if (previous == nullptr)
105 : {
106 6483804 : mEarliestTimer = timer->mNextTimer;
107 : }
108 : else
109 : {
110 147532 : previous->mNextTimer = timer->mNextTimer;
111 : }
112 6631336 : timer->mNextTimer = nullptr;
113 6631336 : return timer;
114 : }
115 772878 : previous = timer;
116 : }
117 67749 : return nullptr;
118 : }
119 :
120 6613264 : TimerList::Node * TimerList::PopEarliest()
121 : {
122 6613264 : if (mEarliestTimer == nullptr)
123 : {
124 6601587 : return nullptr;
125 : }
126 11677 : TimerList::Node * earliest = mEarliestTimer;
127 11677 : mEarliestTimer = mEarliestTimer->mNextTimer;
128 11677 : earliest->mNextTimer = nullptr;
129 11677 : return earliest;
130 : }
131 :
132 4 : TimerList::Node * TimerList::PopIfEarlier(Clock::Timestamp t)
133 : {
134 4 : if ((mEarliestTimer == nullptr) || !(mEarliestTimer->AwakenTime() < t))
135 : {
136 3 : return nullptr;
137 : }
138 1 : TimerList::Node * earliest = mEarliestTimer;
139 1 : mEarliestTimer = mEarliestTimer->mNextTimer;
140 1 : earliest->mNextTimer = nullptr;
141 1 : return earliest;
142 : }
143 :
144 6601585 : TimerList TimerList::ExtractEarlier(Clock::Timestamp t)
145 : {
146 6601585 : TimerList out;
147 :
148 6601585 : if ((mEarliestTimer != nullptr) && (mEarliestTimer->AwakenTime() < t))
149 : {
150 6205 : out.mEarliestTimer = mEarliestTimer;
151 6205 : TimerList::Node * end = mEarliestTimer;
152 11691 : while ((end->mNextTimer != nullptr) && (end->mNextTimer->AwakenTime() < t))
153 : {
154 5486 : end = end->mNextTimer;
155 : }
156 6205 : mEarliestTimer = end->mNextTimer;
157 6205 : end->mNextTimer = nullptr;
158 : }
159 :
160 6601585 : return out;
161 : }
162 :
163 40 : Clock::Timeout TimerList::GetRemainingTime(TimerCompleteCallback aOnComplete, void * aAppState)
164 : {
165 80 : for (TimerList::Node * timer = mEarliestTimer; timer != nullptr; timer = timer->mNextTimer)
166 : {
167 71 : if (timer->GetCallback().GetOnComplete() == aOnComplete && timer->GetCallback().GetAppState() == aAppState)
168 : {
169 31 : Clock::Timestamp currentTime = SystemClock().GetMonotonicTimestamp();
170 :
171 31 : if (currentTime < timer->AwakenTime())
172 : {
173 31 : return Clock::Timeout(timer->AwakenTime() - currentTime);
174 : }
175 0 : return Clock::kZero;
176 : }
177 : }
178 9 : return Clock::kZero;
179 : }
180 :
181 : } // namespace System
182 : } // namespace chip
|