Line data Source code
1 1 : /** 2 : * @file arch/mem.c 3 : * 4 : * @brief Platform specific memory utilities 5 : * 6 : * This module implements some memory related utilities such as memory 7 : * statistics retrieval in a platform independent way 8 : * 9 : * SPDX-FileCopyrightText: 2008-2021 HPDCS Group <rootsim@googlegroups.com> 10 : * SPDX-License-Identifier: GPL-3.0-only 11 : */ 12 : #include <arch/mem.h> 13 : 14 : #include <arch/platform.h> 15 : 16 : #ifdef __POSIX 17 : 18 : #include <sys/resource.h> 19 : #include <sys/time.h> 20 : 21 : #if defined(__MACOS) 22 : 23 : #include <mach/mach_init.h> 24 : #include <mach/mach_port.h> 25 : #include <mach/task.h> 26 : #include <mach/task_info.h> 27 : 28 : int mem_stat_setup(void) 29 : { 30 : return 0; 31 : } 32 : 33 : size_t mem_stat_rss_current_get(void) 34 : { 35 : struct mach_task_basic_info info; 36 : mach_msg_type_number_t count = MACH_TASK_BASIC_INFO_COUNT; 37 : if (__builtin_expect(task_info(mach_task_self(), MACH_TASK_BASIC_INFO, 38 : (task_info_t)&info, &count) != KERN_SUCCESS, 0)) 39 : return (size_t)0; 40 : return (size_t)info.resident_size; 41 : } 42 : 43 : #elif defined(__LINUX) 44 : 45 : #include <ctype.h> 46 : #include <fcntl.h> 47 : #include <unistd.h> 48 : 49 : static int proc_stat_fd; 50 : static long linux_page_size; 51 : 52 : int mem_stat_setup(void) 53 : { 54 : proc_stat_fd = open("/proc/self/statm", O_RDONLY); 55 : if (proc_stat_fd == -1) 56 : return -1; 57 : 58 : linux_page_size = sysconf(_SC_PAGESIZE); 59 : return 0; 60 : } 61 : 62 : size_t mem_stat_rss_current_get(void) 63 : { 64 : char res[40]; // sufficient for two 64 bit base 10 numbers and a space 65 : if (__builtin_expect(lseek(proc_stat_fd, 0, SEEK_SET) == -1 || 66 : read(proc_stat_fd, res, sizeof(res) - 1) == -1, 0)) 67 : return (size_t)0; 68 : 69 : res[sizeof(res) - 1] = '\0'; 70 : 71 : size_t i = 0; 72 : while (res[i] && !isspace(res[i])) { 73 : ++i; 74 : } 75 : 76 : return (size_t)(strtoull(&res[i], NULL, 10) * linux_page_size); 77 : } 78 : 79 : #else 80 : 81 : int mem_stat_setup(void) 82 : { 83 : return 0; 84 : } 85 : 86 : size_t mem_stat_rss_current_get(void) 87 : { 88 : return 0; 89 : } 90 : 91 : #endif 92 : 93 : size_t mem_stat_rss_max_get(void) 94 : { 95 : struct rusage res; 96 : getrusage(RUSAGE_SELF, &res); 97 : 98 : #ifdef __MACOS 99 : return (size_t)res.ru_maxrss; 100 : #else 101 : return (size_t)res.ru_maxrss * 1024; 102 : #endif 103 : } 104 : 105 : #endif 106 : 107 : #ifdef __WINDOWS 108 : 109 : #include <psapi.h> 110 : #include <windows.h> 111 : 112 : int mem_stat_setup(void) 113 : { 114 : return 0; 115 : } 116 : 117 : size_t mem_stat_rss_current_get(void) 118 : { 119 : PROCESS_MEMORY_COUNTERS info; 120 : GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info)); 121 : return (size_t)info.WorkingSetSize; 122 : } 123 : 124 : size_t mem_stat_rss_max_get(void) 125 : { 126 : PROCESS_MEMORY_COUNTERS info; 127 : GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info)); 128 : return (size_t)info.PeakWorkingSetSize; 129 : } 130 : 131 : #endif 132 : 133 :