// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2008 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// BOINC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with BOINC. If not, see .
#define SHOW_TIMING 0
#include "config.h"
#include
#include
#include
#include
#if SHOW_TIMING
#include
#endif
#include "procinfo.h"
#include "client_msgs.h"
#include "client_state.h"
using std::vector;
// build table of all processes in system
//
int procinfo_setup(vector& pi) {
FILE* fd;
PROCINFO p;
int c, real_mem, virtual_mem, hours;
#if SHOW_TIMING
UnsignedWide start, end, elapsed;
start = UpTime();
#endif
// Some values of possible interest available from 'ps' command:
// %cpu percentage cpu usage (alias pcpu)
// %mem percentage memory usage (alias pmem)
// majflt total page faults
// minflt total page reclaims
// nswap total swaps in/out
// pagein pageins (same as majflt)
// pid process ID
// ppid parent process ID
// poip pageouts in progress
// rss resident set size in Kbytes
// rsz resident set size + (text size / text use count)
// time accumulated cpu time, user + system
// vsz virtual size in Kbytes
//
// Unfortunately, the selectors majflt, minflt, pagein do not work on OS X,
// and ps does not return kernel time separately from user time.
//
// This code doesn't use PROCINFO.is_boinc_app, but we set it to be
// consistent with the code for other platforms.
//
// Earlier versions of procinf_mac.C launched a small helper application
// AppStats using a bi-directional pipe. AppStats used mach ports to get
// all the information, including page fault counts, kernel and user times.
// In order to use mach ports, AppStats must run setuid root.
//
// But these three items are not actually used (page fault counts aren't
// available from Windows either) so we have reverted to using the ps
// utility, even though it takes more cpu time than AppStats did.
// This eliminates the need to install our own application which runs setuid
// root; this was perceived by some users as a security risk.
fd = popen("ps -axopid,ppid,rsz,vsz,pagein,time", "r");
if (!fd) return 0;
// Skip over the header line
do {
c = fgetc(fd);
if (c == EOF) {
pclose(fd);
return 0;
}
} while (c != '\n');
while (1) {
memset(&p, 0, sizeof(p));
c = fscanf(fd, "%d%d%d%d%ld%d:%lf\n", &p.id, &p.parentid, &real_mem, &virtual_mem, &p.page_fault_count, &hours, &p.user_time);
if (c < 7) break;
p.working_set_size = (double)real_mem * 1024.;
p.swap_size = (double)virtual_mem * 1024.;
p.user_time += 60. * (float)hours;
p.is_boinc_app = false;
pi.push_back(p);
}
pclose(fd);
#if SHOW_TIMING
end = UpTime();
elapsed = AbsoluteToNanoseconds(SubAbsoluteFromAbsolute(end, start));
msg_printf(NULL, MSG_INFO, "elapsed time = %llu, m_swap = %lf\n", elapsed, gstate.host_info.m_swap);
#endif
return 0;
}
// Scan the process table adding in CPU time and mem usage. Loop
// thru entire table as the entries aren't in order. Recurse at
// most 4 times to get additional child processes
//
void add_child_totals(PROCINFO& pi, vector& piv, int pid, int rlvl) {
unsigned int i;
if (rlvl > 3) {
return;
}
for (i=0; i& piv) {
unsigned int i;
for (i=0; i& piv) {
unsigned int i;
memset(&pi, 0, sizeof(pi));
for (i=0; i