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 4133105 : TimerList::Node * TimerList::Add(TimerList::Node * add) 42 : { 43 4133105 : VerifyOrDie(add != mEarliestTimer); 44 4133105 : if (mEarliestTimer == nullptr || (add->AwakenTime() < mEarliestTimer->AwakenTime())) 45 : { 46 3982599 : add->mNextTimer = mEarliestTimer; 47 3982599 : mEarliestTimer = add; 48 : } 49 : else 50 : { 51 150506 : TimerList::Node * lTimer = mEarliestTimer; 52 317548 : while (lTimer->mNextTimer) 53 : { 54 274714 : VerifyOrDie(lTimer->mNextTimer != add); 55 274714 : if (add->AwakenTime() < lTimer->mNextTimer->AwakenTime()) 56 : { 57 : // found the insert location. 58 107672 : break; 59 : } 60 167042 : lTimer = lTimer->mNextTimer; 61 : } 62 150506 : add->mNextTimer = lTimer->mNextTimer; 63 150506 : lTimer->mNextTimer = add; 64 : } 65 4133105 : 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 4187915 : TimerList::Node * TimerList::Remove(TimerCompleteCallback aOnComplete, void * aAppState) 98 : { 99 4187915 : TimerList::Node * previous = nullptr; 100 4943879 : for (TimerList::Node * timer = mEarliestTimer; timer != nullptr; timer = timer->mNextTimer) 101 : { 102 4877654 : if (timer->GetCallback().GetOnComplete() == aOnComplete && timer->GetCallback().GetAppState() == aAppState) 103 : { 104 4121690 : if (previous == nullptr) 105 : { 106 3976842 : mEarliestTimer = timer->mNextTimer; 107 : } 108 : else 109 : { 110 144848 : previous->mNextTimer = timer->mNextTimer; 111 : } 112 4121690 : timer->mNextTimer = nullptr; 113 4121690 : return timer; 114 : } 115 755964 : previous = timer; 116 : } 117 66225 : return nullptr; 118 : } 119 : 120 4103901 : TimerList::Node * TimerList::PopEarliest() 121 : { 122 4103901 : if (mEarliestTimer == nullptr) 123 : { 124 4092528 : return nullptr; 125 : } 126 11373 : TimerList::Node * earliest = mEarliestTimer; 127 11373 : mEarliestTimer = mEarliestTimer->mNextTimer; 128 11373 : earliest->mNextTimer = nullptr; 129 11373 : 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 4092526 : TimerList TimerList::ExtractEarlier(Clock::Timestamp t) 145 : { 146 4092526 : TimerList out; 147 : 148 4092526 : if ((mEarliestTimer != nullptr) && (mEarliestTimer->AwakenTime() < t)) 149 : { 150 5989 : out.mEarliestTimer = mEarliestTimer; 151 5989 : TimerList::Node * end = mEarliestTimer; 152 11387 : while ((end->mNextTimer != nullptr) && (end->mNextTimer->AwakenTime() < t)) 153 : { 154 5398 : end = end->mNextTimer; 155 : } 156 5989 : mEarliestTimer = end->mNextTimer; 157 5989 : end->mNextTimer = nullptr; 158 : } 159 : 160 4092526 : return out; 161 : } 162 : 163 23 : Clock::Timeout TimerList::GetRemainingTime(TimerCompleteCallback aOnComplete, void * aAppState) 164 : { 165 52 : for (TimerList::Node * timer = mEarliestTimer; timer != nullptr; timer = timer->mNextTimer) 166 : { 167 46 : if (timer->GetCallback().GetOnComplete() == aOnComplete && timer->GetCallback().GetAppState() == aAppState) 168 : { 169 17 : Clock::Timestamp currentTime = SystemClock().GetMonotonicTimestamp(); 170 : 171 17 : if (currentTime < timer->AwakenTime()) 172 : { 173 17 : return Clock::Timeout(timer->AwakenTime() - currentTime); 174 : } 175 0 : return Clock::kZero; 176 : } 177 : } 178 6 : return Clock::kZero; 179 : } 180 : 181 : } // namespace System 182 : } // namespace chip