25 #ifndef CASA_HOSTINFOLINUX_H
26 #define CASA_HOSTINFOLINUX_H
28 # if defined(HOSTINFO_DO_IMPLEMENT)
45 #include <sys/types.h>
59 #include <sys/resource.h>
83 #include <linux/proc_fs.h>
85 #define PROC_SUPER_MAGIC 0x9fa0
88 #define PROCFS "/proc"
89 #define CPUINFO "/proc/cpuinfo"
90 #define MEMINFO "/proc/meminfo"
92 #define bytetok(x) (((x) + 512) >> 10)
96 class HostMachineInfo {
97 friend class HostInfo;
105 ptrdiff_t memory_total;
106 ptrdiff_t memory_used;
107 ptrdiff_t memory_free;
109 ptrdiff_t swap_total;
118 skip_ws(
const char *p)
120 while (isspace(*p)) p++;
125 skip_token(
const char *p)
127 while (isspace(*p)) p++;
128 while (*p && !isspace(*p)) p++;
139 get_cgroup_limit(std::string group, std::string
value, std::string sub_value=
"")
143 const std::string cgroup = std::string(
"/sys/fs/cgroup/") + group +
"/";
147 std::ifstream ifs(
"/proc/self/cgroup", std::ifstream::in);
148 std::string hierarchy;
149 while (getline(ifs, line)) {
150 std::stringstream ss(line);
152 std::vector<std::string> fields;
153 while (getline(ss, token,
':')) {
154 fields.push_back(token);
156 if (fields.size() % 3 != 0) {
159 for (std::vector<std::string>::size_type i=1; i < fields.size(); i+=3) {
160 if (fields[i].find(group) != std::string::npos) {
161 hierarchy = fields[i + 1] +
"/";
165 if (hierarchy.size() == 0) {
169 std::ifstream flimit((cgroup + hierarchy + value).c_str(), std::ifstream::in);
171 if (!flimit.is_open()) {
172 flimit.open((cgroup + value).c_str(), std::ifstream::in);
174 if (flimit.is_open()) {
175 if (!sub_value.empty()) {
177 while (getline(flimit, line)) {
178 std::stringstream ss(line);
181 if (token == sub_value) {
194 HostMachineInfo::HostMachineInfo( ) : valid(1)
201 if (sched_getaffinity(0,
sizeof(cpuset), &cpuset) == 0) {
203 cpus = CPU_COUNT(&cpuset);
205 for (
int i = 0; i < CPU_SETSIZE; i++) {
206 if (CPU_ISSET(i, &cpuset)) {
213 #ifndef AIPS_CRAY_PGI
217 if (statfs(PROCFS, &sb) < 0 || sb.f_type != PROC_SUPER_MAGIC)
219 fprintf( stderr,
"proc filesystem not mounted on " PROCFS
"\n" );
229 FILE *fptr = fopen(CPUINFO,
"r");
230 while ( (p = fgets( buffer,
sizeof(buffer), fptr )) ) {
231 if ( ! strncmp( p,
"processor", 9 ) ) ++cpus;
240 void HostMachineInfo::update_info( )
248 unsigned long sys_mem_total, sys_mem_free, sys_mem_cached,
249 sys_mem_avail, sys_swap_total, sys_swap_free;
251 fd = open(MEMINFO, O_RDONLY);
252 len = ::read(fd, buffer,
sizeof(buffer)-1);
256 p = strstr(buffer,
"MemTotal:");
258 if (sscanf (p,
"MemTotal: %lu kB\nMemFree: %lu kB\n",
259 &sys_mem_total, &sys_mem_free) != 2)
260 cerr <<
"Error parsing MemTotal and MemFree in /proc/meminfo\n";
262 p = strstr (buffer,
"Cached:");
263 if (sscanf (p,
"Cached: %lu kB\n", &sys_mem_cached) != 1)
264 cerr <<
"Error parsing Cached in /proc/meminfo\n";
268 p = strstr (buffer,
"MemAvailable:");
269 if (!p || sscanf (p,
"MemAvailable: %lu kB\n", &sys_mem_avail) != 1) {
271 sys_mem_avail = sys_mem_cached + sys_mem_free;
276 if (getrlimit(RLIMIT_RSS, &rlim) == 0 && rlim.rlim_cur > 0) {
277 sys_mem_total =
std::min(rlim.rlim_cur / 1024, (rlim_t)sys_mem_total);
279 sys_mem_avail =
std::min(sys_mem_total, sys_mem_avail);
283 uInt64 proc_mem_max = get_cgroup_limit(
"memory",
"memory.limit_in_bytes") / 1024;
285 uInt64 proc_mem_used = get_cgroup_limit(
"memory",
"memory.stat",
"total_rss") / 1024;
291 if (proc_mem_max <= sys_mem_total && proc_mem_used <= proc_mem_max) {
292 memory_free = proc_mem_max - proc_mem_used;
298 memory_used = memory_total - memory_free;
300 p = strstr (buffer,
"SwapTotal:");
301 if (sscanf (p,
"SwapTotal: %lu kB\nSwapFree: %lu kB\n",
302 &sys_swap_total, &sys_swap_free) != 2)
303 cerr <<
"Error parsing SwapTotal and SwapFree in /proc/meminfo\n";
306 uInt64 proc_swap_max = get_cgroup_limit(
"memory",
"memory.memsw.limit_in_bytes") / 1024;
307 uInt64 proc_swap_used = get_cgroup_limit(
"memory",
"memory.stat",
"total_swap") / 1024;
309 if (proc_mem_max <= sys_mem_total && proc_mem_max <= proc_swap_max) {
310 proc_swap_max = proc_swap_max - proc_mem_max;
316 if (proc_swap_max <= (
uInt64)swap_total && proc_swap_used <= proc_swap_max) {
317 swap_free = proc_swap_max - proc_swap_used;
320 swap_free = sys_swap_free;
322 swap_used = swap_total - swap_free;
LatticeExprNode max(const LatticeExprNode &left, const LatticeExprNode &right)
unsigned long long uInt64
LatticeExprNode min(const LatticeExprNode &left, const LatticeExprNode &right)
LatticeExprNode value(const LatticeExprNode &expr)
This function returns the value of the expression without a mask.