pm_map.c revision 76e6cb55fed01824e44306aa0485a3f8f122b228
1e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project/*
2e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
3e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project *
4e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * you may not use this file except in compliance with the License.
6e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * You may obtain a copy of the License at
7e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project *
8e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project *
10e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * See the License for the specific language governing permissions and
14e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * limitations under the License.
15e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project */
16e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
17e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <stdlib.h>
18e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <string.h>
19e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
20e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <pagemap/pagemap.h>
21e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
22e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint pm_map_pagemap(pm_map_t *map, uint64_t **pagemap_out, size_t *len) {
23e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (!map)
24e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        return -1;
25e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
26e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    return pm_process_pagemap_range(map->proc, map->start, map->end,
27e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                                    pagemap_out, len);
28e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
29e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
30e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint pm_map_usage(pm_map_t *map, pm_memusage_t *usage_out) {
31e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    uint64_t *pagemap;
32e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    size_t len, i;
33e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    uint64_t count;
34e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    pm_memusage_t usage;
35e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    int error;
36e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
37e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (!map || !usage_out)
38e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        return -1;
39e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
40e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    error = pm_map_pagemap(map, &pagemap, &len);
41e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (error) return error;
42e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
43e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    pm_memusage_zero(&usage);
44e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
45e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    for (i = 0; i < len; i++) {
46e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        if (!PM_PAGEMAP_PRESENT(pagemap[i]) ||
47e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            PM_PAGEMAP_SWAPPED(pagemap[i]))
48e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            continue;
49e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
50e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        error = pm_kernel_count(map->proc->ker, PM_PAGEMAP_PFN(pagemap[i]),
51e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                                &count);
52e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        if (error) goto out;
53e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
54e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        usage.vss += map->proc->ker->pagesize;
55e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        usage.rss += (count >= 1) ? (map->proc->ker->pagesize) : (0);
56e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        usage.pss += (count >= 1) ? (map->proc->ker->pagesize / count) : (0);
57e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        usage.uss += (count == 1) ? (map->proc->ker->pagesize) : (0);
58e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
59e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
60e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    memcpy(usage_out, &usage, sizeof(usage));
61e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
62e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    error = 0;
63e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
64e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectout:
65e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    free(pagemap);
66e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
67e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    return error;
68e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
69e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
70e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint pm_map_workingset(pm_map_t *map, pm_memusage_t *ws_out) {
71e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    uint64_t *pagemap;
72e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    size_t len, i;
73e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    uint64_t count, flags;
74e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    pm_memusage_t ws;
75e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    int error;
76e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
77e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (!map || !ws_out)
78e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        return -1;
79e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
80e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    error = pm_map_pagemap(map, &pagemap, &len);
81e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (error) return error;
82e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
83e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    pm_memusage_zero(&ws);
84e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
85e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    for (i = 0; i < len; i++) {
86e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        error = pm_kernel_flags(map->proc->ker, PM_PAGEMAP_PFN(pagemap[i]),
87e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                                &flags);
88e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        if (error) goto out;
89e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
90e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        if (!(flags & PM_PAGE_REFERENCED))
91e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            continue;
92e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
93e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        error = pm_kernel_count(map->proc->ker, PM_PAGEMAP_PFN(pagemap[i]),
94e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                                &count);
95e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        if (error) goto out;
96e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
97e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        ws.vss += map->proc->ker->pagesize;
9876e6cb55fed01824e44306aa0485a3f8f122b228Selim Gurun        if( PM_PAGEMAP_SWAPPED(pagemap[i]) ) continue;
99e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        ws.rss += (count >= 1) ? (map->proc->ker->pagesize) : (0);
100e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        ws.pss += (count >= 1) ? (map->proc->ker->pagesize / count) : (0);
101e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        ws.uss += (count == 1) ? (map->proc->ker->pagesize) : (0);
102e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
103e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
104e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    memcpy(ws_out, &ws, sizeof(ws));
105e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
106e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    error = 0;
107e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
108e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectout:
109e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    free(pagemap);
110e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
111e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    return 0;
112e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
113e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
114e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint pm_map_destroy(pm_map_t *map) {
115e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (!map)
116e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        return -1;
117e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
118e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    free(map->name);
119e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    free(map);
120e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
121e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    return 0;
122e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
123