Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix CPU usage error with 32bit awk and long uptimes #11

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

brtwrst
Copy link

@brtwrst brtwrst commented Sep 2, 2024

Greetings,

I have encountered the problem, that my cpu usage in the motd would show values like 103% or -97%.
After some searching i found the issue.

The version of awk on my rpi is

$ awk -W version

mawk 1.3.4 20200120
Copyright 2008-2019,2020, Thomas E. Dickey
Copyright 1991-1996,2014, Michael D. Brennan

random-funcs:       srandom/random
regex-funcs:        internal
compiled limits:
sprintf buffer      8192
maximum-integer     2147483647

Note the maximum-integer of 2 billion

Output of my /proc/stat is

$ cat /proc/stat
cpu  2270794 3385 8782791 4555485915 579486 0 92152 0 0 0

Note the idle time of 4 billion at position $5 (uptime is 132 days)

this causes problems when calculating the sum of all the cputimes:

$ echo $(awk '/cpu /{print $2+$3+$4+$5+$6+$7+$8+$9+$10,$5}' /proc/stat;)
4.56728e+09 4555553681

and consequently awk prints an imprecise float number instead of an integer which screws up the following calculations

Forcing it to print integers doesn't work, it then hits the max value of awk

$ echo $(awk '/cpu /{printf "%d %d",$2+$3+$4+$5+$6+$7+$8+$9+$10,$5}' /proc/stat;)
2147483647 2147483647

The solution was to change the math around a bit (result is of course the same), so that awk never "prints" an integer that is bigger than 2 billion

$ echo $(awk -v a="$(awk '/cpu /{print $2+$3+$4+$6+$7+$8+$9+$10,$5}' /proc/stat; sleep 0.3)" '/cpu /{split(a,b," "); printf "%.1f%%", 100*($2+$3+$4+$6+$7+$8+$9+$10-b[1])/(($2+$3+$4+$6+$7+$8+$9+$10-b[1]) + ($5-b[2]))}' /proc/stat)
0.8%

This will of course fail once the cpu "busy" time sum is bigger than 2 billion but considering that on my (admittedly very inactive) raspberry pi that sum is currently around 11 million (after 132 days of uptime) that should not happen very soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant