0

For a school project I need to reprogram ps aux command in C (Like the picture below):

USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.0  0.0 168028 12052 ?        Ss   06:20   0:07 /sbin/init splash
root           2  0.0  0.0      0     0 ?        S    06:20   0:00 [kthreadd]
root           3  0.0  0.0      0     0 ?        I<   06:20   0:00 [rcu_gp]
root           4  0.0  0.0      0     0 ?        I<   06:20   0:00 [rcu_par_gp]
root           6  0.0  0.0      0     0 ?        I<   06:20   0:00 [kworker/0:0H-kblockd]
root           9  0.0  0.0      0     0 ?        I<   06:20   0:00 [mm_percpu_wq]
root          10  0.0  0.0      0     0 ?        S    06:20   0:00 [ksoftirqd/0]
root          11  0.0  0.0      0     0 ?        I    06:20   0:03 [rcu_sched]
root          12  0.0  0.0      0     0 ?        S    06:20   0:00 [migration/0]
root          13  0.0  0.0      0     0 ?        S    06:20   0:00 [idle_inject/0]
root          14  0.0  0.0      0     0 ?        S    06:20   0:00 [cpuhp/0]
root          15  0.0  0.0      0     0 ?        S    06:20   0:00 [cpuhp/1]
root          16  0.0  0.0      0     0 ?        S    06:20   0:00 [idle_inject/1]
root          17  0.0  0.0      0     0 ?        S    06:20   0:00 [migration/1]
root          18  0.0  0.0      0     0 ?        S    06:20   0:00 [ksoftirqd/1]
root          20  0.0  0.0      0     0 ?        I<   06:20   0:00 [kworker/1:0H-kblockd]
root          21  0.0  0.0      0     0 ?        S    06:20   0:00 [cpuhp/2]
root          22  0.0  0.0      0     0 ?        S    06:20   0:00 [idle_inject/2]
root          23  0.0  0.0      0     0 ?        S    06:20   0:00 [migration/2]
root          24  0.0  0.0      0     0 ?        S    06:20   0:00 [ksoftirqd/2]

I managed to reprogram all the column except %CPU and %MEM. Like the other one, I know my answer is in /proc//[stat|status] but I didn't know what values I need to take and what is the formula to calculate the percentage.

Any idea ?

Rachid K.
  • 4,490
  • 3
  • 11
  • 30
remstation
  • 11
  • 2
  • 2
    Please do not post images of text - [reasoning](https://meta.stackoverflow.com/questions/285551/why-not-upload-images-of-code-on-so-when-asking-a-question). Copy it as formatted text into the question. – kaylum Nov 20 '20 at 23:57
  • You want [How to get overall CPU usage (e.g. 57%) on Linux](https://stackoverflow.com/q/9229333/3422102) – David C. Rankin Nov 21 '20 at 05:18

2 Answers2

0

What you display depends on which ps command you mimic.

The BSD ps man page says this about %CPU:

The CPU utilization of the process; this is a decaying average over up to a minute of previous (real) time. Because the time base over which this is computed varies (some processes may be very young), it is possible for the sum of all %cpu fields to exceed 100%.

The description of %mem is this:

The percentage of real memory used by this process.

Notice it says "real" memory, which I take to mean virtual memory is excluded in the computation.

Jeff Holt
  • 2,940
  • 3
  • 22
  • 29
0

Look at the source code of ps command.

%CPU

In the following:

  • pp->utime = field#14 of /proc/[pid]/stat
  • pp->stime = field#15 of /proc/[pid]/stat
  • pp->cutime = field#16 of /proc/[pid]/stat
  • pp->cstime = field#17 of /proc/[pid]/stat
  • pp->start_time = field#22 of /proc/[pid]/stat
  • seconds_since_boot = field#1 of /proc/uptime
  • include_dead_children = 1 if 'S' option is passed (Sum up some information, such as CPU usage, from dead child processes into their parent)
[...]
#define cook_etime(P) (((unsigned long long)seconds_since_boot >= (P->start_time / Hertz)) ? ((unsigned long long)seconds_since_boot - (P->start_time / Hertz)) : 0)
[...]
Hertz = sysconf(_SC_CLK_TCK);
[...]
  /* jiffies used by this process */
  total_time = pp->utime + pp->stime;
  if(include_dead_children) total_time += (pp->cutime + pp->cstime);

  /* seconds of process life */
  seconds = cook_etime(pp);

  /* scaled %cpu, 999 means 99.9% */
  if(seconds) pcpu = (total_time * 1000ULL / Hertz) / seconds;
  if (pcpu > 999U)
    return snprintf(outbuf, COLWID, "%u", pcpu/10U);
  return snprintf(outbuf, COLWID, "%u.%u", pcpu/10U, pcpu%10U);
[...]

%MEM

In the following:

  • pp->vm_rss = field#24 of /proc/[pid]/stat
  • kb_main_total = MemTotal field of /proc/meminfo
   /* pp->vm_rss * 1000 would overflow on 32-bit systems with 64 GB memory */
   pmem = pp->vm_rss * 1000ULL / kb_main_total;
   if (pmem > 999) pmem = 999;

   snprintf(outbuf, COLWID, "%2u.%u", (unsigned)(pmem/10), (unsigned)(pmem%10));
Rachid K.
  • 4,490
  • 3
  • 11
  • 30