views:

59

answers:

2

I crafted a Bash prompt that, When the working directory is a Git repository, displays the name of the current repository. Besides, it contains the current ongoing task and the time spent doing it (from a homebrew timekeeping tool). This, of course, means that just displaying the prompt means running two processes.

This has the drawback that if the system is thrashing for whatever reason, it takes forever to get a prompt to do that necessary killall to save the system, as just loading the git binary is too much to ask of the system in such a state.

So, right now, the prompt is disabled by default, and only enabled on demand, but this is not that comfortable. It would be nicer to detect the load in .bashrc, and only enable the prompt if the system is running fine (i.e. with acceptable disk latency).

In such situations, CPU is fairly cheap, only the disk is expensive. So I need a way that detects thrashing without depending on external utilities.

Hint: /proc might have something useful. E.g. /proc/loadavg would solve my problem if it were the CPU that causes the bottlenecks, not the disk.

+1  A: 

vmstat could help you. If you don't want to use it, all the information is on

  • /proc/meminfo
  • /proc/stat
  • /proc/PID/stat
Michael Foukarakis
+1  A: 

The easiest way would be to check the first byte of /proc/loadavg, and only continue when it is a 0

This will work

loadavg=$(</proc/loadavg)
if [ "${loadavg:0:1}" = "0" ]; then echo "all clear"; fi

But you still have test (or [) which may be run, although that may be a builtin in bash. edit^2 it's a builtin at least in bash 3.2.39 but I suspect it has been builtin for a long time. So this can all happen without another process.

edit^3: update, for fine grained control:

if [ "${loadavg:0:1}${loadavg:2:2}" -lt "60" ]; then echo "below 0.6"; fi

edit^4: I cannot imagine that disk I/O is the bottleneck for the problem at hand. As long as you don't write, but only read, from places that are cached anyway, this is a pure memory / cpu issue.

edit^5: Of course this is for the 1 cpu case, multiply the threshold percentage by the number of cores (for HT processors, take half the "cores" to be sure)

mvds
bonus points for anyone who manages to integrate `$(<...)` into `${...::}`, which seems impossible.
mvds
Funny, `bash` *does* fork off to read `/proc/loadavg`. Guess there's nothing you can do about that, apart from patching `bash` of course.
mvds
@mvds: a shell forks off to do almost anything.
Michael Foukarakis
My point about `loadavg` was that it is not what I need. A single process can send the system thrashing (and probably even below load 1.00), either via excessive and nasty FS usage, or VM swapping. On the other hand, I may run 10 infinite loops (load 10.00), and still get a prompt immediately, since the disk is idling about, and one-fifth of a core is more than enough for this kind of stuff.
AttishOculus
One up-vote for the floating-point comparing trick :)
AttishOculus
thx ;-) I still don't get the point, your processes (parsing `cwd` and `/proc/$$/...`) don't involve blocking disk I/O, so you only need to watch out not to increase a high load.
mvds
A concrete example when this caused a problem: I used a laptop to display a scrolling slideshow of a PDF that contained a huge number of high-DPI photos, one per page. The code must have been leaking memory, because, after about half an hour, core usage was 97x MB (with 1 GB of RAM), and swapping constantly. In this case, the `loadavg` shouldn't be too high, as it is a single process that causes the load. I was looking for a more general solution since VM is not the only thing that can abuse disk bandwidth, but I guess I'll have to stick with watching VM activity only -- better than nothing.
AttishOculus