Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Computation of Cpu percentage by a single process in unix by the "top" command

Tags:

c++

c

unix

solaris

I would like to know how does the "top" command compute the cpu percentage used by any process.

I have tried reading the "psinfo" binary file in the /proc directory , but it didnt help in finding the result.

Please provide any information how it can be done.

Thanks in advance.

like image 530
Arunmu Avatar asked Dec 15 '10 14:12

Arunmu


1 Answers

The top command computes the CPU usage using the data in the proc file system. The actual file containing the CPU usage data can vary from one platform to another. For example, in Linux it is found in /proc/<pid>/stat and for Solaris it is found in /proc/<pid>/psinfo. The CPU usage is calculated as the difference in cumulative CPU time for a process divided by the amount of time measured between updates.


For Linux, you can inspect the procps source which includes ps, top, and other process tool from http://procps.sourceforge.net. The readproc.c file in particular contains the functionality for retrieving the data.


For Solaris, you can inspect the libproc source from https://hg.java.net/hg/solaris~on-src/file/tip/usr/src/lib/libproc. The prog_get_info.c file contains the functionality for retrieving the data and storing it in a psinfo_t struct.


For Linux, Solaris, and others, you can inspect the Unix Top source from http://sourceforge.net/projects/unixtop. The platform-specific source files within the machine directory contain the functionality for retrieving the data.


Update

Another option (Solaris only) for retrieving CPU time for a process may be passing to the PIOCPSINFO or PIOCSTATUS option to the ioctl() system call. The PIOCPSINFO option returns miscellaneous process information in a prpsinfo_t struct. The PIOCSTATUS option returns status information for the process in a prstatus_t struct.

Adapted from example code at http://getthegood.com/TechNotes/Papers/ProcStatistics.html:

int main(int argc, char* argv[])
{
    int fd;
    prpsinfo_t info;
    prstatus_t status;
    char procbuf[50];

    sprintf(procbuf, "/proc/%d", getpid());
    fd = open(procbuf, O_RDONLY);

    ioctl(fd, PIOCPSINFO, &info);
    printf("Process user+sys time = %ld sec %ld nsec\n" 
           "Reaped children user+sys time = %ld sec %ld nsec\n",
           info.pr_time.tv_sec, info.pr_time.tv_nsec,
           info.pr_ctime.tv_sec, info.pr_ctime.tv_nsec);

    ioctl(fd, PIOCSTATUS, &status);
    printf("Process user+sys time = %ld sec %ld nsec\n"
           "Sum of children's user+sys time = %ld sec %ld nsec\n",
           status.pr_utime.tv_sec+status.pr_stime.tv_sec,  
           status.pr_utime.tv_nsec+status.pr_stime.tv_nsec,  
           status.pr_cutime.tv_sec+status.pr_cstime.tv_sec,
           status.pr_cutime.tv_nsec+status.pr_cstime.tv_nsec);

    close(fd);
    exit(0);
}

Note: This code is untested and omits error checking for simplicity.

like image 79
jschmier Avatar answered Sep 28 '22 07:09

jschmier