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
303a1897792d0b5cc972d879af297ee5cfd095be68Colin Crossint pm_map_usage_flags(pm_map_t *map, pm_memusage_t *usage_out,
313a1897792d0b5cc972d879af297ee5cfd095be68Colin Cross                        uint64_t flags_mask, uint64_t required_flags) {
32e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    uint64_t *pagemap;
33e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    size_t len, i;
34e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    uint64_t count;
35e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    pm_memusage_t usage;
36e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    int error;
37e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
38e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (!map || !usage_out)
39e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        return -1;
40e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
41e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    error = pm_map_pagemap(map, &pagemap, &len);
42e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (error) return error;
43e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
44e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    pm_memusage_zero(&usage);
45e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
46e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    for (i = 0; i < len; i++) {
47ad0b50bf21b04d64d56213014565d6e92d1c562eColin Cross        usage.vss += map->proc->ker->pagesize;
48ad0b50bf21b04d64d56213014565d6e92d1c562eColin Cross
49745b964daeacf44350db14bc343d53e319e696b8Colin Cross        if (!PM_PAGEMAP_PRESENT(pagemap[i]))
50e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            continue;
51e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
52745b964daeacf44350db14bc343d53e319e696b8Colin Cross        if (!PM_PAGEMAP_SWAPPED(pagemap[i])) {
53745b964daeacf44350db14bc343d53e319e696b8Colin Cross            if (flags_mask) {
54745b964daeacf44350db14bc343d53e319e696b8Colin Cross                uint64_t flags;
55745b964daeacf44350db14bc343d53e319e696b8Colin Cross                error = pm_kernel_flags(map->proc->ker, PM_PAGEMAP_PFN(pagemap[i]),
56745b964daeacf44350db14bc343d53e319e696b8Colin Cross                                        &flags);
57745b964daeacf44350db14bc343d53e319e696b8Colin Cross                if (error) goto out;
583a1897792d0b5cc972d879af297ee5cfd095be68Colin Cross
59745b964daeacf44350db14bc343d53e319e696b8Colin Cross                if ((flags & flags_mask) != required_flags)
60745b964daeacf44350db14bc343d53e319e696b8Colin Cross                    continue;
61745b964daeacf44350db14bc343d53e319e696b8Colin Cross            }
623a1897792d0b5cc972d879af297ee5cfd095be68Colin Cross
63745b964daeacf44350db14bc343d53e319e696b8Colin Cross            error = pm_kernel_count(map->proc->ker, PM_PAGEMAP_PFN(pagemap[i]),
64745b964daeacf44350db14bc343d53e319e696b8Colin Cross                                    &count);
65745b964daeacf44350db14bc343d53e319e696b8Colin Cross            if (error) goto out;
66e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
67745b964daeacf44350db14bc343d53e319e696b8Colin Cross            usage.rss += (count >= 1) ? map->proc->ker->pagesize : (0);
68745b964daeacf44350db14bc343d53e319e696b8Colin Cross            usage.pss += (count >= 1) ? (map->proc->ker->pagesize / count) : (0);
69745b964daeacf44350db14bc343d53e319e696b8Colin Cross            usage.uss += (count == 1) ? (map->proc->ker->pagesize) : (0);
70745b964daeacf44350db14bc343d53e319e696b8Colin Cross        } else {
71745b964daeacf44350db14bc343d53e319e696b8Colin Cross            usage.swap += map->proc->ker->pagesize;
72745b964daeacf44350db14bc343d53e319e696b8Colin Cross        }
73e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
74e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
75e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    memcpy(usage_out, &usage, sizeof(usage));
76e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
77e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    error = 0;
78e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
79e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectout:
80e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    free(pagemap);
81e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
82e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    return error;
83e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
84e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
853a1897792d0b5cc972d879af297ee5cfd095be68Colin Crossint pm_map_usage(pm_map_t *map, pm_memusage_t *usage_out) {
863a1897792d0b5cc972d879af297ee5cfd095be68Colin Cross    return pm_map_usage_flags(map, usage_out, 0, 0);
873a1897792d0b5cc972d879af297ee5cfd095be68Colin Cross}
883a1897792d0b5cc972d879af297ee5cfd095be68Colin Cross
89e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint pm_map_workingset(pm_map_t *map, pm_memusage_t *ws_out) {
90e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    uint64_t *pagemap;
91e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    size_t len, i;
92e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    uint64_t count, flags;
93e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    pm_memusage_t ws;
94e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    int error;
95e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
96e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (!map || !ws_out)
97e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        return -1;
98e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
99e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    error = pm_map_pagemap(map, &pagemap, &len);
100e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (error) return error;
101e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
102e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    pm_memusage_zero(&ws);
103e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
104e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    for (i = 0; i < len; i++) {
105e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        error = pm_kernel_flags(map->proc->ker, PM_PAGEMAP_PFN(pagemap[i]),
106e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                                &flags);
107e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        if (error) goto out;
108e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
109e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        if (!(flags & PM_PAGE_REFERENCED))
110e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            continue;
111e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
112e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        error = pm_kernel_count(map->proc->ker, PM_PAGEMAP_PFN(pagemap[i]),
113e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                                &count);
114e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        if (error) goto out;
115e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
116e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        ws.vss += map->proc->ker->pagesize;
11776e6cb55fed01824e44306aa0485a3f8f122b228Selim Gurun        if( PM_PAGEMAP_SWAPPED(pagemap[i]) ) continue;
118e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        ws.rss += (count >= 1) ? (map->proc->ker->pagesize) : (0);
119e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        ws.pss += (count >= 1) ? (map->proc->ker->pagesize / count) : (0);
120e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        ws.uss += (count == 1) ? (map->proc->ker->pagesize) : (0);
121e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
122e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
123e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    memcpy(ws_out, &ws, sizeof(ws));
124e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
125e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    error = 0;
126e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
127e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectout:
128e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    free(pagemap);
129e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
130e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    return 0;
131e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
132e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
133e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint pm_map_destroy(pm_map_t *map) {
134e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (!map)
135e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        return -1;
136e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
137e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    free(map->name);
138e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    free(map);
139e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
140e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    return 0;
141e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
142