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 <stdio.h>
     18 #include <stdlib.h>
     19 #include <string.h>
     20 #include <sys/types.h>
     21 
     22 #include <memtrack/memtrack.h>
     23 
     24 #include <pagemap/pagemap.h>
     25 
     26 #define DIV_ROUND_UP(x,y) (((x) + (y) - 1) / (y))
     27 
     28 static int getprocname(pid_t pid, char *buf, int len) {
     29     char *filename;
     30     FILE *f;
     31     int rc = 0;
     32     static const char* unknown_cmdline = "<unknown>";
     33 
     34     if (len <= 0) {
     35         return -1;
     36     }
     37 
     38     if (asprintf(&filename, "/proc/%d/cmdline", pid) < 0) {
     39         rc = 1;
     40         goto exit;
     41     }
     42 
     43     f = fopen(filename, "r");
     44     if (f == NULL) {
     45         rc = 2;
     46         goto releasefilename;
     47     }
     48 
     49     if (fgets(buf, len, f) == NULL) {
     50         rc = 3;
     51         goto closefile;
     52     }
     53 
     54 closefile:
     55     (void) fclose(f);
     56 releasefilename:
     57     free(filename);
     58 exit:
     59     if (rc != 0) {
     60         /*
     61          * The process went away before we could read its process name. Try
     62          * to give the user "<unknown>" here, but otherwise they get to look
     63          * at a blank.
     64          */
     65         if (strlcpy(buf, unknown_cmdline, (size_t)len) >= (size_t)len) {
     66             rc = 4;
     67         }
     68     }
     69 
     70     return rc;
     71 }
     72 
     73 int main(int argc, char *argv[])
     74 {
     75     int ret;
     76     pm_kernel_t *ker;
     77     size_t num_procs;
     78     pid_t *pids;
     79     struct memtrack_proc *p;
     80     size_t i;
     81 
     82     (void)argc;
     83     (void)argv;
     84 
     85     ret = memtrack_init();
     86     if (ret < 0) {
     87         fprintf(stderr, "failed to initialize HAL: %s (%d)\n", strerror(-ret), ret);
     88         exit(EXIT_FAILURE);
     89     }
     90 
     91     ret = pm_kernel_create(&ker);
     92     if (ret) {
     93         fprintf(stderr, "Error creating kernel interface -- "
     94                         "does this kernel have pagemap?\n");
     95         exit(EXIT_FAILURE);
     96     }
     97 
     98     ret = pm_kernel_pids(ker, &pids, &num_procs);
     99     if (ret) {
    100         fprintf(stderr, "Error listing processes.\n");
    101         exit(EXIT_FAILURE);
    102     }
    103 
    104     p = memtrack_proc_new();
    105     if (ret) {
    106         fprintf(stderr, "failed to create memtrack process handle\n");
    107         exit(EXIT_FAILURE);
    108     }
    109 
    110     for (i = 0; i < num_procs; i++) {
    111         pid_t pid = pids[i];
    112         char cmdline[256];
    113         size_t v1;
    114         size_t v2;
    115         size_t v3;
    116         size_t v4;
    117         size_t v5;
    118         size_t v6;
    119 
    120         getprocname(pid, cmdline, (int)sizeof(cmdline));
    121 
    122         ret = memtrack_proc_get(p, pid);
    123         if (ret) {
    124             fprintf(stderr, "failed to get memory info for pid %d: %s (%d)\n",
    125                     pid, strerror(-ret), ret);
    126             continue;
    127         }
    128 
    129         v1 = DIV_ROUND_UP(memtrack_proc_graphics_total(p), 1024);
    130         v2 = DIV_ROUND_UP(memtrack_proc_graphics_pss(p), 1024);
    131         v3 = DIV_ROUND_UP(memtrack_proc_gl_total(p), 1024);
    132         v4 = DIV_ROUND_UP(memtrack_proc_gl_pss(p), 1024);
    133         v5 = DIV_ROUND_UP(memtrack_proc_other_total(p), 1024);
    134         v6 = DIV_ROUND_UP(memtrack_proc_other_pss(p), 1024);
    135 
    136         if (v1 | v2 | v3 | v4 | v5 | v6) {
    137             printf("%5d %6zu %6zu %6zu %6zu %6zu %6zu %s\n", pid,
    138                    v1, v2, v3, v4, v5, v6, cmdline);
    139         }
    140     }
    141 
    142     memtrack_proc_destroy(p);
    143 
    144     return 0;
    145 }
    146