PerfMon is a demonstration application to help illustrate the use of the GPK library. It is a multithreaded Linux performance monitor that delegates the responsibility for updating each performance meter to an individual thread.

Overview

PerfMon looks like this:

The four toggle buttons on the left each spawn/kill a thread to control each of four performance meters. The slider is used to control the wait interval each thread uses before gathering the next performance sample from the /proc filesystem. As pictured, each meter will sample every 1.0 seconds.

Although the existing functionality could fairly easily be implemented using standard GTK event loop/callback methods, the next developmental step for this application could not: using RPC or sockets to read performance values on other systems whose response time is indeterminate.

PerfMon also demonstrates the distributed widgets ownership concept enabled using threads. The C variables used to maintain the GTK widgets and the performance variables are implemented as automatic types as opposed to the usual global or static.

How does it work?

Here is the general flow:
  • Create the GUI shell that will hold the meters displaying system performance. Populate it with toggle buttons that are wired to activate a thread for each meter, and the interval slider.
  • Enter the main GTK event loop.
  • When any of the meter toggles are depressed, spawn a thread that builds the meter (by proxy), adds it to the main window, tracks the running average of the last two performance measures and periodically updates the meter labels.
  • A shared interval timer is controlled by the slider. Its value is protected by a mutex.

Things to note

Before the threads enter their infinite for loop, they turn off "wait" with gpk_auto_wait_set(). This has the effect of making all subsequent calls to GPK non-blocking, i.e, not waiting for the function to be executed and discarding any return values. This feature should be used with care: the caller does not know when the function will execute and must ensure that the parameters passed and whatever they reference stay in existence for until it does execute.

Single GPK calls typically replace 3, 4 or 5 GTK calls. To accomodate this and the ThreadProxy requirement to pass only pointers, parameters for a number of calls are packaged in structures. Because I found myself having to consult the GTK tutorial about the meanings of "expand", "fill", and others, I added defines that make these for self-explanatory.


If you have comments or suggestions, email me at sdybiec@humanfactor.com