library: tweak support for get/select/reap, <PIDS> api
When the <pids> api was refactored in the commit shown
below, one objective was enabling the simultaneous use
of 'get' & 'select/reap' functions. Unlike other 'get'
functions, this <pids> 'get' acts as an iterator where
successive calls will return successive tasks/threads.
However, that goal wasn't quite met since a stack used
by 'get' was commingled with the 'select/reap' stacks.
Such commingling supported the 'reset' function, again
a provision which was unique to this <pids> interface.
Unfortunately, some poor assumptions in 'stacks_fetch'
produced a SEGV whenever 'reap/select' followed 'get'.
Thus, this patch addresses those issues and guarantees
such commingled stacks (extents) will be accommodated.
Reference(s):
. standardize portions of interface, <PIDS> api
commit 9ebadc1438
Signed-off-by: Jim Warner <james.warner@comcast.net>
This commit is contained in:
parent
a9bfb186eb
commit
f87fc7dc83
36
proc/pids.c
36
proc/pids.c
@ -86,7 +86,7 @@ struct pids_info {
|
||||
unsigned long hertz; // for TIME_ALL & TIME_ELAPSED calculations
|
||||
unsigned long long boot_seconds; // for TIME_ELAPSED calculation
|
||||
PROCTAB *get_PT; // oldlib interface for active 'get'
|
||||
struct stacks_extent *get_ext; // an extent used for active 'get'
|
||||
struct stacks_extent *get_ext; // for active 'get' (also within 'extents')
|
||||
enum pids_fetch_type get_type; // last known type of 'get' request
|
||||
int seterr; // an ENOMEM encountered during assign
|
||||
};
|
||||
@ -1047,13 +1047,10 @@ static int pids_stacks_fetch (
|
||||
if (!info->fetch.anchor) {
|
||||
if (!(info->fetch.anchor = calloc(sizeof(void *), STACKS_INCR)))
|
||||
return -1;
|
||||
n_alloc = STACKS_INCR;
|
||||
}
|
||||
if (!info->extents) {
|
||||
if (!(ext = pids_stacks_alloc(info, n_alloc)))
|
||||
if (!(ext = pids_stacks_alloc(info, STACKS_INCR)))
|
||||
return -1; // here, errno was set to ENOMEM
|
||||
memset(info->fetch.anchor, 0, sizeof(void *) * n_alloc);
|
||||
memcpy(info->fetch.anchor, ext->stacks, sizeof(void *) * n_alloc);
|
||||
memcpy(info->fetch.anchor, ext->stacks, sizeof(void *) * STACKS_INCR);
|
||||
n_alloc = STACKS_INCR;
|
||||
}
|
||||
pids_cleanup_stacks_all(info);
|
||||
pids_toggle_history(info);
|
||||
@ -1223,6 +1220,9 @@ PROCPS_EXPORT int procps_pids_unref (
|
||||
free((*info)->hist);
|
||||
}
|
||||
|
||||
if ((*info)->get_ext)
|
||||
pids_oldproc_close(&(*info)->get_PT);
|
||||
|
||||
numa_uninit();
|
||||
|
||||
free(*info);
|
||||
@ -1288,10 +1288,10 @@ PROCPS_EXPORT struct pids_stack *procps_pids_get (
|
||||
if (!info->curitems)
|
||||
return NULL;
|
||||
|
||||
fresh_start:
|
||||
if (!info->get_ext) {
|
||||
if (!(info->get_ext = pids_stacks_alloc(info, 1)))
|
||||
return NULL; // here, errno was overridden with ENOMEM
|
||||
fresh_start:
|
||||
if (!pids_oldproc_open(&info->get_PT, info->oldflags))
|
||||
return NULL; // here, errno was overridden with ENOMEM/others
|
||||
info->get_type = which;
|
||||
@ -1300,10 +1300,6 @@ fresh_start:
|
||||
|
||||
if (info->get_type != which) {
|
||||
pids_oldproc_close(&info->get_PT);
|
||||
pids_cleanup_stack(info->get_ext->stacks[0]->head);
|
||||
if (pids_extent_cut(info, info->get_ext))
|
||||
free(info->get_ext);
|
||||
info->get_ext = NULL;
|
||||
goto fresh_start;
|
||||
}
|
||||
errno = 0;
|
||||
@ -1364,6 +1360,9 @@ PROCPS_EXPORT int procps_pids_reset (
|
||||
if (pids_items_check_failed(newitems, newnumitems))
|
||||
return -EINVAL;
|
||||
|
||||
if (info->dirty_stacks)
|
||||
pids_cleanup_stacks_all(info);
|
||||
|
||||
/* shame on this caller, they didn't change anything. and unless they have
|
||||
altered the depth of the stacks we're not gonna change anything either! */
|
||||
if (info->curitems == newnumitems + 1
|
||||
@ -1371,22 +1370,25 @@ PROCPS_EXPORT int procps_pids_reset (
|
||||
return 0;
|
||||
|
||||
if (info->maxitems < newnumitems + 1) {
|
||||
if (info->dirty_stacks)
|
||||
pids_cleanup_stacks_all(info);
|
||||
while (info->extents) {
|
||||
struct stacks_extent *p = info->extents;
|
||||
info->extents = p->next;
|
||||
free(p);
|
||||
};
|
||||
if (info->get_ext) {
|
||||
pids_oldproc_close(&info->get_PT);
|
||||
info->get_ext = NULL;
|
||||
}
|
||||
if (info->fetch.anchor) {
|
||||
free(info->fetch.anchor);
|
||||
info->fetch.anchor = NULL;
|
||||
}
|
||||
// allow for our PIDS_logical_end
|
||||
info->maxitems = newnumitems + 1;
|
||||
if (!(info->items = realloc(info->items, sizeof(enum pids_item) * info->maxitems)))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (info->dirty_stacks)
|
||||
pids_cleanup_stacks_all(info);
|
||||
|
||||
memcpy(info->items, newitems, sizeof(enum pids_item) * newnumitems);
|
||||
info->items[newnumitems] = PIDS_logical_end;
|
||||
// account for above PIDS_logical_end
|
||||
|
Loading…
Reference in New Issue
Block a user