File indexing completed on 2024-05-05 03:48:22
0001 /* 0002 SPDX-FileCopyrightText: David Robert Nadeau <http://NadeauSoftware.com/> 0003 SPDX-License-Identifier: CC-BY-3.0 0004 */ 0005 0006 //http://nadeausoftware.com/articles/2012/07/c_c_tip_how_get_process_resident_set_size_physical_memory_use 0007 0008 #if defined(_WIN32) 0009 #include <windows.h> 0010 #include <psapi.h> 0011 0012 #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__)) || defined(__HAIKU__) 0013 #include <unistd.h> 0014 #include <sys/resource.h> 0015 0016 #if defined(__APPLE__) && defined(__MACH__) 0017 #include <mach/mach.h> 0018 0019 #elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__))) 0020 #include <fcntl.h> 0021 #include <procfs.h> 0022 0023 #elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__) 0024 #include <stdio.h> 0025 0026 #endif 0027 0028 #else 0029 #error "Cannot define getPeakRSS( ) or getCurrentRSS( ) for an unknown OS." 0030 #endif 0031 0032 0033 0034 0035 0036 /** 0037 * Returns the peak (maximum so far) resident set size (physical 0038 * memory use) measured in bytes, or zero if the value cannot be 0039 * determined on this OS. 0040 */ 0041 size_t getPeakRSS( ) 0042 { 0043 #if defined(_WIN32) 0044 /* Windows -------------------------------------------------- */ 0045 PROCESS_MEMORY_COUNTERS info; 0046 GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) ); 0047 return (size_t)info.PeakWorkingSetSize; 0048 0049 #elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__))) 0050 /* AIX and Solaris ------------------------------------------ */ 0051 struct psinfo psinfo; 0052 int fd = -1; 0053 if ( (fd = open( "/proc/self/psinfo", O_RDONLY )) == -1 ) 0054 return (size_t)0L; /* Can't open? */ 0055 if ( read( fd, &psinfo, sizeof(psinfo) ) != sizeof(psinfo) ) 0056 { 0057 close( fd ); 0058 return (size_t)0L; /* Can't read? */ 0059 } 0060 close( fd ); 0061 return (size_t)(psinfo.pr_rssize * 1024L); 0062 0063 #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__)) 0064 /* BSD, Linux, and OSX -------------------------------------- */ 0065 struct rusage rusage; 0066 getrusage( RUSAGE_SELF, &rusage ); 0067 #if defined(__APPLE__) && defined(__MACH__) 0068 return (size_t)rusage.ru_maxrss; 0069 #else 0070 return (size_t)(rusage.ru_maxrss * 1024L); 0071 #endif 0072 0073 #else 0074 /* Unknown OS ----------------------------------------------- */ 0075 return (size_t)0L; /* Unsupported. */ 0076 #endif 0077 } 0078 0079 0080 0081 0082 0083 /** 0084 * Returns the current resident set size (physical memory use) measured 0085 * in bytes, or zero if the value cannot be determined on this OS. 0086 */ 0087 size_t getCurrentRSS( ) 0088 { 0089 #if defined(_WIN32) 0090 /* Windows -------------------------------------------------- */ 0091 PROCESS_MEMORY_COUNTERS info; 0092 GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) ); 0093 return (size_t)info.WorkingSetSize; 0094 0095 #elif defined(__APPLE__) && defined(__MACH__) 0096 /* OSX ------------------------------------------------------ */ 0097 struct mach_task_basic_info info; 0098 mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT; 0099 if ( task_info( mach_task_self( ), MACH_TASK_BASIC_INFO, 0100 (task_info_t)&info, &infoCount ) != KERN_SUCCESS ) 0101 return (size_t)0L; /* Can't access? */ 0102 return (size_t)info.resident_size; 0103 0104 #elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__) 0105 /* Linux ---------------------------------------------------- */ 0106 long rss = 0L; 0107 FILE* fp = nullptr; 0108 if ( (fp = fopen( "/proc/self/statm", "r" )) == nullptr ) 0109 return (size_t)0L; /* Can't open? */ 0110 if ( fscanf( fp, "%*s%ld", &rss ) != 1 ) 0111 { 0112 fclose( fp ); 0113 return (size_t)0L; /* Can't read? */ 0114 } 0115 fclose( fp ); 0116 0117 if ((size_t)rss > std::numeric_limits<size_t>::max()/(size_t)sysconf( _SC_PAGESIZE)) 0118 return std::numeric_limits<size_t>::max(); 0119 else 0120 return (size_t)rss * (size_t)sysconf( _SC_PAGESIZE); 0121 0122 #else 0123 /* AIX, BSD, Solaris, and Unknown OS ------------------------ */ 0124 return (size_t)0L; /* Unsupported. */ 0125 #endif 0126 }