top: improve the most heavily used library interface

In the procs_refresh() function:
. the proctable scan was simplified
. memory allocation is now much more efficient
. window ppts will usually not now need xrealloc
This commit is contained in:
Jim Warner 2011-11-17 10:31:07 -06:00 committed by Craig Small
parent 88087ec5a5
commit c8bbcec5db

52
top.c
View File

@ -1954,47 +1954,47 @@ static void prochlp (proc_t *this) {
* we reuse and extend any prior proc_t's. He's been customized * we reuse and extend any prior proc_t's. He's been customized
* for our specific needs and to avoid the use of <stdarg.h> */ * for our specific needs and to avoid the use of <stdarg.h> */
static void procs_refresh (void) { static void procs_refresh (void) {
static proc_t **private_ppt; // our base proc_t pointer table #define n_used Frame_maxtask // maintained by prochlp()
static unsigned savmax = 0; // first time, Bypass: (i) static proc_t **private_ppt; // our base proc_t ptr table
proc_t *ptask = (proc_t*)-1; // first time, Force: (ii) static int n_alloc = 0; // size of our private_ppt
unsigned curmax = 0; // every time (jeeze) static int n_saved = 0; // last window ppt size
proc_t *ptask;
PROCTAB* PT; PROCTAB* PT;
int i; int i;
proc_t*(*read_something)(PROCTAB*, proc_t*); proc_t*(*read_something)(PROCTAB*, proc_t*);
prochlp(NULL); // prep for a new frame prochlp(NULL); // prep for a new frame
if (NULL == (PT = openproc(Frames_libflags, Monpids))) if (NULL == (PT = openproc(Frames_libflags, Monpids)))
error_exit(fmtmk("failed openproc: %s", strerror(errno))); error_exit(fmtmk("failed openproc: %s", strerror(errno)));
read_something = Thread_mode ? readeither : readproc; read_something = Thread_mode ? readeither : readproc;
// i) Allocated Chunks: *Existing* table; refresh + reuse for (;;) {
while (curmax < savmax) { if (n_used == n_alloc) {
if (!(ptask = read_something(PT, private_ppt[curmax]))) break; n_alloc = 10 + ((n_alloc * 5) / 4); // grow by over 25%
prochlp(ptask); // tally & complete this proc_t private_ppt = xrealloc(private_ppt, sizeof(proc_t*) * n_alloc);
++curmax; // ensure NULL pointers for the additional memory just acquired
} memset(private_ppt + n_used, 0, sizeof(proc_t*) * (n_alloc - n_used));
// ii) Unallocated Chunks: *New* or *Existing* table; extend + fill
while (ptask) {
// realloc as we go, keeping 'ppt' ahead of 'currmax++'
private_ppt = alloc_r(private_ppt, (curmax + 1) * sizeof(proc_t*));
// here, the library will allocate the underlying proc_t stg
if ((ptask = read_something(PT, NULL))) {
prochlp(ptask); // tally & complete this proc_t
private_ppt[curmax++] = ptask;
} }
// on the way to n_alloc, the library will allocate the underlying
// proc_t storage whenever our private_ppt[] pointer is NULL...
if (!(ptask = read_something(PT, private_ppt[n_used]))) break;
prochlp((private_ppt[n_used] = ptask)); // tally this proc_t
} }
closeproc(PT); closeproc(PT);
// iii) Chunkless: End frame, but not necessarily end of allocated space
if (savmax < curmax) savmax = curmax;
// lastly, refresh each window's proc pointers table... // lastly, refresh each window's proc pointers table...
for (i = 0; i < GROUPSMAX; i++) { if (n_saved == n_alloc)
Winstk[i].ppt = alloc_r(Winstk[i].ppt, savmax * sizeof(proc_t*)); for (i = 0; i < GROUPSMAX; i++)
memcpy(Winstk[i].ppt, private_ppt, Frame_maxtask * sizeof(proc_t*)); memcpy(Winstk[i].ppt, private_ppt, sizeof(proc_t*) * n_used);
else {
n_saved = n_alloc;
for (i = 0; i < GROUPSMAX; i++) {
Winstk[i].ppt = xrealloc(Winstk[i].ppt, sizeof(proc_t*) * n_alloc);
memcpy(Winstk[i].ppt, private_ppt, sizeof(proc_t*) * n_used);
}
} }
#undef n_used
} // end: procs_refresh } // end: procs_refresh