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