Skip to content
Snippets Groups Projects
Select Git revision
  • dddeba4c779a46f52dfc67a7a86c96c2795a98a2
  • master default protected
  • fix_Makefile.mingw#2
  • update_Makefile.mingw
  • fix_Makefile.mingw
  • fix_API_for_C_apps
  • fix_procinfo_mac
  • boinccmd_gpu_mode_always_until_sigterm
  • fgrp_osx_hotfix
  • fix_boinc_master@f8250782
  • eah_wrapper_improvements
  • diagnostics_win-hotfix
  • diagnostics_win-hotfix-old
  • current_fgrp_apps
  • testing_gw_apps
  • gw_app_darwin_15
  • current_brp_apps
  • current_brp_apps_android10
  • current_gfx_apps
  • current_server
  • current_gw_apps
  • previous_fgrp_apps
  • previous_gw_apps
  • testing_brp_apps
  • apps_FGRP3_1.07
  • apps_FGRP3_1.08
26 results

boinc_api_fortran.C

Blame
  • procinfo_mac.cpp 5.71 KiB
    // 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 <http://www.gnu.org/licenses/>.
    
    #define SHOW_TIMING 0
    
    #include "config.h"
    #include <cstdio>
    
    #include <ctype.h>
    #include <sys/types.h>
    #include <dirent.h>
    
    #if SHOW_TIMING
    #include <Carbon/Carbon.h>
    #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<PROCINFO>& pi) {
        int pid = getpid();
        FILE* fd;
        PROCINFO p;
        int c, real_mem, virtual_mem, hours;
        char* lf;
    
    #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)
    // command    command (executable name)
    // 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
    // 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 -axcopid,ppid,rss,vsz,pagein,time,command", "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 ", &p.id, &p.parentid, &real_mem, 
                        &virtual_mem, &p.page_fault_count, &hours, &p.user_time);
            if (c < 7) break;
            if (fgets(p.command, sizeof(p.command) , fd) == NULL) break;
            lf = strchr(p.command, '\n');
            if (lf) *lf = '\0';         // Strip trailing linefeed
            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 = (p.id == pid || strcasestr(p.command, "boinc"));
            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<PROCINFO>& piv, int pid, int rlvl) {
        unsigned int i;
    
        if (rlvl > 3) {
            return;
        }
        for (i=0; i<piv.size(); i++) {
            PROCINFO& p = piv[i];
            if (p.parentid == pid) {
    //            pi.kernel_time += p.kernel_time;
                pi.user_time += p.user_time;
                pi.swap_size += p.swap_size;
                pi.working_set_size += p.working_set_size;
                p.is_boinc_app = true;
                // look for child process of this one
                add_child_totals(pi, piv, p.id, rlvl+1); // recursion - woo hoo!
            }
        }
    }
    
    // fill in the given PROCINFO (which initially is zero except for id)
    // with totals from that process and all its descendants
    //
    void procinfo_app(PROCINFO& pi, vector<PROCINFO>& piv) {
        unsigned int i;
    
        for (i=0; i<piv.size(); i++) {
            PROCINFO& p = piv[i];
            if (p.id == pi.id) {
    //            pi.kernel_time += p.kernel_time;
                pi.user_time += p.user_time;
                pi.swap_size += p.swap_size;
                pi.working_set_size += p.working_set_size;
                p.is_boinc_app = true;
                // look for child processes
     	    add_child_totals(pi, piv, pi.id, 0);
                return;
            }
        }
    }
    
    void procinfo_other(PROCINFO& pi, vector<PROCINFO>& piv) {
        unsigned int i;
    
        memset(&pi, 0, sizeof(pi));
        for (i=0; i<piv.size(); i++) {
            PROCINFO& p = piv[i];
            if (!p.is_boinc_app) {
    //            pi.kernel_time += p.kernel_time;
                pi.user_time += p.user_time;
                pi.swap_size += p.swap_size;
                pi.working_set_size += p.working_set_size;
                p.is_boinc_app = true;
            }
        }
    }