1 /* 2 * Copyright (C) 2016 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 #ifndef CHRE_CORE_TIMER_POOL_H_ 18 #define CHRE_CORE_TIMER_POOL_H_ 19 20 #include "chre_api/chre/re.h" 21 22 #include "chre/platform/system_timer.h" 23 #include "chre/util/non_copyable.h" 24 #include "chre/util/priority_queue.h" 25 26 namespace chre { 27 28 /** 29 * The type to use when referring to a timer instance. 30 * 31 * Note that this mirrors the CHRE API definition of a timer handle, so should 32 * not be changed without appropriate consideration. 33 */ 34 typedef uint32_t TimerHandle; 35 36 /** 37 * Tracks requests from CHRE apps for timed events. 38 */ 39 class TimerPool : public NonCopyable { 40 public: 41 /** 42 * Sets up the timer instance initial conditions. 43 */ 44 TimerPool(); 45 46 /** 47 * Requests a timer for a nanoapp given a cookie to pass to the nanoapp when 48 * the timer event is published. 49 * 50 * @param nanoapp The nanoapp for which this timer is being requested. 51 * @param duration The duration of the timer. 52 * @param cookie A cookie to pass to the app when the timer elapses. 53 * @param oneShot false if the timer is expected to auto-reload. 54 * @return TimerHandle of the requested timer. Returns CHRE_TIMER_INVALID if 55 * not successful. 56 */ 57 TimerHandle setTimer(const Nanoapp *nanoapp, Nanoseconds duration, 58 const void *cookie, bool oneShot); 59 60 /** 61 * Cancels a timer given a handle. If the timer handle is invalid or the timer 62 * is not owned by the passed in nanoapp, false is returned. 63 * 64 * @param nanoapp The nanoapp requesting a timer to be cancelled. 65 * @param timerHandle The handle for a timer to be cancelled. 66 * @return true if the timer was cancelled successfully. 67 */ 68 bool cancelTimer(const Nanoapp* nanoapp, TimerHandle timerHandle); 69 70 // TODO: should also add methods here to: 71 // - post an event after a delay 72 // - invoke a callback in "unsafe" context (i.e. from other thread), which the 73 // CHRE system could use to trigger things while the task runner is busy 74 75 private: 76 /** 77 * Tracks metadata associated with a request for a timed event. 78 */ 79 struct TimerRequest { 80 //! The nanoapp instance ID from which this request was made. 81 uint32_t nanoappInstanceId; 82 83 //! The TimerHandle assigned to this request. 84 TimerHandle timerHandle; 85 86 //! The time when the request was made. 87 Nanoseconds expirationTime; 88 89 //! The requested duration of the timer. 90 Nanoseconds duration; 91 92 //! Whether or not the request is a one shot or should be rescheduled. 93 bool isOneShot; 94 95 //! The cookie pointer to be passed as an event to the requesting nanoapp. 96 const void *cookie; 97 98 /** 99 * Provides a greater than comparison of TimerRequests. 100 * 101 * @param request The other request to compare against. 102 * @return Returns true if this request is greater than the provided 103 * request. 104 */ 105 bool operator>(const TimerRequest& request) const; 106 }; 107 108 //! The queue of outstanding timer requests. 109 PriorityQueue<TimerRequest, std::greater<TimerRequest>> mTimerRequests; 110 111 //! The underlying system timer used to schedule delayed callbacks. 112 SystemTimer mSystemTimer; 113 114 //! The next timer handle for generateTimerHandle() to return. 115 TimerHandle mLastTimerHandle = CHRE_TIMER_INVALID; 116 117 //! Max number of timers that can be requested for all apps 118 static constexpr size_t kMaxTimerRequests = 64; 119 120 //! Whether or not the timer handle generation logic needs to perform a 121 //! search for a vacant timer handle. 122 bool mGenerateTimerHandleMustCheckUniqueness = false; 123 124 /** 125 * Looks up a timer request given a timer handle. The lock must be acquired 126 * prior to entering this function. 127 * 128 * @param timerHandle The timer handle referring to a given request. 129 * @param index A pointer to the index of the handle. If the handle is found 130 * this will be populated with the index of the request from the list 131 * of requests. This is optional and will only be populated if not 132 * nullptr. 133 * @return A pointer to a TimerRequest or nullptr if no match is found. 134 */ 135 TimerRequest *getTimerRequestByTimerHandle(TimerHandle timerHandle, 136 size_t *index = nullptr); 137 138 /** 139 * Obtains a unique timer handle to return to an app requesting a timer. 140 * 141 * @return The guaranteed unique timer handle. 142 */ 143 TimerHandle generateTimerHandle(); 144 145 /** 146 * Obtains a unique timer handle by searching through the list of timer 147 * requests. This is a fallback for once the timer handles have been 148 * exhausted. The lock must be acquired prior to entering this function. 149 * 150 * @return A guaranteed unique timer handle. 151 */ 152 TimerHandle generateUniqueTimerHandle(); 153 154 /** 155 * Inserts a TimerRequest into the list of active timer requests. The order of 156 * mTimerRequests is always maintained such that the timer request with the 157 * closest expiration time is at the front of the list. 158 * 159 * @param timerRequest The timer request being inserted into the list. 160 * @return true if insertion of timer succeeds. 161 */ 162 bool insertTimerRequest(const TimerRequest& timerRequest); 163 164 /** 165 * Sets the underlying system timer to the next timer in the timer list if 166 * available. The lock must be acquired prior to entering this function. 167 * 168 * @return true if any timer events were posted 169 */ 170 bool handleExpiredTimersAndScheduleNext(); 171 172 /** 173 * This static method handles the callback from the system timer. The data 174 * pointer here is the TimerPool instance. 175 * 176 * @param data A pointer to the timer pool. 177 */ 178 static void handleSystemTimerCallback(void *timerPoolPtr); 179 }; 180 181 } // namespace chre 182 183 #endif // CHRE_CORE_TIMER_POOL_H_ 184