1 /* 2 * Copyright (C) 2019 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 ANDROID_SYSTEM_SUSPEND_WAKE_LOCK_ENTRY_LIST_H 18 #define ANDROID_SYSTEM_SUSPEND_WAKE_LOCK_ENTRY_LIST_H 19 20 #include <android-base/unique_fd.h> 21 #include <android/system/suspend/WakeLockInfo.h> 22 #include <utils/Mutex.h> 23 24 #include <list> 25 #include <mutex> 26 #include <unordered_map> 27 #include <utility> 28 #include <vector> 29 30 namespace android { 31 namespace system { 32 namespace suspend { 33 namespace V1_0 { 34 35 using android::base::unique_fd; 36 using TimestampType = int64_t; 37 38 TimestampType getTimeNow(); 39 40 /* 41 * WakeLockEntryList to collect wake lock stats. 42 * This class is thread safe. 43 */ 44 class WakeLockEntryList { 45 public: 46 WakeLockEntryList(size_t capacity, unique_fd kernelWakelockStatsFd); 47 void updateOnAcquire(const std::string& name, int pid, TimestampType timeNow); 48 void updateOnRelease(const std::string& name, int pid, TimestampType timeNow); 49 // updateNow() should be called before getWakeLockStats() to ensure stats are 50 // updated wrt the current time. 51 void updateNow(); 52 void getWakeLockStats(std::vector<WakeLockInfo>* aidl_return) const; 53 friend std::ostream& operator<<(std::ostream& out, const WakeLockEntryList& list); 54 55 private: 56 void evictIfFull() REQUIRES(mStatsLock); 57 void insertEntry(WakeLockInfo entry) REQUIRES(mStatsLock); 58 void deleteEntry(std::list<WakeLockInfo>::iterator entry) REQUIRES(mStatsLock); 59 WakeLockInfo createNativeEntry(const std::string& name, int pid, TimestampType timeNow) const; 60 WakeLockInfo createKernelEntry(const std::string& name) const; 61 void getKernelWakelockStats(std::vector<WakeLockInfo>* aidl_return) const; 62 63 // Hash for WakeLockEntry key (pair<std::string, int>) 64 struct LockHash { operatorLockHash65 std::size_t operator()(const std::pair<std::string, int>& key) const { 66 return std::hash<std::string>()(key.first) ^ std::hash<int>()(key.second); 67 } 68 }; 69 70 size_t mCapacity; 71 unique_fd mKernelWakelockStatsFd; 72 73 mutable std::mutex mStatsLock; 74 75 // std::list and std::unordered map are used to support both inserting a stat 76 // and eviction of the LRU stat in O(1) time. The LRU stat is maintained at 77 // the back of the list. 78 std::list<WakeLockInfo> mStats GUARDED_BY(mStatsLock); 79 std::unordered_map<std::pair<std::string, int>, std::list<WakeLockInfo>::iterator, LockHash> 80 mLookupTable GUARDED_BY(mStatsLock); 81 }; 82 83 } // namespace V1_0 84 } // namespace suspend 85 } // namespace system 86 } // namespace android 87 88 #endif // ANDROID_SYSTEM_SUSPEND_WAKE_LOCK_ENTRY_LIST_H 89