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);
4508ea6e722b1f2d6359f54fe39c6bed82f524291cThierry Strudel    pm_memusage_pswap_init_handle(&usage, usage_out->p_swap);
46e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
47e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    for (i = 0; i < len; i++) {
48ad0b50bf21b04d64d56213014565d6e92d1c562eColin Cross        usage.vss += map->proc->ker->pagesize;
49ad0b50bf21b04d64d56213014565d6e92d1c562eColin Cross
50aa5a7df9d83c39e41fd07c1281a9912544022448Yu Liu        if (!PM_PAGEMAP_PRESENT(pagemap[i]) &&
5108ea6e722b1f2d6359f54fe39c6bed82f524291cThierry Strudel                !PM_PAGEMAP_SWAPPED(pagemap[i]))
52e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            continue;
53e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
54745b964daeacf44350db14bc343d53e319e696b8Colin Cross        if (!PM_PAGEMAP_SWAPPED(pagemap[i])) {
55745b964daeacf44350db14bc343d53e319e696b8Colin Cross            if (flags_mask) {
56745b964daeacf44350db14bc343d53e319e696b8Colin Cross                uint64_t flags;
57745b964daeacf44350db14bc343d53e319e696b8Colin Cross                error = pm_kernel_flags(map->proc->ker, PM_PAGEMAP_PFN(pagemap[i]),
58745b964daeacf44350db14bc343d53e319e696b8Colin Cross                                        &flags);
59745b964daeacf44350db14bc343d53e319e696b8Colin Cross                if (error) goto out;
603a1897792d0b5cc972d879af297ee5cfd095be68Colin Cross
61745b964daeacf44350db14bc343d53e319e696b8Colin Cross                if ((flags & flags_mask) != required_flags)
62745b964daeacf44350db14bc343d53e319e696b8Colin Cross                    continue;
63745b964daeacf44350db14bc343d53e319e696b8Colin Cross            }
643a1897792d0b5cc972d879af297ee5cfd095be68Colin Cross
65745b964daeacf44350db14bc343d53e319e696b8Colin Cross            error = pm_kernel_count(map->proc->ker, PM_PAGEMAP_PFN(pagemap[i]),
66745b964daeacf44350db14bc343d53e319e696b8Colin Cross                                    &count);
67745b964daeacf44350db14bc343d53e319e696b8Colin Cross            if (error) goto out;
68e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
69745b964daeacf44350db14bc343d53e319e696b8Colin Cross            usage.rss += (count >= 1) ? map->proc->ker->pagesize : (0);
70745b964daeacf44350db14bc343d53e319e696b8Colin Cross            usage.pss += (count >= 1) ? (map->proc->ker->pagesize / count) : (0);
71745b964daeacf44350db14bc343d53e319e696b8Colin Cross            usage.uss += (count == 1) ? (map->proc->ker->pagesize) : (0);
72745b964daeacf44350db14bc343d53e319e696b8Colin Cross        } else {
73745b964daeacf44350db14bc343d53e319e696b8Colin Cross            usage.swap += map->proc->ker->pagesize;
7408ea6e722b1f2d6359f54fe39c6bed82f524291cThierry Strudel            pm_memusage_pswap_add_offset(&usage, PM_PAGEMAP_SWAP_OFFSET(pagemap[i]));
75745b964daeacf44350db14bc343d53e319e696b8Colin Cross        }
76e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
77e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
78e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    memcpy(usage_out, &usage, sizeof(usage));
79e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
80e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    error = 0;
81e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
8208ea6e722b1f2d6359f54fe39c6bed82f524291cThierry Strudelout:
83e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    free(pagemap);
84e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
85e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    return error;
86e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
87e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
883a1897792d0b5cc972d879af297ee5cfd095be68Colin Crossint pm_map_usage(pm_map_t *map, pm_memusage_t *usage_out) {
893a1897792d0b5cc972d879af297ee5cfd095be68Colin Cross    return pm_map_usage_flags(map, usage_out, 0, 0);
903a1897792d0b5cc972d879af297ee5cfd095be68Colin Cross}
913a1897792d0b5cc972d879af297ee5cfd095be68Colin Cross
92e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint pm_map_workingset(pm_map_t *map, pm_memusage_t *ws_out) {
93e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    uint64_t *pagemap;
94e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    size_t len, i;
95e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    uint64_t count, flags;
96e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    pm_memusage_t ws;
97e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    int error;
98e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
99e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (!map || !ws_out)
100e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        return -1;
101e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
102e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    error = pm_map_pagemap(map, &pagemap, &len);
103e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (error) return error;
104e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
105e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    pm_memusage_zero(&ws);
10608ea6e722b1f2d6359f54fe39c6bed82f524291cThierry Strudel
107e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    for (i = 0; i < len; i++) {
108e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        error = pm_kernel_flags(map->proc->ker, PM_PAGEMAP_PFN(pagemap[i]),
109e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                                &flags);
110e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        if (error) goto out;
111e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
1129eed624c760b9c70de9a8f75ff84c5f085d62fdcElliott Hughes        if (!(flags & KPF_REFERENCED))
113e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            continue;
114e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
115e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        error = pm_kernel_count(map->proc->ker, PM_PAGEMAP_PFN(pagemap[i]),
116e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                                &count);
117e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        if (error) goto out;
118e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
119e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        ws.vss += map->proc->ker->pagesize;
12076e6cb55fed01824e44306aa0485a3f8f122b228Selim Gurun        if( PM_PAGEMAP_SWAPPED(pagemap[i]) ) continue;
121e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        ws.rss += (count >= 1) ? (map->proc->ker->pagesize) : (0);
122e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        ws.pss += (count >= 1) ? (map->proc->ker->pagesize / count) : (0);
123e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        ws.uss += (count == 1) ? (map->proc->ker->pagesize) : (0);
124e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
125e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
126e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    memcpy(ws_out, &ws, sizeof(ws));
127e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
128e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    error = 0;
129e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
130e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectout:
131e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    free(pagemap);
132e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
133e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    return 0;
134e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
135e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
136e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint pm_map_destroy(pm_map_t *map) {
137e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (!map)
138e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        return -1;
139e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
140e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    free(map->name);
141e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    free(map);
142e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
143e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    return 0;
144e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
145