1 /* 2 * Copyright (C) 2013 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 #include <errno.h> 18 #include <stdio.h> 19 #include <string.h> 20 #include <sys/mman.h> 21 22 #include <hardware/memtrack.h> 23 24 #include "memtrack_exynos5.h" 25 26 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) 27 #define min(x, y) ((x) < (y) ? (x) : (y)) 28 29 struct memtrack_record record_templates[] = { 30 { 31 .flags = MEMTRACK_FLAG_SMAPS_ACCOUNTED | 32 MEMTRACK_FLAG_PRIVATE | 33 MEMTRACK_FLAG_NONSECURE, 34 }, 35 { 36 .flags = MEMTRACK_FLAG_SMAPS_UNACCOUNTED | 37 MEMTRACK_FLAG_PRIVATE | 38 MEMTRACK_FLAG_NONSECURE, 39 }, 40 }; 41 42 int mali_memtrack_get_memory(pid_t pid, int type, 43 struct memtrack_record *records, 44 size_t *num_records) 45 { 46 size_t allocated_records = min(*num_records, ARRAY_SIZE(record_templates)); 47 int i; 48 FILE *fp; 49 char line[1024]; 50 51 *num_records = ARRAY_SIZE(record_templates); 52 53 /* fastpath to return the necessary number of records */ 54 if (allocated_records == 0) { 55 return 0; 56 } 57 58 fp = fopen("/sys/devices/platform/mali.0/gpu_memory", "r"); 59 if (fp == NULL) { 60 return -errno; 61 } 62 63 memcpy(records, record_templates, 64 sizeof(struct memtrack_record) * allocated_records); 65 66 while (1) { 67 if (fgets(line, sizeof(line), fp) == NULL) { 68 break; 69 } 70 71 /* Format: 72 * Name pid cap(pages) usage(pages) unmapped(pages) 73 * ================================================================= 74 * mali0 524288 85163 75 * ndroid.calendar 10708 1048575 181 111 76 */ 77 if (line[0] == ' ' && line[1] == ' ') { 78 unsigned int allocated; 79 unsigned int unmapped; 80 int line_pid; 81 82 int ret = sscanf(line, " %*s %u %*u %u %u\n", 83 &line_pid, &allocated, &unmapped); 84 if (ret == 3 && line_pid == pid) { 85 if (allocated_records > 0) { 86 records[0].size_in_bytes = (allocated - unmapped) * PAGE_SIZE; 87 } 88 if (allocated_records > 1) { 89 records[1].size_in_bytes = unmapped * PAGE_SIZE; 90 } 91 break; 92 } 93 } 94 } 95 96 fclose(fp); 97 98 return 0; 99 } 100