Home | History | Annotate | Download | only in core
      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