File indexing completed on 2024-05-12 05:26:23

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