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