Пример #1
0
void procinfo_show(PROC_MAP& pm) {
    PROCINFO pi;
    pi.clear();
    PROC_MAP::iterator i;
    for (i=pm.begin(); i!=pm.end(); ++i) {
        PROCINFO& p = i->second;

        msg_printf(NULL, MSG_INFO, "%d %s: boinc? %d low_pri %d (u%f k%f)",
            p.id, p.command, p.is_boinc_app, p.is_low_priority,
            p.user_time, p.kernel_time
        );
#ifdef _WIN32
        if (p.id == 0) continue;
#endif
        if (p.is_boinc_app) continue;
        if (p.is_low_priority) continue;
        pi.kernel_time += p.kernel_time;
        pi.user_time += p.user_time;
    }
    msg_printf(NULL, MSG_INFO, "non-boinc: u%f k%f", pi.user_time, pi.kernel_time);
}
Пример #2
0
// get resource usage of non-BOINC apps
//
void procinfo_non_boinc(PROCINFO& pi, PROC_MAP& pm) {
    pi.clear();
    PROC_MAP::iterator i;
    for (i=pm.begin(); i!=pm.end(); i++) {
        PROCINFO& p = i->second;
#ifdef _WIN32
        if (p.id == 0) continue;    // idle process
#endif
        if (p.is_boinc_app) continue;
        if (p.is_low_priority) continue;

        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;
    }
}
Пример #3
0
// build table of all processes in system
//
int procinfo_setup(PROC_MAP& pm) {
    DIR *dir;
    dirent *piddir;
    FILE* fd;
    PROC_STAT ps;
    char pidpath[MAXPATHLEN];
    char buf[1024];
    int pid = getpid();
    int retval;

    dir = opendir("/proc");
    if (!dir) {
        fprintf(stderr, "procinfo_setup(): can't open /proc\n");
        return 0;
    }

    while (1) {
        piddir = readdir(dir);
        if (!piddir) break;
        if (!isdigit(piddir->d_name[0])) continue;

#if defined(HAVE_PROCFS_H) && defined(HAVE__PROC_SELF_PSINFO)  // solaris
        psinfo_t psinfo;
        sprintf(pidpath, "/proc/%s/psinfo", piddir->d_name);
        fd = fopen(pidpath, "r");
        if (!fd) continue;
        PROCINFO p;
        p.clear();
        if (fread(&psinfo, sizeof(psinfo_t), 1, fd) == 1) {
            p.id = psinfo.pr_pid;
            p.parentid = psinfo.pr_ppid;
            p.swap_size = psinfo.pr_size*1024.;
            p.working_set_size = psinfo.pr_rssize * 1024.;
            strlcpy(p.command, psinfo.pr_fname, sizeof(p.command));
        }
        fclose(fd);
        sprintf(pidpath, "/proc/%s/usage", piddir->d_name);
        prusage_t prusage;
        fd = fopen(pidpath, "r");
        if (!fd) continue;
        if (fread(&prusage, sizeof(prusage_t), 1, fd) == 1) {
            p.user_time = (float)prusage.pr_utime.tv_sec +
                ((float)prusage.pr_utime.tv_nsec)/1e+9;
            p.kernel_time = (float)prusage.pr_stime.tv_sec +
                ((float)prusage.pr_utime.tv_nsec)/1e+9;
            // page faults: I/O + non I/O
            p.page_fault_count = prusage.pr_majf + prusage.pr_minf;
        }
        fclose(fd);
        p.is_boinc_app = (p.id == pid || strcasestr(p.command, "boinc"));
        pm.insert(std::pair(p.id, p));
#else  // linux
        sprintf(pidpath, "/proc/%s/stat", piddir->d_name);
        fd = fopen(pidpath, "r");
        if (!fd) continue;
        if (fgets(buf, sizeof(buf), fd) == NULL) {
            retval = ERR_NULL;
        } else {
            retval = ps.parse(buf);
        }
        fclose(fd);

        if (retval) {
            // ps.parse() returns an error if the executable name contains ).
            // In that case skip this process.
            //
            continue;
        }
        PROCINFO p;
        p.clear();
        p.id = ps.pid;
        p.parentid = ps.ppid;
        p.swap_size = ps.vsize;
        // rss = pages, need bytes
        // assumes page size = 4k
        p.working_set_size = ps.rss * (float)getpagesize();
        // page faults: I/O + non I/O
        p.page_fault_count = ps.majflt + ps.minflt;
        // times are in jiffies, need seconds
        // assumes 100 jiffies per second
        p.user_time = ps.utime / 100.;
        p.kernel_time = ps.stime / 100.;
        strlcpy(p.command, ps.comm, sizeof(p.command));
        p.is_boinc_app = (p.id == pid || strcasestr(p.command, "boinc"));
        p.is_low_priority = (ps.priority == 39);
            // Internally Linux stores the process priority as nice + 20
            // as -ve values are error codes. Thus this generally gives
            // a process priority range of 39..0
        pm.insert(std::pair<int, PROCINFO>(p.id, p));
#endif
    }
    closedir(dir);
    find_children(pm);
    return 0;
}
Пример #4
0
// build table of all processes in system
//
int procinfo_setup(PROC_MAP& pm) {
    int pid = getpid();
    FILE* fd;
    PROCINFO p;
    int c, real_mem, virtual_mem, hours;
    char* lf;
    static long iBrandID = -1;
    int priority;
    
    if (iBrandID < 0) {
        iBrandID = BOINC_BRAND_ID;

        // For GridRepublic or ProgressThruProcessors, the Mac 
        // installer put a branding file in our data directory
        FILE *f = fopen("/Library/Application Support/BOINC Data/Branding", "r");
        if (f) {
            fscanf(f, "BrandId=%ld\n", &iBrandID);
            fclose(f);
        }
    }

#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
// pri        scheduling priority
// 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.  
//
// 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,pri,time,command", "r");
    if (!fd) return ERR_FOPEN;

    // Skip over the header line
    do {
        c = fgetc(fd);
        if (c == EOF) {
            pclose(fd);
            return ERR_GETS;
        }
    } while (c != '\n');

    while (1) {
        p.clear();
        c = fscanf(fd, "%d%d%d%d%lu%d%d:%lf ",
            &p.id,
            &p.parentid,
            &real_mem, 
            &virtual_mem,
            &p.page_fault_count,
            &priority,
            &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"));
        p.is_low_priority = (priority <= 12);

        switch (iBrandID) {
        case GRIDREPUBLIC_BRAND_ID:
            if (!strcasestr(p.command, "GridRepublic")) {
                p.is_boinc_app = true;
            }
            break;
        case PROGRESSTHRUPROCESSORS_BRAND_ID:
            if (!strcasestr(p.command, "Progress Thru Processors")) {
                p.is_boinc_app = true;
            }
            break;
        case CHARITYENGINE_BRAND_ID:
            if (!strcasestr(p.command, "Charity Engine")) {
                p.is_boinc_app = true;
            }
            break;
        }
        pm.insert(std::pair<int, PROCINFO>(p.id, 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
    
    find_children(pm);
    return 0;
}
Пример #5
0
// Note: the following will work on both NT and XP,
// because the NT process structure differs only at the end
//
int get_procinfo_XP(PROC_MAP& pm) {
    ULONG                   cbBuffer = 128*1024;    // 128k initial buffer
    PVOID                   pBuffer = NULL;
    PSYSTEM_PROCESSES       pProcesses = NULL;
    static DWORD            pid = 0;

    if (!pid) {
        pid = GetCurrentProcessId();
    }
#if 0
    printf("FILETIME: %d\n", sizeof(FILETIME));
    printf("LARGE_INTEGER: %d\n", sizeof(LARGE_INTEGER));
    printf("DWORD: %d\n", sizeof(DWORD));
    printf("UNICODE_STRING: %d\n", sizeof(UNICODE_STRING));
    printf("KPRIORITY: %d\n", sizeof(KPRIORITY));
    printf("ULONG: %d\n", sizeof(ULONG));
    printf("SIZE_T: %d\n", sizeof(SIZE_T));
#endif

    get_process_information(&pBuffer, &cbBuffer);
    pProcesses = (PSYSTEM_PROCESSES)pBuffer;
    while (pProcesses) {
        PROCINFO p;
        p.clear();
        p.id = pProcesses->ProcessId;
        p.parentid = pProcesses->InheritedFromProcessId;
        p.swap_size = pProcesses->VmCounters.PagefileUsage;
        p.working_set_size = pProcesses->VmCounters.WorkingSetSize;
        p.page_fault_count = pProcesses->VmCounters.PageFaultCount;
        p.user_time = ((double) pProcesses->UserTime.QuadPart)/1e7;
        p.kernel_time = ((double) pProcesses->KernelTime.QuadPart)/1e7;
        p.id = pProcesses->ProcessId;
        p.parentid = pProcesses->InheritedFromProcessId;
        p.is_low_priority = (pProcesses->BasePriority <= 4);
        WideCharToMultiByte(CP_ACP, 0,
            pProcesses->ProcessName.Buffer,
            pProcesses->ProcessName.Length,
            p.command,
            sizeof(p.command),
            NULL, NULL
        );
        p.is_boinc_app = (p.id == (int)pid) || (strcasestr(p.command, "boinc") != NULL);
        
#ifdef _GRIDREPUBLIC
        if (!strcmp(p.command, "gridrepublic.exe")) {
            p.is_boinc_app = true;
        }
#endif        
#ifdef _PROGRESSTHRUPROCESSORS
        if (!strcmp(p.command, "progressthruprocessors.exe")) {
            p.is_boinc_app = true;
        }
#endif        
        pm.insert(std::pair<int, PROCINFO>(p.id, p));
        if (!pProcesses->NextEntryDelta) {
            break;
        }
        pProcesses = (PSYSTEM_PROCESSES)(((LPBYTE)pProcesses) + pProcesses->NextEntryDelta);
    }

    if (pBuffer) HeapFree(GetProcessHeap(), NULL, pBuffer);
    find_children(pm);
    return 0;
}
Пример #6
0
// build table of all processes in system
//
int procinfo_setup(PROC_MAP& pm) {

#if HAVE_DIRENT_H
    DIR *dir;
    dirent *piddir;
    FILE* fd;
    PROC_STAT ps;
    PROCINFO p;
    char pidpath[MAXPATHLEN];
    char buf[1024];
    int pid = getpid();
    int retval, final_retval = 0;

    dir = opendir("/proc");
    if (!dir) return 0;

    while (1) {
        piddir = readdir(dir);
        if (!piddir) break;
        if (!isdigit(piddir->d_name[0])) continue;

#if defined(HAVE_PROCFS_H) && defined(HAVE__PROC_SELF_PSINFO)  // solaris
        psinfo_t psinfo;
        sprintf(pidpath, "/proc/%s/psinfo", piddir->d_name);
        fd = fopen(pidpath, "r");
        if (fd) {
            p.clear();
            if (fread(&psinfo, sizeof(psinfo_t), 1, fd) == 1) {
                p.id = psinfo.pr_pid;
                p.parentid = psinfo.pr_ppid;
                p.swap_size = psinfo.pr_size*1024.;
                p.working_set_size = psinfo.pr_rssize * 1024.;
                strlcpy(p.command, psinfo.pr_fname, sizeof(p.command));
            }
            fclose(fd);
            sprintf(pidpath, "/proc/%s/usage", piddir->d_name);
            prusage_t prusage;
            fd = fopen(pidpath, "r");
            if (fd) {
                if (fread(&prusage, sizeof(prusage_t), 1, fd) == 1) {
                    p.user_time = (float)prusage.pr_utime.tv_sec +
                        ((float)prusage.pr_utime.tv_nsec)/1e+9;
                    p.kernel_time = (float)prusage.pr_stime.tv_sec +
                        ((float)prusage.pr_utime.tv_nsec)/1e+9;
                    // page faults: I/O + non I/O
                    p.page_fault_count = prusage.pr_majf + prusage.pr_minf;
                }
                fclose(fd);
                p.is_boinc_app = (p.id == pid || strcasestr(p.command, "boinc"));
                pm.insert(std::pair(p.id, p));
            }
        }
#else  // linux
        sprintf(pidpath, "/proc/%s/stat", piddir->d_name);
        fd = fopen(pidpath, "r");
        if (fd) {
            fgets(buf, sizeof(buf), fd);
            retval = ps.parse(buf);
            fclose(fd);

            if (retval) {
                final_retval = retval;
            } else {
                p.clear();
                p.id = ps.pid;
                p.parentid = ps.ppid;
                p.swap_size = ps.vsize;
                // rss = pages, need bytes
                // assumes page size = 4k
                p.working_set_size = ps.rss * (float)getpagesize();
                // page faults: I/O + non I/O
                p.page_fault_count = ps.majflt + ps.minflt;
                // times are in jiffies, need seconds
                // assumes 100 jiffies per second
                p.user_time = ps.utime / 100.;
                p.kernel_time = ps.stime / 100.;
                strlcpy(p.command, ps.comm, sizeof(p.command));
                p.is_boinc_app = (p.id == pid || strcasestr(p.command, "boinc"));
                p.is_low_priority = (ps.priority == 39);
                    // Linux seems to add 20 here,
                    // but this isn't documented anywhere
                pm.insert(std::pair<int, PROCINFO>(p.id, p));
            }
        }
#endif
    }
    closedir(dir);
#endif
    find_children(pm);
    return final_retval;

}