1 /* 2 * Copyright 2023 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 package androidx.benchmark.macro.perfetto 18 19 import androidx.benchmark.traceprocessor.TraceProcessor 20 import androidx.benchmark.traceprocessor.processNameLikePkg 21 22 internal object MemoryCountersQuery { 23 // https://perfetto.dev/docs/data-sources/memory-counters getQuerynull24 internal fun getQuery(targetPackageName: String) = 25 """ 26 SELECT 27 track.name as counter_name, 28 SUM(value) 29 FROM counter 30 LEFT JOIN process_counter_track as track on counter.track_id = track.id 31 LEFT JOIN process using (upid) 32 WHERE 33 ${processNameLikePkg(targetPackageName)} AND 34 track.name LIKE 'mem.%.count' 35 GROUP BY counter_name 36 """ 37 .trimIndent() 38 39 private const val MINOR_PAGE_FAULTS_COUNT = "mem.mm.min_flt.count" 40 private const val MAJOR_PAGE_FAULTS_COUNT = "mem.mm.maj_flt.count" 41 private const val PAGE_FAULTS_BACKED_BY_SWAP_CACHE_COUNT = "mem.mm.swp_flt.count" 42 private const val PAGE_FAULTS_BACKED_BY_READ_IO_COUNT = "mem.mm.read_io.count" 43 private const val MEMORY_COMPACTION_EVENTS_COUNT = "mem.mm.compaction.count" 44 private const val MEMORY_RECLAIM_EVENTS_COUNT = "mem.mm.reclaim.count" 45 46 data class SubMetrics( 47 // Minor Page Faults 48 val minorPageFaults: Double, 49 // Major Page Faults 50 val majorPageFaults: Double, 51 // Page Faults Served by Swap Cache 52 val pageFaultsBackedBySwapCache: Double, 53 // Read Page Faults backed by I/O 54 val pageFaultsBackedByReadIO: Double, 55 // Memory Compaction Events 56 val memoryCompactionEvents: Double, 57 // Memory Reclaim Events 58 val memoryReclaimEvents: Double 59 ) 60 61 fun getMemoryCounters(session: TraceProcessor.Session, targetPackageName: String): SubMetrics? { 62 val queryResultIterator = 63 session.query(query = getQuery(targetPackageName = targetPackageName)) 64 65 val rows = queryResultIterator.toList() 66 return if (rows.isEmpty()) { 67 null 68 } else { 69 val summations: Map<String, Double> = 70 rows.associate { it.string("counter_name") to it.double("SUM(value)") } 71 SubMetrics( 72 minorPageFaults = summations[MINOR_PAGE_FAULTS_COUNT] ?: 0.0, 73 majorPageFaults = summations[MAJOR_PAGE_FAULTS_COUNT] ?: 0.0, 74 pageFaultsBackedBySwapCache = 75 summations[PAGE_FAULTS_BACKED_BY_SWAP_CACHE_COUNT] ?: 0.0, 76 pageFaultsBackedByReadIO = summations[PAGE_FAULTS_BACKED_BY_READ_IO_COUNT] ?: 0.0, 77 memoryCompactionEvents = summations[MEMORY_COMPACTION_EVENTS_COUNT] ?: 0.0, 78 memoryReclaimEvents = summations[MEMORY_RECLAIM_EVENTS_COUNT] ?: 0.0 79 ) 80 } 81 } 82 } 83