1 /*
2 * Author: David Robert Nadeau
3 * Site: http://NadeauSoftware.com/
4 * License: Creative Commons Attribution 3.0 Unported License
5 * http://creativecommons.org/licenses/by/3.0/deed.en_US
6 * Modified: Holger Vogt, 2019
7 */
8
9 #include "ngspice/ngspice.h"
10 #include "resource.h"
11
12 #if defined(_WIN32)
13 #undef BOOLEAN
14 #include <windows.h>
15 #include <psapi.h>
16
17 #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__))
18 #include <unistd.h>
19 #include <sys/resource.h>
20
21 #if defined(__APPLE__) && defined(__MACH__)
22 #include <mach/mach.h>
23
24 #elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__)))
25 #include <fcntl.h>
26 #include <procfs.h>
27
28 #elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__)
29 #include <stdio.h>
30
31 #endif
32
33 #else
34 #error "Cannot define getPeakRSS( ) or getCurrentRSS( ) for an unknown OS."
35 #endif
36
37
38 /**
39 * Returns the peak (maximum so far) resident set size (physical
40 * memory use) measured in bytes, or zero if the value cannot be
41 * determined on this OS.
42 */
getPeakRSS(void)43 unsigned long long getPeakRSS(void)
44 {
45 #if defined(HAVE__PROC_MEMINFO)
46 /* Linux ---------------------------------------------------- */
47 unsigned long long rss = 0L;
48 FILE* fp = NULL;
49 if ( (fp = fopen( "/proc/self/statm", "r" )) == NULL )
50 return (unsigned long long) 0L; /* Can't open? */
51 if ( fscanf( fp, "%llu", &rss ) != 1 )
52 {
53 fclose( fp );
54 return 0L; /* Can't read? */
55 }
56 fclose( fp );
57 return rss * (unsigned long long) sysconf(_SC_PAGESIZE);
58
59 #elif defined(HAVE_GETRUSAGE)
60 /* BSD, Linux, and OSX --------------------------------------
61 * not (yet) available with CYGWIN */
62 struct rusage rusage;
63 getrusage(RUSAGE_SELF, &rusage);
64 #if defined(__APPLE__) && defined(__MACH__)
65 return (unsigned long long) rusage.ru_maxrss;
66 #else
67 return (unsigned long long) (rusage.ru_maxrss * 1024L);
68 #endif
69
70 #elif defined(_WIN32)
71 /* Windows -------------------------------------------------- */
72 PROCESS_MEMORY_COUNTERS info;
73 GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) );
74 return (unsigned long long) info.PeakWorkingSetSize;
75
76 #elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__)))
77 /* AIX and Solaris ------------------------------------------ */
78 struct psinfo psinfo;
79 int fd = -1;
80 if ( (fd = open( "/proc/self/psinfo", O_RDONLY )) == -1 )
81 return 0L; /* Can't open? */
82 if ( read( fd, &psinfo, sizeof(psinfo) ) != sizeof(psinfo) )
83 {
84 close( fd );
85 return 0L; /* Can't read? */
86 }
87 close( fd );
88 return (unsigned long long) (psinfo.pr_rssize * 1024L);
89
90 #else
91 /* Unknown OS ----------------------------------------------- */
92 return 0L; /* Unsupported. */
93 #endif
94 }
95
96
97
98
99
100 /**
101 * Returns the current resident set size (physical memory use) measured
102 * in bytes, or zero if the value cannot be determined on this OS.
103 */
getCurrentRSS(void)104 unsigned long long getCurrentRSS(void)
105 {
106 #if defined(_WIN32)
107 /* Windows -------------------------------------------------- */
108 PROCESS_MEMORY_COUNTERS info;
109 GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) );
110 return (unsigned long long) info.WorkingSetSize;
111
112 #elif defined(__APPLE__) && defined(__MACH__)
113 /* OSX ------------------------------------------------------ */
114 struct mach_task_basic_info info;
115 mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
116 if ( task_info( mach_task_self( ), MACH_TASK_BASIC_INFO,
117 (task_info_t)&info, &infoCount ) != KERN_SUCCESS )
118 return 0L; /* Can't access? */
119 return (unsigned long long) info.resident_size;
120
121 //#elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__)
122 #elif defined(HAVE__PROC_MEMINFO)
123 /* Linux ---------------------------------------------------- */
124 unsigned long long rss = 0L;
125 FILE* fp = NULL;
126 if ( (fp = fopen( "/proc/self/statm", "r" )) == NULL )
127 return (unsigned long long) 0L; /* Can't open? */
128 if ( fscanf( fp, "%*s%llu", &rss ) != 1 )
129 {
130 fclose( fp );
131 return 0L; /* Can't read? */
132 }
133 fclose( fp );
134 return rss * (unsigned long long) sysconf(_SC_PAGESIZE);
135
136 #else
137 /* AIX, BSD, Solaris, and Unknown OS ------------------------ */
138 return (unsigned long long) 0L; /* Unsupported. */
139 #endif
140 }
141