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 <stdlib.h> 48 : #include <unistd.h> 49 : 50 : static int proc_stat_fd; 51 : static long linux_page_size; 52 : 53 : int mem_stat_setup(void) 54 : { 55 : proc_stat_fd = open("/proc/self/statm", O_RDONLY); 56 : if (proc_stat_fd == -1) 57 : return -1; 58 : 59 : linux_page_size = sysconf(_SC_PAGESIZE); 60 : return 0; 61 : } 62 : 63 : size_t mem_stat_rss_current_get(void) 64 : { 65 : char res[40]; // sufficient for two 64 bit base 10 numbers and a space 66 : if (__builtin_expect(lseek(proc_stat_fd, 0, SEEK_SET) == -1 || 67 : read(proc_stat_fd, res, sizeof(res) - 1) == -1, 0)) 68 : return (size_t)0; 69 : 70 : res[sizeof(res) - 1] = '\0'; 71 : 72 : size_t i = 0; 73 : while (res[i] && !isspace(res[i])) { 74 : ++i; 75 : } 76 : 77 : return (size_t)(strtoull(&res[i], NULL, 10) * linux_page_size); 78 : } 79 : 80 : #else 81 : 82 : int mem_stat_setup(void) 83 : { 84 : return 0; 85 : } 86 : 87 : size_t mem_stat_rss_current_get(void) 88 : { 89 : return 0; 90 : } 91 : 92 : #endif 93 : 94 : size_t mem_stat_rss_max_get(void) 95 : { 96 : struct rusage res; 97 : getrusage(RUSAGE_SELF, &res); 98 : 99 : #ifdef __MACOS 100 : return (size_t)res.ru_maxrss; 101 : #else 102 : return (size_t)res.ru_maxrss * 1024; 103 : #endif 104 : } 105 : 106 : #endif 107 : 108 : #ifdef __WINDOWS 109 : 110 : #include <psapi.h> 111 : #include <windows.h> 112 : 113 : int mem_stat_setup(void) 114 : { 115 : return 0; 116 : } 117 : 118 : size_t mem_stat_rss_current_get(void) 119 : { 120 : PROCESS_MEMORY_COUNTERS info; 121 : GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info)); 122 : return (size_t)info.WorkingSetSize; 123 : } 124 : 125 : size_t mem_stat_rss_max_get(void) 126 : { 127 : PROCESS_MEMORY_COUNTERS info; 128 : GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info)); 129 : return (size_t)info.PeakWorkingSetSize; 130 : } 131 : 132 : #endif 133 : 134 :