diff options
author | Sandeep Patil <sspatil@google.com> | 2019-01-29 13:43:36 -0800 |
---|---|---|
committer | Sandeep Patil <sspatil@google.com> | 2019-01-29 13:43:36 -0800 |
commit | 0566b21cce8ac5b51eea0081bf711a58b4ffb3df (patch) | |
tree | ae1b712116610ff08dca1dafe5f82db49a13cde8 /libpagemap | |
parent | 58a4d50ece679525d1c3a7fcd1bfa04701041a08 (diff) | |
download | extras-0566b21cce8ac5b51eea0081bf711a58b4ffb3df.tar.gz |
libpagemap: Remove it.
Bug: 113035067
Test: lunch aosp_blueline-userdebug; m -j
Change-Id: Id3b99876fea86d9fb74877d7d238241b718fc4dc
Signed-off-by: Sandeep Patil <sspatil@google.com>
Diffstat (limited to 'libpagemap')
-rw-r--r-- | libpagemap/.clang-format | 11 | ||||
-rw-r--r-- | libpagemap/Android.bp | 45 | ||||
-rw-r--r-- | libpagemap/MODULE_LICENSE_APACHE2 | 0 | ||||
-rw-r--r-- | libpagemap/NOTICE | 190 | ||||
-rw-r--r-- | libpagemap/include/pagemap/pagemap.h | 253 | ||||
-rw-r--r-- | libpagemap/pagemap_test.cpp | 48 | ||||
-rw-r--r-- | libpagemap/pm_kernel.c | 256 | ||||
-rw-r--r-- | libpagemap/pm_map.c | 173 | ||||
-rw-r--r-- | libpagemap/pm_map.h | 24 | ||||
-rw-r--r-- | libpagemap/pm_memusage.c | 132 | ||||
-rw-r--r-- | libpagemap/pm_process.c | 367 |
11 files changed, 0 insertions, 1499 deletions
diff --git a/libpagemap/.clang-format b/libpagemap/.clang-format deleted file mode 100644 index 55773a29..00000000 --- a/libpagemap/.clang-format +++ /dev/null @@ -1,11 +0,0 @@ -BasedOnStyle: Google -AccessModifierOffset: -2 -AllowShortFunctionsOnASingleLine: Inline -ColumnLimit: 100 -CommentPragmas: NOLINT:.* -DerivePointerAlignment: false -IndentWidth: 4 -ContinuationIndentWidth: 8 -PointerAlignment: Left -TabWidth: 4 -UseTab: Never diff --git a/libpagemap/Android.bp b/libpagemap/Android.bp deleted file mode 100644 index e89d1d8a..00000000 --- a/libpagemap/Android.bp +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (C) 2008 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -cc_library { - name: "libpagemap", - cflags: ["-Werror"], - vendor_available: true, - vndk: { - enabled: true, - }, - srcs: [ - "pm_kernel.c", - "pm_process.c", - "pm_map.c", - "pm_memusage.c", - ], - local_include_dirs: ["include"], - export_include_dirs: ["include"], -} - -cc_test { - name: "pagemap_test", - cflags: ["-Werror"], - srcs: ["pagemap_test.cpp"], - shared_libs: ["libpagemap"], - required: ["libpagemap"], -} - -cc_test { - name: "pagemap_static_test", - cflags: ["-Werror"], - srcs: ["pagemap_test.cpp"], - static_libs: ["libpagemap"], -} diff --git a/libpagemap/MODULE_LICENSE_APACHE2 b/libpagemap/MODULE_LICENSE_APACHE2 deleted file mode 100644 index e69de29b..00000000 --- a/libpagemap/MODULE_LICENSE_APACHE2 +++ /dev/null diff --git a/libpagemap/NOTICE b/libpagemap/NOTICE deleted file mode 100644 index c5b1efa7..00000000 --- a/libpagemap/NOTICE +++ /dev/null @@ -1,190 +0,0 @@ - - Copyright (c) 2005-2008, The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - diff --git a/libpagemap/include/pagemap/pagemap.h b/libpagemap/include/pagemap/pagemap.h deleted file mode 100644 index d567729f..00000000 --- a/libpagemap/include/pagemap/pagemap.h +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _PAGEMAP_PAGEMAP_H -#define _PAGEMAP_PAGEMAP_H - -#include <stdint.h> -#include <stdio.h> -#include <sys/cdefs.h> -#include <sys/types.h> -#include <sys/queue.h> - -#include <linux/kernel-page-flags.h> - -__BEGIN_DECLS - -typedef struct pm_proportional_swap pm_proportional_swap_t; - -typedef struct pm_swap_offset pm_swap_offset_t; - -struct pm_swap_offset { - unsigned int offset; - SIMPLEQ_ENTRY(pm_swap_offset) simpleqe; -}; - -typedef struct pm_memusage pm_memusage_t; - -/* Holds the various metrics for memory usage of a process or a mapping. */ -struct pm_memusage { - size_t vss; - size_t rss; - size_t pss; - size_t uss; - size_t swap; - /* if non NULL then use swap_offset_list to compute proportional swap */ - pm_proportional_swap_t *p_swap; - SIMPLEQ_HEAD(simpleqhead, pm_swap_offset) swap_offset_list; -}; - -typedef struct pm_swapusage pm_swapusage_t; -struct pm_swapusage { - size_t proportional; - size_t unique; -}; - -/* Clears a memusage. */ -void pm_memusage_zero(pm_memusage_t *mu); -/* Adds one memusage (a) to another (b). */ -void pm_memusage_add(pm_memusage_t *a, pm_memusage_t *b); -/* Adds a swap offset */ -void pm_memusage_pswap_add_offset(pm_memusage_t *mu, unsigned int offset); -/* Enable proportional swap computing. */ -void pm_memusage_pswap_init_handle(pm_memusage_t *mu, pm_proportional_swap_t *p_swap); -/* Computes and return the proportional swap */ -void pm_memusage_pswap_get_usage(pm_memusage_t *mu, pm_swapusage_t *su); -void pm_memusage_pswap_free(pm_memusage_t *mu); -/* Initialize a proportional swap computing handle: - assumes only 1 swap device, total swap size of this device in bytes to be given as argument */ -pm_proportional_swap_t * pm_memusage_pswap_create(int swap_size); -void pm_memusage_pswap_destroy(pm_proportional_swap_t *p_swap); - -typedef struct pm_kernel pm_kernel_t; -typedef struct pm_process pm_process_t; -typedef struct pm_map pm_map_t; - -/* pm_kernel_t holds the state necessary to interface to the kernel's pagemap - * system on a global level. */ -struct pm_kernel { - int kpagecount_fd; - int kpageflags_fd; - int pageidle_fd; - - int pagesize; -}; - -/* pm_process_t holds the state necessary to interface to a particular process' - * pagemap. */ -struct pm_process { - pm_kernel_t *ker; - - pid_t pid; - - pm_map_t **maps; - int num_maps; - - int pagemap_fd; -}; - -/* pm_map_t holds the state necessary to access information about a particular - * mapping in a particular process. */ -struct pm_map { - pm_process_t *proc; - - uint64_t start; - uint64_t end; - uint64_t offset; - int flags; - - char *name; -}; - -/* Create a pm_kernel_t. */ -int pm_kernel_create(pm_kernel_t **ker_out); - -#define pm_kernel_pagesize(ker) ((ker)->pagesize) - -#define pfn_to_page_idle_offset(x) ((x >> 6) << 3) - -/* Sets up the interaction with kernel's idle page tracking support - * by opening /sys/kernel/mm/page_idle/bitmap - * - * Return: - * 0 on success -errno on failure. - */ -int pm_kernel_init_page_idle(pm_kernel_t* ker); - -/* Checks if the kernel idle page tracking interface has been initialized. - * Return: - * 0 if not initialized or failed to initialize. - * 1 if we are ready to talk to page_idle/bitmap. - */ -int pm_kernel_has_page_idle(pm_kernel_t* ker); - -/* Get idle status of given page frame number. - * Returns: - * 0 if not idle i.e. page frame was accessed by the process. - * 1 if page frame continues to be idle since last time idle flag was set. - * -errno on failure - */ -int pm_kernel_get_page_idle(pm_kernel_t* ker, uint64_t pfn); - -/* Mark page frames idle. - * Return: - * 0 on success -errno on failure. - */ -int pm_kernel_mark_page_idle(pm_kernel_t* ker, uint64_t* pfn, int n); - -/* Determines if the page frame has been accessed by user space since - * the working set was last reset - * 0 If page frame wasn't accessed. - * 1 If page frame was accessed. - * -errno on failure. - */ -int pm_kernel_page_is_accessed(pm_kernel_t* ker, uint64_t pfn, uint64_t* flags); - -/* Get a list of probably-existing PIDs (returned through *pids_out). - * Length of the array (in sizeof(pid_t) units) is returned through *len. - * The array should be freed by the caller. */ -int pm_kernel_pids(pm_kernel_t *ker, pid_t **pids_out, size_t *len); - -/* Get the map count (from /proc/kpagecount) of a physical frame. - * The count is returned through *count_out. */ -int pm_kernel_count(pm_kernel_t *ker, uint64_t pfn, uint64_t *count_out); - -/* Get the page flags (from /proc/kpageflags) of a physical frame. - * Flag constants are in <linux/kernel-page-flags.h>. - * The count is returned through *flags_out. - */ -int pm_kernel_flags(pm_kernel_t *ker, uint64_t pfn, uint64_t *flags_out); - -/* Destroy a pm_kernel_t. */ -int pm_kernel_destroy(pm_kernel_t *ker); - -/* Get the PID of a pm_process_t. */ -#define pm_process_pid(proc) ((proc)->pid) - -/* Create a pm_process_t and returns it through *proc_out. - * Takes a pm_kernel_t, and the PID of the process. */ -int pm_process_create(pm_kernel_t *ker, pid_t pid, pm_process_t **proc_out); - -/* Get the total memory usage of a process and store in *usage_out. */ -int pm_process_usage(pm_process_t *proc, pm_memusage_t *usage_out); - -/* Get the total memory usage of a process and store in *usage_out, only - * counting pages with specified flags. */ -int pm_process_usage_flags(pm_process_t *proc, pm_memusage_t *usage_out, - uint64_t flags_mask, uint64_t required_flags); - -/* Get the working set of a process (if ws_out != NULL), and reset it - * (if reset != 0). */ -int pm_process_workingset(pm_process_t *proc, pm_memusage_t *ws_out, int reset); - -/* Get the PFNs corresponding to a range of virtual addresses. - * The array of PFNs is returned through *range_out, and the caller has the - * responsibility to free it. */ -int pm_process_pagemap_range(pm_process_t *proc, - uint64_t low, uint64_t hi, - uint64_t **range_out, size_t *len); - -#define _BITS(x, offset, bits) (((x) >> (offset)) & ((1LL << (bits)) - 1)) - -#define PM_PAGEMAP_PRESENT(x) (_BITS(x, 63, 1)) -#define PM_PAGEMAP_SWAPPED(x) (_BITS(x, 62, 1)) -#define PM_PAGEMAP_SHIFT(x) (_BITS(x, 55, 6)) -#define PM_PAGEMAP_PFN(x) (_BITS(x, 0, 55)) -#define PM_PAGEMAP_SWAP_OFFSET(x) (_BITS(x, 5, 50)) -#define PM_PAGEMAP_SWAP_TYPE(x) (_BITS(x, 0, 5)) - -/* Get the maps in the virtual address space of this process. - * Returns an array of pointers to pm_map_t through *maps. - * The array should be freed by the caller, but the maps should not be - * modified or destroyed. */ -int pm_process_maps(pm_process_t *proc, pm_map_t ***maps_out, size_t *len); - -/* Destroy a pm_process_t. */ -int pm_process_destroy(pm_process_t *proc); - -/* Get the name, flags, start/end address, or offset of a map. */ -#define pm_map_name(map) ((map)->name) -#define pm_map_flags(map) ((map)->flags) -#define PM_MAP_READ 1 -#define PM_MAP_WRITE 2 -#define PM_MAP_EXEC 4 -#define PM_MAP_PERMISSIONS (PM_MAP_READ | PM_MAP_WRITE | PM_MAP_EXEC) -#define pm_map_start(map) ((map)->start) -#define pm_map_end(map) ((map)->end) -#define pm_map_offset(map) ((map)->offset) - -/* Get the PFNs of the pages in the virtual address space of this map. - * Array of PFNs is returned through *pagemap_out, and should be freed by the - * caller. */ -int pm_map_pagemap(pm_map_t *map, uint64_t **pagemap_out, size_t *len); - -/* Mark all the present pages in process's VM as idle */ -int pm_map_mark_idle(pm_map_t* map); - -/* Get the memory usage of this map alone. */ -int pm_map_usage(pm_map_t *map, pm_memusage_t *usage_out); - -/* Get the memory usage of this map alone, only counting pages with specified - * flags. */ -int pm_map_usage_flags(pm_map_t *map, pm_memusage_t *usage_out, - uint64_t flags_mask, uint64_t required_flags); - -/* Get the working set of this map alone. */ -int pm_map_workingset(pm_map_t *map, pm_memusage_t *ws_out); - -__END_DECLS - -#endif diff --git a/libpagemap/pagemap_test.cpp b/libpagemap/pagemap_test.cpp deleted file mode 100644 index 592072c6..00000000 --- a/libpagemap/pagemap_test.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <pagemap/pagemap.h> - -#include <string> - -#include <gtest/gtest.h> - -TEST(pagemap, maps) { - pm_kernel_t* kernel; - ASSERT_EQ(0, pm_kernel_create(&kernel)); - - pm_process_t* process; - ASSERT_EQ(0, pm_process_create(kernel, getpid(), &process)); - - pm_map_t** maps; - size_t num_maps; - ASSERT_EQ(0, pm_process_maps(process, &maps, &num_maps)); - - bool found_heap = false; - bool found_stack = false; - for (size_t i = 0; i < num_maps; i++) { - std::string name(maps[i]->name); - if (name == "[heap]" || name == "[anon:libc_malloc]") found_heap = true; - if (name == "[stack]") found_stack = true; - } - - ASSERT_TRUE(found_heap); - ASSERT_TRUE(found_stack); - - free(maps); - pm_process_destroy(process); - pm_kernel_destroy(kernel); -} diff --git a/libpagemap/pm_kernel.c b/libpagemap/pm_kernel.c deleted file mode 100644 index 1a3f70b1..00000000 --- a/libpagemap/pm_kernel.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <dirent.h> -#include <errno.h> -#include <fcntl.h> -#include <stdint.h> -#include <stdlib.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <unistd.h> - -#include <pagemap/pagemap.h> - -int pm_kernel_create(pm_kernel_t **ker_out) { - pm_kernel_t *ker; - int error; - - if (!ker_out) - return 1; - - ker = calloc(1, sizeof(*ker)); - if (!ker) - return -errno; - - ker->kpagecount_fd = open("/proc/kpagecount", O_RDONLY); - if (ker->kpagecount_fd < 0) { - error = -errno; - free(ker); - return error; - } - - ker->kpageflags_fd = open("/proc/kpageflags", O_RDONLY); - if (ker->kpageflags_fd < 0) { - error = -errno; - close(ker->kpagecount_fd); - free(ker); - return error; - } - - /* This must be explicitly initialized through pm_kernel_init_page_idle() */ - ker->pageidle_fd = -1; - - ker->pagesize = getpagesize(); - - *ker_out = ker; - - return 0; -} - -int pm_kernel_init_page_idle(pm_kernel_t* ker) { - if (!ker || ker->pageidle_fd != -1) { - return -EINVAL; - } - - ker->pageidle_fd = open("/sys/kernel/mm/page_idle/bitmap", O_RDWR | O_CLOEXEC); - if (ker->pageidle_fd < 0) { - return -errno; - } - - return 0; -} - -#define INIT_PIDS 20 -int pm_kernel_pids(pm_kernel_t *ker __unused, pid_t **pids_out, size_t *len) { - DIR *proc; - struct dirent *dir; - pid_t pid, *pids, *new_pids; - size_t pids_count, pids_size; - int error; - - proc = opendir("/proc"); - if (!proc) - return -errno; - - pids = malloc(INIT_PIDS * sizeof(pid_t)); - if (!pids) { - closedir(proc); - return -errno; - } - pids_count = 0; pids_size = INIT_PIDS; - - while ((dir = readdir(proc))) { - if (sscanf(dir->d_name, "%d", &pid) < 1) - continue; - - if (pids_count >= pids_size) { - new_pids = realloc(pids, 2 * pids_size * sizeof(pid_t)); - if (!new_pids) { - error = -errno; - free(pids); - closedir(proc); - return error; - } - pids = new_pids; - pids_size = 2 * pids_size; - } - - pids[pids_count] = pid; - - pids_count++; - } - - closedir(proc); - - new_pids = realloc(pids, pids_count * sizeof(pid_t)); - if (!new_pids) { - error = -errno; - free(pids); - return error; - } - - *pids_out = new_pids; - *len = pids_count; - - return 0; -} - -int pm_kernel_count(pm_kernel_t *ker, uint64_t pfn, uint64_t *count_out) { - off64_t off; - - if (!ker || !count_out) return -1; - - off = lseek64(ker->kpagecount_fd, pfn * sizeof(uint64_t), SEEK_SET); - if (off == (off64_t)-1) return -errno; - if (TEMP_FAILURE_RETRY(read(ker->kpagecount_fd, count_out, sizeof(uint64_t))) < - (ssize_t)sizeof(uint64_t)) { - return -errno; - } - - return 0; -} - -int pm_kernel_flags(pm_kernel_t* ker, uint64_t pfn, uint64_t* flags_out) { - off64_t off; - - if (!ker || !flags_out) { - return -EINVAL; - } - - off = lseek64(ker->kpageflags_fd, pfn * sizeof(uint64_t), SEEK_SET); - if (off == (off64_t)-1) return -errno; - if (TEMP_FAILURE_RETRY(read(ker->kpageflags_fd, flags_out, sizeof(uint64_t))) < - (ssize_t)sizeof(uint64_t)) { - return -errno; - } - - return 0; -} - -int pm_kernel_has_page_idle(pm_kernel_t* ker) { - /* Treat error to be fallback to clear_refs */ - if (!ker) { - return 0; - } - - return !(ker->pageidle_fd < 0); -} - -int pm_kernel_get_page_idle(pm_kernel_t* ker, uint64_t pfn) { - uint64_t bits; - off64_t offset; - - if (!ker) { - return -EINVAL; - } - - if (ker->pageidle_fd < 0) { - return -ENXIO; - } - - offset = pfn_to_page_idle_offset(pfn); - if (pread64(ker->pageidle_fd, &bits, sizeof(uint64_t), offset) < 0) { - return -errno; - } - - bits >>= (pfn % 64); - - return bits & 1; -} - -int pm_kernel_mark_page_idle(pm_kernel_t* ker, uint64_t* pfn, int n) { - uint64_t bits; - - if (!ker) { - return -EINVAL; - } - - if (ker->pageidle_fd < 0) { - return -ENXIO; - } - - for (int i = 0; i < n; i++) { - off64_t offset = pfn_to_page_idle_offset(pfn[i]); - if (pread64(ker->pageidle_fd, &bits, sizeof(uint64_t), offset) < 0) { - return -errno; - } - - bits |= 1ULL << (pfn[i] % 64); - - if (pwrite64(ker->pageidle_fd, &bits, sizeof(uint64_t), offset) < 0) { - return -errno; - } - } - - return 0; -} - -int pm_kernel_page_is_accessed(pm_kernel_t* ker, uint64_t pfn, uint64_t* flags) { - int error; - uint64_t page_flags; - - if (!ker) { - return -EINVAL; - } - - if (pm_kernel_has_page_idle(ker)) { - return pm_kernel_get_page_idle(ker, pfn); - } - - if (!flags) { - flags = &page_flags; - error = pm_kernel_flags(ker, pfn, flags); - if (error) return error; - } - - return !!(*flags & (1 << KPF_REFERENCED)); -} - -int pm_kernel_destroy(pm_kernel_t *ker) { - if (!ker) - return -1; - - close(ker->kpagecount_fd); - close(ker->kpageflags_fd); - if (ker->pageidle_fd >= 0) { - close(ker->pageidle_fd); - } - - free(ker); - - return 0; -} diff --git a/libpagemap/pm_map.c b/libpagemap/pm_map.c deleted file mode 100644 index 3e23c41c..00000000 --- a/libpagemap/pm_map.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <errno.h> -#include <stdlib.h> -#include <string.h> - -#include <pagemap/pagemap.h> - -int pm_map_pagemap(pm_map_t *map, uint64_t **pagemap_out, size_t *len) { - if (!map) { - return -EINVAL; - } - - return pm_process_pagemap_range(map->proc, map->start, map->end, - pagemap_out, len); -} - -int pm_map_mark_idle(pm_map_t* map) { - uint64_t* pagemap; - size_t len; - int error; - - if (!map) { - return -EINVAL; - } - - error = pm_map_pagemap(map, &pagemap, &len); - if (error) { - return error; - } - - for (size_t i = 0; i < len; i++) { - uint64_t pfn; - if (!PM_PAGEMAP_PRESENT(pagemap[i])) { - continue; - } - pfn = PM_PAGEMAP_PFN(pagemap[i]); - error = pm_kernel_mark_page_idle(map->proc->ker, &pfn, 1); - if (error) { - break; - } - } - - free(pagemap); - return error; -} - -int pm_map_usage_flags(pm_map_t *map, pm_memusage_t *usage_out, - uint64_t flags_mask, uint64_t required_flags) { - uint64_t *pagemap; - size_t len, i; - uint64_t count; - pm_memusage_t usage; - int error; - - if (!map || !usage_out) - return -1; - - error = pm_map_pagemap(map, &pagemap, &len); - if (error) return error; - - pm_memusage_zero(&usage); - pm_memusage_pswap_init_handle(&usage, usage_out->p_swap); - - for (i = 0; i < len; i++) { - usage.vss += map->proc->ker->pagesize; - - if (!PM_PAGEMAP_PRESENT(pagemap[i]) && !PM_PAGEMAP_SWAPPED(pagemap[i])) continue; - - if (!PM_PAGEMAP_SWAPPED(pagemap[i])) { - if (flags_mask) { - uint64_t flags; - error = pm_kernel_flags(map->proc->ker, PM_PAGEMAP_PFN(pagemap[i]), &flags); - if (error) goto out; - - if ((flags & flags_mask) != required_flags) continue; - } - - error = pm_kernel_count(map->proc->ker, PM_PAGEMAP_PFN(pagemap[i]), &count); - if (error) goto out; - - usage.rss += (count >= 1) ? map->proc->ker->pagesize : (0); - usage.pss += (count >= 1) ? (map->proc->ker->pagesize / count) : (0); - usage.uss += (count == 1) ? (map->proc->ker->pagesize) : (0); - } else { - usage.swap += map->proc->ker->pagesize; - pm_memusage_pswap_add_offset(&usage, PM_PAGEMAP_SWAP_OFFSET(pagemap[i])); - } - } - - memcpy(usage_out, &usage, sizeof(usage)); - - error = 0; - -out: - free(pagemap); - - return error; -} - -int pm_map_usage(pm_map_t* map, pm_memusage_t* usage_out) { - return pm_map_usage_flags(map, usage_out, 0, 0); -} - -int pm_map_workingset(pm_map_t* map, pm_memusage_t* ws_out) { - uint64_t* pagemap; - size_t len, i; - uint64_t count; - pm_memusage_t ws; - int error; - - if (!map || !ws_out) return -1; - - error = pm_map_pagemap(map, &pagemap, &len); - if (error) return error; - - pm_memusage_zero(&ws); - - for (i = 0; i < len; i++) { - if (!PM_PAGEMAP_PRESENT(pagemap[i]) && !PM_PAGEMAP_SWAPPED(pagemap[i])) { - continue; - } - - if (!pm_kernel_page_is_accessed(map->proc->ker, PM_PAGEMAP_PFN(pagemap[i]), NULL)) { - continue; - } - - error = pm_kernel_count(map->proc->ker, PM_PAGEMAP_PFN(pagemap[i]), &count); - if (error) { - goto out; - } - - ws.vss += map->proc->ker->pagesize; - if (PM_PAGEMAP_SWAPPED(pagemap[i])) { - continue; - } - ws.rss += (count >= 1) ? (map->proc->ker->pagesize) : (0); - ws.pss += (count >= 1) ? (map->proc->ker->pagesize / count) : (0); - ws.uss += (count == 1) ? (map->proc->ker->pagesize) : (0); - } - - memcpy(ws_out, &ws, sizeof(ws)); - - error = 0; - -out: - free(pagemap); - - return 0; -} - -int pm_map_destroy(pm_map_t *map) { - if (!map) - return -1; - - free(map->name); - free(map); - - return 0; -} diff --git a/libpagemap/pm_map.h b/libpagemap/pm_map.h deleted file mode 100644 index 08dc4485..00000000 --- a/libpagemap/pm_map.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _LIBS_PAGEMAP_PM_MAP_H -#define _LIBS_PAGEMAP_PM_MAP_H - -#include <pagemap/pagemap.h> - -int pm_map_destroy(pm_map_t *map); - -#endif diff --git a/libpagemap/pm_memusage.c b/libpagemap/pm_memusage.c deleted file mode 100644 index 71a5783e..00000000 --- a/libpagemap/pm_memusage.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdlib.h> -#include <unistd.h> - -#include <pagemap/pagemap.h> - -#define SIMPLEQ_INSERT_SIMPLEQ_TAIL(head_a, head_b) \ - do { \ - if (!SIMPLEQ_EMPTY(head_b)) { \ - if ((head_a)->sqh_first == NULL) \ - (head_a)->sqh_first = (head_b)->sqh_first; \ - *(head_a)->sqh_last = (head_b)->sqh_first; \ - (head_a)->sqh_last = (head_b)->sqh_last; \ - } \ - } while (/*CONSTCOND*/0) - -/* We use an array of int to store the references to a given offset in the swap - 1 GiB swap means 512KiB size array: offset are the index */ -typedef unsigned short pm_pswap_refcount_t; -struct pm_proportional_swap { - unsigned int array_size; - pm_pswap_refcount_t *offset_array; -}; - -void pm_memusage_zero(pm_memusage_t *mu) { - mu->vss = mu->rss = mu->pss = mu->uss = mu->swap = 0; - mu->p_swap = NULL; - SIMPLEQ_INIT(&mu->swap_offset_list); -} - -void pm_memusage_pswap_init_handle(pm_memusage_t *mu, pm_proportional_swap_t *p_swap) { - mu->p_swap = p_swap; -} - -void pm_memusage_add(pm_memusage_t *a, pm_memusage_t *b) { - a->vss += b->vss; - a->rss += b->rss; - a->pss += b->pss; - a->uss += b->uss; - a->swap += b->swap; - SIMPLEQ_INSERT_SIMPLEQ_TAIL(&a->swap_offset_list, &b->swap_offset_list); -} - -pm_proportional_swap_t * pm_memusage_pswap_create(int swap_size) -{ - pm_proportional_swap_t *p_swap = NULL; - - p_swap = malloc(sizeof(pm_proportional_swap_t)); - if (p_swap == NULL) { - fprintf(stderr, "Error allocating proportional swap.\n"); - } else { - p_swap->array_size = swap_size / getpagesize(); - p_swap->offset_array = calloc(p_swap->array_size, sizeof(pm_pswap_refcount_t)); - if (p_swap->offset_array == NULL) { - fprintf(stderr, "Error allocating proportional swap offset array.\n"); - free(p_swap); - p_swap = NULL; - } - } - - return p_swap; -} - -void pm_memusage_pswap_destroy(pm_proportional_swap_t *p_swap) { - if (p_swap) { - free(p_swap->offset_array); - free(p_swap); - } -} - -void pm_memusage_pswap_add_offset(pm_memusage_t *mu, unsigned int offset) { - pm_swap_offset_t *soff; - - if (mu->p_swap == NULL) - return; - - if (offset >= mu->p_swap->array_size) { - fprintf(stderr, "SWAP offset %d is out of swap bounds.\n", offset); - return; - } - - if (mu->p_swap->offset_array[offset] == USHRT_MAX) { - fprintf(stderr, "SWAP offset %d ref. count if overflowing ushort type.\n", offset); - } else { - mu->p_swap->offset_array[offset]++; - } - - soff = malloc(sizeof(pm_swap_offset_t)); - if (soff) { - soff->offset = offset; - SIMPLEQ_INSERT_TAIL(&mu->swap_offset_list, soff, simpleqe); - } -} - -void pm_memusage_pswap_get_usage(pm_memusage_t *mu, pm_swapusage_t *su) { - - int pagesize = getpagesize(); - pm_swap_offset_t *elem; - - if (su == NULL) - return; - - su->proportional = su->unique = 0; - SIMPLEQ_FOREACH(elem, &mu->swap_offset_list, simpleqe) { - su->proportional += pagesize / mu->p_swap->offset_array[elem->offset]; - su->unique += mu->p_swap->offset_array[elem->offset] == 1 ? pagesize : 0; - } -} - -void pm_memusage_pswap_free(pm_memusage_t *mu) { - pm_swap_offset_t *elem = SIMPLEQ_FIRST(&mu->swap_offset_list); - while (elem) { - SIMPLEQ_REMOVE_HEAD(&mu->swap_offset_list, simpleqe); - free(elem); - elem = SIMPLEQ_FIRST(&mu->swap_offset_list); - } -} diff --git a/libpagemap/pm_process.c b/libpagemap/pm_process.c deleted file mode 100644 index 98c1c6a0..00000000 --- a/libpagemap/pm_process.c +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <errno.h> -#include <fcntl.h> -#include <inttypes.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include <pagemap/pagemap.h> - -#include "pm_map.h" - -static int read_maps(pm_process_t *proc); -static int pm_process_clear_refs(pm_process_t* proc); -static int pm_process_mark_idle(pm_process_t* proc); - -#define MAX_FILENAME 64 - -int pm_process_create(pm_kernel_t *ker, pid_t pid, pm_process_t **proc_out) { - pm_process_t *proc; - char filename[MAX_FILENAME]; - int error; - - if (!ker || !proc_out) - return -1; - - proc = calloc(1, sizeof(*proc)); - if (!proc) - return errno; - - proc->ker = ker; - proc->pid = pid; - - error = snprintf(filename, MAX_FILENAME, "/proc/%d/pagemap", pid); - if (error < 0 || error >= MAX_FILENAME) { - error = (error < 0) ? (errno) : (-1); - free(proc); - return error; - } - - proc->pagemap_fd = open(filename, O_RDONLY); - if (proc->pagemap_fd < 0) { - error = errno; - free(proc); - return error; - } - - error = read_maps(proc); - if (error) { - free(proc); - return error; - } - - *proc_out = proc; - - return 0; -} - -int pm_process_usage_flags(pm_process_t *proc, pm_memusage_t *usage_out, - uint64_t flags_mask, uint64_t required_flags) -{ - pm_memusage_t usage, map_usage; - int error; - int i; - - if (!proc || !usage_out) - return -1; - - pm_memusage_zero(&usage); - pm_memusage_pswap_init_handle(&usage, usage_out->p_swap); - - pm_memusage_zero(&map_usage); - pm_memusage_pswap_init_handle(&map_usage, usage_out->p_swap); - - for (i = 0; i < proc->num_maps; i++) { - error = pm_map_usage_flags(proc->maps[i], &map_usage, flags_mask, - required_flags); - if (error) return error; - - pm_memusage_add(&usage, &map_usage); - } - - memcpy(usage_out, &usage, sizeof(pm_memusage_t)); - - return 0; - -} - -int pm_process_usage(pm_process_t *proc, pm_memusage_t *usage_out) { - return pm_process_usage_flags(proc, usage_out, 0, 0); -} - -int pm_process_pagemap_range(pm_process_t *proc, - uint64_t low, uint64_t high, - uint64_t **range_out, size_t *len) { - uint64_t firstpage; - uint64_t numpages; - uint64_t *range; - off64_t off; - int error; - - if (!proc || (low > high) || !range_out || !len) { - return -EINVAL; - } - - if (low == high) { - *range_out = NULL; - *len = 0; - return 0; - } - - firstpage = low / proc->ker->pagesize; - numpages = (high - low) / proc->ker->pagesize; - - range = malloc(numpages * sizeof(uint64_t)); - if (!range) { - return -ENOMEM; - } - - off = lseek64(proc->pagemap_fd, firstpage * sizeof(uint64_t), SEEK_SET); - if (off == (off_t)-1) { - error = -errno; - free(range); - return error; - } - error = read(proc->pagemap_fd, (char*)range, numpages * sizeof(uint64_t)); - if (error == 0) { - /* EOF, mapping is not in userspace mapping range (probably vectors) */ - *len = 0; - free(range); - *range_out = NULL; - return 0; - } else if (error < 0 || (error > 0 && error < (int)(numpages * sizeof(uint64_t)))) { - error = (error < 0) ? -errno : -EIO; - free(range); - return error; - } - - *range_out = range; - *len = numpages; - - return 0; -} - -int pm_process_maps(pm_process_t *proc, pm_map_t ***maps_out, size_t *len) { - pm_map_t **maps; - - if (!proc || !maps_out || !len) - return -1; - - if (proc->num_maps) { - maps = malloc(proc->num_maps * sizeof(pm_map_t*)); - if (!maps) - return errno; - - memcpy(maps, proc->maps, proc->num_maps * sizeof(pm_map_t*)); - - *maps_out = maps; - } else { - *maps_out = NULL; - } - *len = proc->num_maps; - - return 0; -} - -int pm_process_workingset(pm_process_t *proc, - pm_memusage_t *ws_out, int reset) { - pm_memusage_t ws, map_ws; - int i; - int error; - - if (!proc) - return -1; - - if (ws_out) { - pm_memusage_zero(&ws); - pm_memusage_pswap_init_handle(&ws, ws_out->p_swap); - - pm_memusage_zero(&map_ws); - pm_memusage_pswap_init_handle(&map_ws, ws_out->p_swap); - - for (i = 0; i < proc->num_maps; i++) { - error = pm_map_workingset(proc->maps[i], &map_ws); - if (error) return error; - - pm_memusage_add(&ws, &map_ws); - } - memcpy(ws_out, &ws, sizeof(ws)); - } - - if (reset) { - return pm_kernel_has_page_idle(proc->ker) ? pm_process_mark_idle(proc) - : pm_process_clear_refs(proc); - } - - return 0; -} - -int pm_process_destroy(pm_process_t *proc) { - int i; - - if (!proc) - return -1; - - for (i = 0; i < proc->num_maps; i++) { - pm_map_destroy(proc->maps[i]); - } - free(proc->maps); - close(proc->pagemap_fd); - free(proc); - - return 0; -} - -#define INITIAL_MAPS 10 -#define MAX_PERMS 5 - -static int read_maps(pm_process_t *proc) { - char filename[MAX_FILENAME]; - char *line = NULL; - size_t line_length = 0; - char perms[MAX_PERMS]; - FILE *maps_f; - pm_map_t *map, **maps, **new_maps; - int maps_count, maps_size; - int error; - - if (!proc) - return -1; - - maps = calloc(INITIAL_MAPS, sizeof(pm_map_t*)); - if (!maps) - return errno; - maps_count = 0; maps_size = INITIAL_MAPS; - - error = snprintf(filename, MAX_FILENAME, "/proc/%d/maps", proc->pid); - if (error < 0 || error >= MAX_FILENAME) { - free(maps); - return (error < 0) ? (errno) : (-1); - } - - maps_f = fopen(filename, "r"); - if (!maps_f) { - free(maps); - return errno; - } - - while (getline(&line, &line_length, maps_f) != -1) { - line[strlen(line) - 1] = '\0'; // Lose the newline. - - if (maps_count >= maps_size) { - new_maps = realloc(maps, 2 * maps_size * sizeof(pm_map_t*)); - if (!new_maps) { - error = errno; - free(maps); - free(line); - fclose(maps_f); - return error; - } - maps = new_maps; - maps_size *= 2; - } - - maps[maps_count] = map = calloc(1, sizeof(*map)); - - map->proc = proc; - - int name_offset; - sscanf(line, "%" SCNx64 "-%" SCNx64 " %4s %" SCNx64 " %*s %*d %n", - &map->start, &map->end, perms, &map->offset, &name_offset); - - map->name = strdup(line + name_offset); - if (!map->name) { - error = errno; - for (; maps_count > 0; maps_count--) - pm_map_destroy(maps[maps_count]); - free(maps); - free(line); - fclose(maps_f); - return error; - } - - if (perms[0] == 'r') map->flags |= PM_MAP_READ; - if (perms[1] == 'w') map->flags |= PM_MAP_WRITE; - if (perms[2] == 'x') map->flags |= PM_MAP_EXEC; - - maps_count++; - } - - free(line); - fclose(maps_f); - - new_maps = realloc(maps, maps_count * sizeof(pm_map_t*)); - if (maps_count && !new_maps) { - error = errno; - free(maps); - return error; - } - - proc->maps = new_maps; - proc->num_maps = maps_count; - - return 0; -} - -static int pm_process_clear_refs(pm_process_t* proc) { - int error; - char filename[MAX_FILENAME]; - - if (!proc) { - return -EINVAL; - } - - error = snprintf(filename, MAX_FILENAME, "/proc/%d/clear_refs", proc->pid); - if (error < 0 || error >= MAX_FILENAME) { - return (error < 0) ? -errno : -1; - } - - int fd = open(filename, O_WRONLY | O_CLOEXEC); - if (fd < 0) { - return -errno; - } - - const char* cmd = "1\n"; - size_t cmdlen = strlen(cmd); - - error = TEMP_FAILURE_RETRY(write(fd, cmd, cmdlen)); - error = (error == cmdlen) ? 0 : -errno; - - close(fd); - - return error; -} - -static int pm_process_mark_idle(pm_process_t* proc) { - int error; - - if (!proc) { - return -EINVAL; - } - - for (int i = 0; i < proc->num_maps; i++) { - error = pm_map_mark_idle(proc->maps[i]); - if (error) { - return error; - } - } - - return 0; -} |