summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Warner <james.warner@comcast.net>2023-05-03 00:00:00 -0500
committerCraig Small <csmall@dropbear.xyz>2023-05-07 09:43:44 +1000
commit1c9e65d785b8b8d82256f946d4feb2a1070ac02f (patch)
tree6b486fca4f27346e536bc7d601454521ca9b1929
parent157612a5ed91d0e6485e56b20beced90c31202cf (diff)
downloadprocps-ng-1c9e65d785b8b8d82256f946d4feb2a1070ac02f.tar.gz
library: improve the assign results function, pids api
Currently, all the newlib APIs handle the assigning of results the same. Namely, they loop through the stacks while checking for the hidden 'logical_end' fencepost. Along the way, the Item_table was indexed to determine which 'setsfunc' to call, passing suitable parameters. The approach was quite robust since by testing against the unsigned 'logical_end' enumerator this library was immune from user result corruption. The worst that may happen was early loop exit with some results unvalued. However, there was a drawback to the current approach. For every result structure in every stack, an index to that Item_table had to be calculated for a 'setsfunc'. For programs like top or ps that may involve thousands of Item_table index recalculations for each iteration. With this commit, in support of assign, we will now do the needed Item_table calculations just one time under the 'new' and 'reset' functions. Then, at assign time, the only overhead is actually invoking the 'setsfunc'. This makes us even more robust than we were before. No longer will a corrupted results structure suffer early assign exit leaving some unvalued. Rather, all results are properly placed regardless of any user corruption. [ those other interfaces will remain unchanged since ] [ the depth of their stacks are modest and since the ] [ assign guys weren't already passed an info pointer ] Signed-off-by: Jim Warner <james.warner@comcast.net>
-rw-r--r--library/pids.c34
1 files changed, 28 insertions, 6 deletions
diff --git a/library/pids.c b/library/pids.c
index 3b9bf99..6ae94ad 100644
--- a/library/pids.c
+++ b/library/pids.c
@@ -75,6 +75,8 @@ struct fetch_support {
struct pids_counts counts; // actual counts pointed to by 'results'
};
+typedef void (*SET_t)(struct pids_info *, struct pids_result *, proc_t *);
+
struct pids_info {
int refcount;
int maxitems; // includes 'logical_end' delimiter
@@ -96,6 +98,7 @@ struct pids_info {
int seterr; // an ENOMEM encountered during assign
proc_t get_proc; // the proc_t used by procps_pids_get
proc_t fetch_proc; // the proc_t used by pids_stacks_fetch
+ SET_t *func_array; // extracted Item_table 'setsfunc' pointers
};
@@ -403,7 +406,6 @@ srtDECL(noop) {
// placed here so an 'f' prefix wouldn't make 'em first
#define z_autogrp PROC_FILLAUTOGRP
-typedef void (*SET_t)(struct pids_info *, struct pids_result *, proc_t *);
typedef void (*FRE_t)(struct pids_result *);
typedef int (*QSR_t)(const void *, const void *, void *);
@@ -856,14 +858,13 @@ static inline int pids_assign_results (
proc_t *p)
{
struct pids_result *this = stack->head;
+ SET_t *that = &info->func_array[0];
info->seterr = 0;
- for (;;) {
- enum pids_item item = this->item;
- if (item >= PIDS_logical_end)
- break;
- Item_table[item].setsfunc(info, this, p);
+ while (*that) {
+ (*that)(info, this, p);
++this;
+ ++that;
}
return !info->seterr;
} // end: pids_assign_results
@@ -1041,6 +1042,20 @@ static inline int pids_oldproc_open (
} // end: pids_oldproc_open
+static int pids_prep_func_array (
+ struct pids_info *info)
+{
+ int i;
+
+ if (!(info->func_array = realloc(info->func_array, sizeof(SET_t) * info->maxitems)))
+ return 0;
+ for (i = 0; i < info->maxitems -1; i++)
+ info->func_array[i] = Item_table[info->items[i]].setsfunc;
+ info->func_array[i] = NULL;
+ return 1;
+} // end: pids_prep_func_array
+
+
static inline int pids_proc_tally (
struct pids_info *info,
struct pids_counts *counts,
@@ -1273,6 +1288,8 @@ PROCPS_EXPORT int procps_pids_new (
memcpy(p->items, items, sizeof(enum pids_item) * numitems);
p->items[numitems] = PIDS_logical_end;
pids_libflags_set(p);
+ if (!pids_prep_func_array(p))
+ return -ENOMEM;
}
if (!(p->hist = calloc(1, sizeof(struct history_info)))
@@ -1360,6 +1377,9 @@ PROCPS_EXPORT int procps_pids_unref (
if ((*info)->get_ext)
pids_oldproc_close(&(*info)->get_PT);
+ if ((*info)->func_array)
+ free((*info)->func_array);
+
numa_uninit();
free(*info);
@@ -1528,6 +1548,8 @@ PROCPS_EXPORT int procps_pids_reset (
// so we'll rely on pids_stacks_alloc() to itemize ...
pids_itemize_stacks_all(info);
pids_libflags_set(info);
+ if (!pids_prep_func_array(info))
+ return -ENOMEM;
return 0;
} // end: procps_pids_reset