CS 4420/5420 Programming Assignment 1 Exploring the Proc Filesystem  Part III: The “4420_proctool_ps” Tool solution


Original Work ?


5/5 - (3 votes)


In the third part of assignment 1, you will implement the tool “4420_proctool_ps”. This tool is a reimplementation of the Unix tool “ps” which lists statistics for all the processes in the system. More specifically, the “4420_proctools_ps” tool should produce (a subset of) all the information a call to “ps aux” would produce.

The tool has one required command argument and has the following syntax: Shell> 4420_proctool_ps [-cpu|-mem|-pid|-com] The tool will produce statistical information about all the process in the system. Specifically, it should produce a table containing the following columns: PID (u_int) Command (string) State (char) %CPU (float) %MEM (float) VSZ(virtual memory size) (u_long; in bytes) RSS (resident set size) (u_long; in bytes) In order to calculate the values in the different columns, you will need to access two different proc files: • “/proc//stat” • “/proc/uptime Note that the difference between these two proc file locations is that each process has its own “/proc//stat” file, while the system as a whole has only one “/proc/uptime” file.

Also note that the contents in these files constantly change. In other words, if you read the contents twice, at different points in time, they will reflect the differences in the system between those two time points. An important resource for you to understand the structure in both files is again the Linux man page for proc (see Part I). It describes the format of both files in detail. Most of the data needed in the different columns above can be directly read from “/proc//stat”.

Specifically, you can read the “PID”, the “Command” string (note that commands are stored in parentheses, the “State”, the virtual memory size “VSZ”, and the resident set size “RSS”. It turns out that the “%CPU” and “%MEM” field require a little bit extra work. Let’s start with the “%MEM” field. Since we’re basically re-implementing the Unix “ps” command, we can look at the definition of “%MEM” This field is defined as (see “man proc”) “ratio of the process’s resident set size to the physical memory on the machine, expressed as a percentage”.

Since we already know the (RSS) resident set size (see above), all we need to calculate “%MEM” is the availability of physical memory in the machine. There are different ways of doing it, but I suggest you use the “sysconf()” function. This works as follows: long phys_pages = sysconf(_SC_PHYS_PAGES); long page_size = sysconf(_SC_PAGE_SIZE); long phys_mem_size = phys_pages * page_size; Next, the RSS is specified in units of numbers of “pages”. A “page” is a fixed size, basic management unit in memory management.

Different CPUs may use different page sizes. In order to calculate the actual physical memory footprint of a process in bytes, the value of RSS (as read from “/proc//stat”, needs to be multiplied with the (constant) value of the page size. This value can be obtained using the function “getpagesize()” (see man getpagesize) or using “sysconf()” again (as shown above).

Now you can calculate the “%MEM” for each process by using the following equation: ( RSS * getpagesize() * 100 ) / phys_mem_size The “%CPU” is a little bit more complicated. First note that the Unix commands “ps” and “top” use different ways of calculating “%CPU”. In fact, “top” uses a more precise way of calculating this statistic. Since we re-implement “ps” though, we will use its method. You should be able to verify the correctness of your implementation by comparing your calculations to the ones done by the “ps” tool.

Note that its method is not very accurate. For example, it is possible (under certain circumstances) to obtain a %CPU value for a process that exceeds 100%! The Unix tool “ps” defines %CPU (see man ps) as “cpu utilization of the process in “##.#” format. Currently it is the CPU time used divided by the time the process has been running (cputime/realtime ratio), expressed as percentage. It will not add up to 100% unless you are lucky” Here is how this value can be calculated.

First extract the two fields “utime” and “stime” from “/proc//stat” (see man -s5 proc). These two field represent the amount of time that a process has been scheduled in user mode (“utime”) and in kernel mode (“stime”), measured in clock ticks. In order to translate these values to seconds, you will need to divide them by system clock speed in HZ (divide by “sysconf(_SC_CLK_TCK)”). In other words, process_time = ( “utime” / sysconf(_SC_CLK_TCK) ) + ( “stime” / sysconf(_SC_ClK_TCK) ) is the total amount of time (in seconds) that a process has received.

Next, you will need to determine the time a process started after (i.e. relative to) system boot. This value, “starttime” is also contained in the file “/proc//stat”. Now you will need the total system “uptime”, which represents the total amount of “useful” time the CPU has spent since boot. This value is stored in a per-system “/proc/uptime” (see man proc). This file contains two numbers. The one you need is the first one. Note that this time is already given in units of seconds (not clock ticks; you therefore don’t need to divide this value). Now, you finally can calculate a process’s %CPU using the following formula: real_time = “uptime” – ( “starttime” / sysconf(_SC_CLK_TCK) ) “%CPU” = real_time = process_time * 100 / real_time

Specific Requirements:

• Implement the above described tool “4420_proctools_ps”. The tool has one required argument which is the sort order in which the process’s entries in the table (columns as described above) are sorted. The following sort orders should be supported: o 4420_proctools_ps -cpu sort the rows based on “%CPU” (from highest to lowest) o 4420_proctools_ps -mem sort the rows based on ”%MEM” (from highest to lowest) o 4420_proctools_ps -pid sort the rows based on “PID” (from lowest to highest) o 4420_proctools_ps -com sort the rows lexicographically by command name • You have to implement the tool either in C or C++.

You need to use the proc filesystem (as explained above) for this project. Do not use any other functions (example: system(), getrusage(), etc.) • Calling “4420_proctools_ps” witch an invalid argument (or without required argument) should create some error message • I put a reference implementation of “4420_proctools_ps” in my home directory on the prime machines.

You can access it in the folder “/home/drews/proctools”. • The screenshot above shows a sample output of my reference tool. • You will need to submit the source file(s), header files (if necessary), and you WILL NEED TO SUBMIT A MAKEFILE. I will grade the project on “pu2.cs.ohio.edu”. I will type “make” to build the executable tool (which, again, should be called “4420_proctools_ps”). If “make” fails (due to an error), the GRADE FOR THE PROJECT WILL BE AN “F”! • You will need to submit the program from “p2.cs.ohio.edu” (NOTE: THIS IS IMPORTANT.

THE SUBMISSION WILL NOT WORK FROM ANY OTHER (LAB)MACHINE OR SERVER!). The submission is simple: “cd” into your project folder and type the following command (exactly as is shown here): “bash> /home/drews/bin/442submit 3”. Should you need to re-submit your project (due to changes), you will need to add an override switch “-f” to the submission: “bash> /home/drews/bin/442submit -f 3”. Deadline: The project is due by 10/3/2018 (11.59pm). I will not accept any late submissions. Additional Help and Resources: You can use similar functions as in Parts I and II.