library: reduce copies of items to minimum, <STAT> api
This commit will consolidate the three separate copies of the item enumerators currently supporting that reap function (summary, cpus & nodes) into one shared copy. That select function will continue to maintain its own dedicated items copy, albeit via a new item structure. [ and while we're at it, we'll move the 'select' guy ] [ to its proper alphabetical place, after our 'reap' ] Signed-off-by: Jim Warner <james.warner@comcast.net>
This commit is contained in:
parent
8cd1214aac
commit
4fe52ccd44
112
proc/stat.c
112
proc/stat.c
@ -84,9 +84,13 @@ struct stacks_extent {
|
|||||||
struct stat_stack **stacks;
|
struct stat_stack **stacks;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct item_support {
|
||||||
|
int num; // includes 'logical_end' delimiter
|
||||||
|
enum stat_item *enums; // includes 'logical_end' delimiter
|
||||||
|
};
|
||||||
|
|
||||||
struct ext_support {
|
struct ext_support {
|
||||||
int numitems; // includes 'logical_end' delimiter
|
struct item_support *items; // how these stacks are configured
|
||||||
enum stat_item *items; // includes 'logical_end' delimiter
|
|
||||||
struct stacks_extent *extents; // anchor for these extents
|
struct stacks_extent *extents; // anchor for these extents
|
||||||
int dirty_stacks;
|
int dirty_stacks;
|
||||||
};
|
};
|
||||||
@ -123,6 +127,8 @@ struct procps_statinfo {
|
|||||||
int (*our_node_of_cpu)(int); // a libnuma function call via dlsym()
|
int (*our_node_of_cpu)(int); // a libnuma function call via dlsym()
|
||||||
#endif
|
#endif
|
||||||
struct stat_result get_this; // for return to caller after a get
|
struct stat_result get_this; // for return to caller after a get
|
||||||
|
struct item_support reap_items; // items used for reap (shared among 3)
|
||||||
|
struct item_support select_items; // items unique to select
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -608,7 +614,7 @@ static struct stacks_extent *stacks_alloc (
|
|||||||
vect_size = sizeof(void *) * maxstacks; // size of the addr vectors |
|
vect_size = sizeof(void *) * maxstacks; // size of the addr vectors |
|
||||||
vect_size += sizeof(void *); // plus NULL addr delimiter |
|
vect_size += sizeof(void *); // plus NULL addr delimiter |
|
||||||
head_size = sizeof(struct stat_stack); // size of that head struct |
|
head_size = sizeof(struct stat_stack); // size of that head struct |
|
||||||
list_size = sizeof(struct stat_result) * this->numitems; // any single results stack |
|
list_size = sizeof(struct stat_result) * this->items->num;// any single results stack |
|
||||||
blob_size = sizeof(struct stacks_extent); // the extent anchor itself |
|
blob_size = sizeof(struct stacks_extent); // the extent anchor itself |
|
||||||
blob_size += vect_size; // plus room for addr vects |
|
blob_size += vect_size; // plus room for addr vects |
|
||||||
blob_size += head_size * maxstacks; // plus room for head thing |
|
blob_size += head_size * maxstacks; // plus room for head thing |
|
||||||
@ -629,7 +635,7 @@ static struct stacks_extent *stacks_alloc (
|
|||||||
|
|
||||||
for (i = 0; i < maxstacks; i++) {
|
for (i = 0; i < maxstacks; i++) {
|
||||||
p_head = (struct stat_stack *)v_head;
|
p_head = (struct stat_stack *)v_head;
|
||||||
p_head->head = itemize_stack((struct stat_result *)v_list, this->numitems, this->items);
|
p_head->head = itemize_stack((struct stat_result *)v_list, this->items->num, this->items->enums);
|
||||||
p_blob->stacks[i] = p_head;
|
p_blob->stacks[i] = p_head;
|
||||||
v_list += list_size;
|
v_list += list_size;
|
||||||
v_head += head_size;
|
v_head += head_size;
|
||||||
@ -696,16 +702,15 @@ static int stacks_reconfig_maybe (
|
|||||||
|
|
||||||
/* is this the first time or have things changed since we were last called?
|
/* is this the first time or have things changed since we were last called?
|
||||||
if so, gotta' redo all of our stacks stuff ... */
|
if so, gotta' redo all of our stacks stuff ... */
|
||||||
if (this->numitems != numitems + 1
|
if (this->items->num != numitems + 1
|
||||||
|| memcmp(this->items, items, sizeof(enum stat_item) * numitems)) {
|
|| memcmp(this->items->enums, items, sizeof(enum stat_item) * numitems)) {
|
||||||
// allow for our PROCPS_STAT_logical_end
|
// allow for our PROCPS_STAT_logical_end
|
||||||
if (!(this->items = realloc(this->items, sizeof(enum stat_item) * (numitems + 1))))
|
if (!(this->items->enums = realloc(this->items->enums, sizeof(enum stat_item) * (numitems + 1))))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
memcpy(this->items, items, sizeof(enum stat_item) * numitems);
|
memcpy(this->items->enums, items, sizeof(enum stat_item) * numitems);
|
||||||
this->items[numitems] = PROCPS_STAT_logical_end;
|
this->items->enums[numitems] = PROCPS_STAT_logical_end;
|
||||||
this->numitems = numitems + 1;
|
this->items->num = numitems + 1;
|
||||||
if (this->extents)
|
extents_free_all(this);
|
||||||
extents_free_all(this);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -714,13 +719,8 @@ static int stacks_reconfig_maybe (
|
|||||||
|
|
||||||
static struct stat_stack *update_single_stack (
|
static struct stat_stack *update_single_stack (
|
||||||
struct procps_statinfo *info,
|
struct procps_statinfo *info,
|
||||||
struct ext_support *this,
|
struct ext_support *this)
|
||||||
enum stat_item *items,
|
|
||||||
int numitems)
|
|
||||||
{
|
{
|
||||||
if (0 > stacks_reconfig_maybe(this, items, numitems))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (!this->extents
|
if (!this->extents
|
||||||
&& !(stacks_alloc(this, 1)))
|
&& !(stacks_alloc(this, 1)))
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -770,6 +770,12 @@ PROCPS_EXPORT int procps_stat_new (
|
|||||||
p->results.nodes = &p->nodes.result;
|
p->results.nodes = &p->nodes.result;
|
||||||
p->cpus.total = procps_cpu_count();
|
p->cpus.total = procps_cpu_count();
|
||||||
|
|
||||||
|
// these 3 are for reap, sharing a single set of items
|
||||||
|
p->cpu_summary.items = p->cpus.fetch.items = p->nodes.fetch.items = &p->reap_items;
|
||||||
|
|
||||||
|
// the select guy has its own set of items
|
||||||
|
p->select.items = &p->select_items;
|
||||||
|
|
||||||
#ifndef NUMA_DISABLE
|
#ifndef NUMA_DISABLE
|
||||||
#ifndef PRETEND_NUMA
|
#ifndef PRETEND_NUMA
|
||||||
// we'll try for the most recent version, then a version we know works...
|
// we'll try for the most recent version, then a version we know works...
|
||||||
@ -820,8 +826,6 @@ PROCPS_EXPORT int procps_stat_unref (
|
|||||||
free((*info)->cpus.anchor);
|
free((*info)->cpus.anchor);
|
||||||
if ((*info)->cpus.hist.tics)
|
if ((*info)->cpus.hist.tics)
|
||||||
free((*info)->cpus.hist.tics);
|
free((*info)->cpus.hist.tics);
|
||||||
if ((*info)->cpus.fetch.items)
|
|
||||||
free((*info)->cpus.fetch.items);
|
|
||||||
if ((*info)->cpus.fetch.extents)
|
if ((*info)->cpus.fetch.extents)
|
||||||
extents_free_all(&(*info)->cpus.fetch);
|
extents_free_all(&(*info)->cpus.fetch);
|
||||||
|
|
||||||
@ -829,21 +833,20 @@ PROCPS_EXPORT int procps_stat_unref (
|
|||||||
free((*info)->nodes.anchor);
|
free((*info)->nodes.anchor);
|
||||||
if ((*info)->nodes.hist.tics)
|
if ((*info)->nodes.hist.tics)
|
||||||
free((*info)->nodes.hist.tics);
|
free((*info)->nodes.hist.tics);
|
||||||
if ((*info)->nodes.fetch.items)
|
|
||||||
free((*info)->nodes.fetch.items);
|
|
||||||
if ((*info)->nodes.fetch.extents)
|
if ((*info)->nodes.fetch.extents)
|
||||||
extents_free_all(&(*info)->nodes.fetch);
|
extents_free_all(&(*info)->nodes.fetch);
|
||||||
|
|
||||||
if ((*info)->cpu_summary.items)
|
|
||||||
free((*info)->cpu_summary.items);
|
|
||||||
if ((*info)->cpu_summary.extents)
|
if ((*info)->cpu_summary.extents)
|
||||||
extents_free_all(&(*info)->cpu_summary);
|
extents_free_all(&(*info)->cpu_summary);
|
||||||
|
|
||||||
if ((*info)->select.items)
|
|
||||||
free((*info)->select.items);
|
|
||||||
if ((*info)->select.extents)
|
if ((*info)->select.extents)
|
||||||
extents_free_all(&(*info)->select);
|
extents_free_all(&(*info)->select);
|
||||||
|
|
||||||
|
if ((*info)->reap_items.enums)
|
||||||
|
free((*info)->reap_items.enums);
|
||||||
|
if ((*info)->select_items.enums)
|
||||||
|
free((*info)->select_items.enums);
|
||||||
|
|
||||||
#ifndef NUMA_DISABLE
|
#ifndef NUMA_DISABLE
|
||||||
#ifndef PRETEND_NUMA
|
#ifndef PRETEND_NUMA
|
||||||
if ((*info)->libnuma_handle)
|
if ((*info)->libnuma_handle)
|
||||||
@ -891,28 +894,6 @@ PROCPS_EXPORT struct stat_result *procps_stat_get (
|
|||||||
} // end: procps_stat_get
|
} // end: procps_stat_get
|
||||||
|
|
||||||
|
|
||||||
/* procps_stat_select():
|
|
||||||
*
|
|
||||||
* Harvest all the requested TIC and/or SYS information then return
|
|
||||||
* it in a results stack.
|
|
||||||
*
|
|
||||||
* Returns: pointer to a stat_stack struct on success, NULL on error.
|
|
||||||
*/
|
|
||||||
PROCPS_EXPORT struct stat_stack *procps_stat_select (
|
|
||||||
struct procps_statinfo *info,
|
|
||||||
enum stat_item *items,
|
|
||||||
int numitems)
|
|
||||||
{
|
|
||||||
if (info == NULL || items == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (read_stat_failed(info))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return update_single_stack(info, &info->select, items, numitems);
|
|
||||||
} // end: procps_stat_select
|
|
||||||
|
|
||||||
|
|
||||||
/* procps_stat_reap():
|
/* procps_stat_reap():
|
||||||
*
|
*
|
||||||
* Harvest all the requested NUMA NODE and/or CPU information providing the
|
* Harvest all the requested NUMA NODE and/or CPU information providing the
|
||||||
@ -947,17 +928,17 @@ PROCPS_EXPORT struct stat_reaped *procps_stat_reap (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if ((rc = stacks_reconfig_maybe(&info->cpu_summary, items, numitems)) < 0)
|
|
||||||
|
if (0 > (rc = stacks_reconfig_maybe(&info->cpu_summary, items, numitems)))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (rc) {
|
if (rc) {
|
||||||
if ((rc = stacks_reconfig_maybe(&info->cpus.fetch, items, numitems)) < 0
|
extents_free_all(&info->cpus.fetch);
|
||||||
|| ((rc = stacks_reconfig_maybe(&info->nodes.fetch, items, numitems)) < 0))
|
extents_free_all(&info->nodes.fetch);
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (read_stat_failed(info))
|
if (read_stat_failed(info))
|
||||||
return NULL;
|
return NULL;
|
||||||
info->results.summary = update_single_stack(info, &info->cpu_summary, items, numitems);
|
info->results.summary = update_single_stack(info, &info->cpu_summary);
|
||||||
|
|
||||||
switch (what) {
|
switch (what) {
|
||||||
case STAT_REAP_CPUS_ONLY:
|
case STAT_REAP_CPUS_ONLY:
|
||||||
@ -983,3 +964,28 @@ PROCPS_EXPORT struct stat_reaped *procps_stat_reap (
|
|||||||
|
|
||||||
return &info->results;
|
return &info->results;
|
||||||
} // end: procps_stat_reap
|
} // end: procps_stat_reap
|
||||||
|
|
||||||
|
|
||||||
|
/* procps_stat_select():
|
||||||
|
*
|
||||||
|
* Harvest all the requested TIC and/or SYS information then return
|
||||||
|
* it in a results stack.
|
||||||
|
*
|
||||||
|
* Returns: pointer to a stat_stack struct on success, NULL on error.
|
||||||
|
*/
|
||||||
|
PROCPS_EXPORT struct stat_stack *procps_stat_select (
|
||||||
|
struct procps_statinfo *info,
|
||||||
|
enum stat_item *items,
|
||||||
|
int numitems)
|
||||||
|
{
|
||||||
|
if (info == NULL || items == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (0 > stacks_reconfig_maybe(&info->select, items, numitems))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (read_stat_failed(info))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return update_single_stack(info, &info->select);
|
||||||
|
} // end: procps_stat_select
|
||||||
|
Loading…
x
Reference in New Issue
Block a user