* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <limits.h>
#include <ctype.h>
#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
-#include <sys/types.h>
+#include <unistd.h>
+
#include <sys/stat.h>
-#include <fcntl.h>
+#include <sys/types.h>
#include <proc/slab.h>
#include "procps-private.h"
#define SLABINFO_LINE_LEN 2048
#define SLAB_INFO_NAME_LEN 128
-struct slabinfo_node {
- char name[SLAB_INFO_NAME_LEN]; /* name of this cache */
- unsigned long cache_size; /* size of entire cache */
- unsigned nr_objs; /* number of objects in this cache */
- unsigned nr_active_objs; /* number of active objects */
- unsigned obj_size; /* size of each object */
- unsigned objs_per_slab; /* number of objects per slab */
- unsigned pages_per_slab; /* number of pages per slab */
- unsigned nr_slabs; /* number of slabs in this cache */
- unsigned nr_active_slabs; /* number of active slabs */
- unsigned use; /* percent full: total / active */
-};
-
struct slabinfo_stats {
unsigned long total_size; /* size of all objects */
unsigned long active_size; /* size of all active objects */
- unsigned nr_objs; /* number of objects, among all caches */
- unsigned nr_active_objs; /* number of active objects, among all caches */
- unsigned nr_pages; /* number of pages consumed by all objects */
- unsigned nr_slabs; /* number of slabs, among all caches */
- unsigned nr_active_slabs; /* number of active slabs, among all caches */
- unsigned nr_caches; /* number of caches */
- unsigned nr_active_caches; /* number of active caches */
- unsigned avg_obj_size; /* average object size */
- unsigned min_obj_size; /* size of smallest object */
- unsigned max_obj_size; /* size of largest object */
+ unsigned int nr_objs; /* number of objects, among all caches */
+ unsigned int nr_active_objs; /* number of active objects, among all caches */
+ unsigned int nr_pages; /* number of pages consumed by all objects */
+ unsigned int nr_slabs; /* number of slabs, among all caches */
+ unsigned int nr_active_slabs; /* number of active slabs, among all caches */
+ unsigned int nr_caches; /* number of caches */
+ unsigned int nr_active_caches; /* number of active caches */
+ unsigned int avg_obj_size; /* average object size */
+ unsigned int min_obj_size; /* size of smallest object */
+ unsigned int max_obj_size; /* size of largest object */
+};
+
+struct slabinfo_node {
+ char name[SLAB_INFO_NAME_LEN]; /* name of this cache */
+ unsigned long cache_size; /* size of entire cache */
+ unsigned int nr_objs; /* number of objects in this cache */
+ unsigned int nr_active_objs; /* number of active objects */
+ unsigned int obj_size; /* size of each object */
+ unsigned int objs_per_slab; /* number of objects per slab */
+ unsigned int pages_per_slab; /* number of pages per slab */
+ unsigned int nr_slabs; /* number of slabs in this cache */
+ unsigned int nr_active_slabs; /* number of active slabs */
+ unsigned int use; /* percent full: total / active */
};
struct procps_slabinfo {
struct slabinfo_node *nodes; /* first slabnode of this list */
int nodes_alloc; /* nodes alloc()ed */
int nodes_used; /* nodes using alloced memory */
- struct chains_anchor *chained;
+ struct stacks_anchor *stacked;
};
-struct chain_vectors {
- struct chains_anchor *owner;
- struct slabnode_chain **heads;
+struct stack_vectors {
+ struct stacks_anchor *owner;
+ struct slabnode_stack **heads;
};
-struct chains_anchor {
+struct stacks_anchor {
int depth;
int inuse;
int header_size;
- struct chain_vectors *vectors;
- struct chains_anchor *self;
- struct chains_anchor *next;
+ struct stack_vectors *vectors;
+ struct stacks_anchor *self;
+ struct stacks_anchor *next;
};
return retval;
if (sscanf(buffer,
- "%" STRINGIFY(SLAB_INFO_NAME_LEN)
- "s %d %d %d %d %d : tunables %*d %*d %*d : \
- slabdata %d %d %*d", node->name,
+ "%" STRINGIFY(SLAB_INFO_NAME_LEN) "s" \
+ "%u %u %u %u %u : tunables %*u %*u %*u : slabdata %u %u %*u",
+ node->name,
&node->nr_active_objs, &node->nr_objs,
&node->obj_size, &node->objs_per_slab,
&node->pages_per_slab, &node->nr_active_slabs,
* page_size;
if (node->nr_objs) {
- node->use = 100 * node->nr_active_objs / node->nr_objs;
+ node->use = (unsigned int)100 * node->nr_active_objs / node->nr_objs;
stats->nr_active_caches++;
} else
node->use = 0;
/* procps_slabinfo_read():
*
* Read the data out of /proc/slabinfo putting the information
- * into the supplie info container
+ * into the supplied info container
*
* Returns: 0 on success, negative on error
*/
{
if (info == NULL)
return -EINVAL;
+
info->refcount++;
return info->refcount;
}
{
if (info == NULL || *info == NULL)
return -EINVAL;
+
(*info)->refcount--;
if ((*info)->refcount == 0) {
if ((*info)->slabinfo_fp) {
fclose((*info)->slabinfo_fp);
(*info)->slabinfo_fp = NULL;
}
- if ((*info)->chained) {
+ if ((*info)->stacked) {
do {
- struct chains_anchor *p = (*info)->chained;
- (*info)->chained = (*info)->chained->next;
+ struct stacks_anchor *p = (*info)->stacked;
+ (*info)->stacked = (*info)->stacked->next;
free(p);
- } while((*info)->chained);
+ } while((*info)->stacked);
}
free((*info)->nodes);
free(*info);
struct procps_slabinfo *info,
enum slabs_item item)
{
+ /* note: most of the results we might return are actually just
+ unsigned int, but we must accommodate the largest potential
+ result and so return an unsigned long */
if (info == NULL)
return -EINVAL;
return info->stats.total_size;
case PROCPS_SLABS_SIZE_ACTIVE:
return info->stats.active_size;
- case PROCPS_SLABS_noop:
- return 0;
default:
- return -EINVAL;
+ return 0;
}
- return 0;
}
-PROCPS_EXPORT int procps_slabs_getchain (
+PROCPS_EXPORT int procps_slabs_getstack (
struct procps_slabinfo *info,
- struct slabs_result *these)
+ struct slab_result *these)
{
if (info == NULL || these == NULL)
return -EINVAL;
- do {
+ for (;;) {
switch (these->item) {
case PROCPS_SLABS_OBJS:
- these->result = info->stats.nr_objs;
+ these->result.u_int = info->stats.nr_objs;
break;
case PROCPS_SLABS_AOBJS:
- these->result = info->stats.nr_active_objs;
+ these->result.u_int = info->stats.nr_active_objs;
break;
case PROCPS_SLABS_PAGES:
- these->result = info->stats.nr_pages;
+ these->result.u_int = info->stats.nr_pages;
break;
case PROCPS_SLABS_SLABS:
- these->result = info->stats.nr_slabs;
+ these->result.u_int = info->stats.nr_slabs;
break;
case PROCPS_SLABS_ASLABS:
- these->result = info->stats.nr_active_slabs;
+ these->result.u_int = info->stats.nr_active_slabs;
break;
case PROCPS_SLABS_CACHES:
- these->result = info->stats.nr_caches;
+ these->result.u_int = info->stats.nr_caches;
break;
case PROCPS_SLABS_ACACHES:
- these->result = info->stats.nr_active_caches;
+ these->result.u_int = info->stats.nr_active_caches;
break;
case PROCPS_SLABS_SIZE_AVG:
- these->result = info->stats.avg_obj_size;
+ these->result.u_int = info->stats.avg_obj_size;
break;
case PROCPS_SLABS_SIZE_MIN:
- these->result = info->stats.min_obj_size;
+ these->result.u_int = info->stats.min_obj_size;
break;
case PROCPS_SLABS_SIZE_MAX:
- these->result = info->stats.max_obj_size;
+ these->result.u_int = info->stats.max_obj_size;
break;
case PROCPS_SLABS_SIZE_TOTAL:
- these->result = info->stats.total_size;
+ these->result.ul_int = info->stats.total_size;
break;
case PROCPS_SLABS_SIZE_ACTIVE:
- these->result = info->stats.active_size;
+ these->result.ul_int = info->stats.active_size;
break;
case PROCPS_SLABS_noop:
- these->result = 0;
+ // don't disturb potential user data in the result struct
break;
+ case PROCPS_SLABS_stack_end:
+ return 0;
default:
return -EINVAL;
}
- these = these->next;
- } while(these);
- return 0;
+ ++these;
+ }
}
/*
enum slabnode_item item,
int nodeid)
{
+ /* note: most of the results we might return are actually just
+ unsigned int, but we must accommodate the largest potential
+ result and so return an unsigned long */
if (info == NULL)
return -EINVAL;
return info->nodes[nodeid].nr_active_slabs;
case PROCPS_SLABNODE_USE:
return info->nodes[nodeid].use;
- case PROCPS_SLABNODE_noop:
- return 0;
- // PROCPS_SLABNODE_NAME also invalid in this context
default:
- return -EINVAL;
+ return 0;
}
- return 0;
}
-PROCPS_EXPORT int procps_slabnode_getchain (
+PROCPS_EXPORT int procps_slabnode_getstack (
struct procps_slabinfo *info,
- struct slabnode_result *these,
+ struct slab_result *these,
int nodeid)
{
if (info == NULL || these == NULL)
if (nodeid > info->nodes_used)
return -EINVAL;
- do {
+ for (;;) {
switch (these->item) {
case PROCPS_SLABNODE_SIZE:
- these->result.num = info->nodes[nodeid].cache_size;
+ these->result.ul_int = info->nodes[nodeid].cache_size;
break;
case PROCPS_SLABNODE_OBJS:
- these->result.num = info->nodes[nodeid].nr_objs;
+ these->result.u_int = info->nodes[nodeid].nr_objs;
break;
case PROCPS_SLABNODE_AOBJS:
- these->result.num = info->nodes[nodeid].nr_active_objs;
+ these->result.u_int = info->nodes[nodeid].nr_active_objs;
break;
case PROCPS_SLABNODE_OBJ_SIZE:
- these->result.num = info->nodes[nodeid].obj_size;
+ these->result.u_int = info->nodes[nodeid].obj_size;
break;
case PROCPS_SLABNODE_OBJS_PER_SLAB:
- these->result.num = info->nodes[nodeid].objs_per_slab;
+ these->result.u_int = info->nodes[nodeid].objs_per_slab;
break;
case PROCPS_SLABNODE_PAGES_PER_SLAB:
- these->result.num = info->nodes[nodeid].pages_per_slab;
+ these->result.u_int = info->nodes[nodeid].pages_per_slab;
break;
case PROCPS_SLABNODE_SLABS:
- these->result.num = info->nodes[nodeid].nr_slabs;
+ these->result.u_int = info->nodes[nodeid].nr_slabs;
break;
case PROCPS_SLABNODE_ASLABS:
- these->result.num = info->nodes[nodeid].nr_active_slabs;
+ these->result.u_int = info->nodes[nodeid].nr_active_slabs;
break;
case PROCPS_SLABNODE_USE:
- these->result.num = info->nodes[nodeid].use;
+ these->result.u_int = info->nodes[nodeid].use;
break;
case PROCPS_SLABNODE_NAME:
these->result.str = info->nodes[nodeid].name;
break;
case PROCPS_SLABNODE_noop:
- these->result.num = 0;
+ // don't disturb potential user data in the result struct
break;
+ case PROCPS_SLABNODE_stack_end:
+ return 0;
default:
return -EINVAL;
}
- these = these->next;
- } while(these);
- return 0;
+ ++these;
+ }
}
-PROCPS_EXPORT int procps_slabnode_chain_fill (
+PROCPS_EXPORT int procps_slabnode_stack_fill (
struct procps_slabinfo *info,
- struct slabnode_chain *chain,
+ struct slabnode_stack *stack,
int nodeid)
{
int rc;
- if (info == NULL || chain == NULL || chain->head == NULL)
+ if (info == NULL || stack == NULL || stack->head == NULL)
return -EINVAL;
if ((rc = procps_slabinfo_read(info)) < 0)
return rc;
- return procps_slabnode_getchain(info, chain->head, nodeid);
+ return procps_slabnode_getstack(info, stack->head, nodeid);
}
/*
* Returns: number of nodes in @info or <0 on error
*/
PROCPS_EXPORT int procps_slabnode_count (
- const struct procps_slabinfo *info)
+ struct procps_slabinfo *info)
{
+ int rc = 0;
+
if (!info)
return -EINVAL;
+ if (!info->nodes_used)
+ rc = procps_slabinfo_read(info);
+ if (rc < 0)
+ return rc;
return info->nodes_used;
}
-PROCPS_EXPORT int procps_slabnode_chains_fill (
+PROCPS_EXPORT int procps_slabnode_stacks_fill (
struct procps_slabinfo *info,
- struct slabnode_chain **chains,
- int maxchains)
+ struct slabnode_stack **stacks,
+ int maxstacks)
{
int i, rc;
- if (info == NULL || *chains == NULL)
+ if (info == NULL || *stacks == NULL)
return -EINVAL;
- if (maxchains < 1)
+ if (maxstacks < 1)
return -EINVAL;
if ((rc = procps_slabinfo_read(info)) < 0)
return rc;
- if (maxchains > info->chained->depth)
- maxchains = info->chained->depth;
- if (maxchains > info->nodes_used)
- maxchains = info->nodes_used;
+ if (maxstacks > info->stacked->depth)
+ maxstacks = info->stacked->depth;
+ if (maxstacks > info->nodes_used)
+ maxstacks = info->nodes_used;
- for (i = 0; i < maxchains; i++) {
- if (chains[i] == NULL)
+ for (i = 0; i < maxstacks; i++) {
+ if (stacks[i] == NULL)
break;
- if ((rc = procps_slabnode_getchain(info, chains[i]->head, i) < 0))
+ if ((rc = procps_slabnode_getstack(info, stacks[i]->head, i) < 0))
return rc;
}
- info->chained->inuse = i;
- return info->chained->inuse;
+ info->stacked->inuse = i;
+ return info->stacked->inuse;
}
-static void chains_validate (struct slabnode_chain **v, const char *who)
+static void stacks_validate (struct slabnode_stack **v, const char *who)
{
#if 0
#include <stdio.h>
- int i, x, n = 0;
- struct chain_vectors *p = (struct chain_vectors *)v - 1;
+ int i, t, x, n = 0;
+ struct stack_vectors *p = (struct stack_vectors *)v - 1;
fprintf(stderr, "%s: called by '%s'\n", __func__, who);
fprintf(stderr, "%s: owned by %p (whose self = %p)\n", __func__, p->owner, p->owner->self);
for (x = 0; v[x]; x++) {
- struct slabnode_chain *h = v[x];
- struct slabnode_result *r = h->head;
+ struct slabnode_stack *h = v[x];
+ struct slab_result *r = h->head;
fprintf(stderr, "%s: vector[%02d] = %p", __func__, x, h);
- i = 0;
- do {
- i++;
- r = r->next;
- } while (r);
- fprintf(stderr, ", chain %d found %d elements\n", n, i);
+ for (i = 0; r->item < PROCPS_SLABNODE_stack_end; i++, r++)
+ ;
+ t = i + 1;
+ fprintf(stderr, ", stack %d found %d elements\n", n, i);
++n;
}
- fprintf(stderr, "%s: found %d chain(s)\n", __func__, x);
+ fprintf(stderr, "%s: found %d stack(s), each %d bytes (including eos)\n", __func__, x, (int)sizeof(struct slab_result) * t);
+ fprintf(stderr, "%s: found %d stack(s)\n", __func__, x);
fprintf(stderr, "%s: this header size = %2d\n", __func__, (int)p->owner->header_size);
- fprintf(stderr, "%s: sizeof(struct slabnode_chain) = %2d\n", __func__, (int)sizeof(struct slabnode_chain));
- fprintf(stderr, "%s: sizeof(struct slabnode_result) = %2d\n", __func__, (int)sizeof(struct slabnode_result));
+ fprintf(stderr, "%s: sizeof(struct slabnode_stack) = %2d\n", __func__, (int)sizeof(struct slabnode_stack));
+ fprintf(stderr, "%s: sizeof(struct slab_result) = %2d\n", __func__, (int)sizeof(struct slab_result));
fputc('\n', stderr);
return;
#endif
}
-static struct slabnode_result *chain_make (
- struct slabnode_result *p,
+static struct slab_result *stack_make (
+ struct slab_result *p,
int maxitems,
enum slabnode_item *items)
{
- struct slabnode_result *p_sav = p;
+ struct slab_result *p_sav = p;
int i;
for (i = 0; i < maxitems; i++) {
- if (i > PROCPS_SLABNODE_noop)
- p->item = PROCPS_SLABNODE_noop;
- else
- p->item = items[i];
- p->result.num = 0;
- p->next = p + 1;
+ p->item = items[i];
+ // note: we rely on calloc to initialize actual result
++p;
}
- (--p)->next = NULL;
return p_sav;
}
+static int stack_items_valid (
+ int maxitems,
+ enum slabnode_item *items)
+{
+ int i;
+
+ for (i = 0; i < maxitems; i++) {
+ if (items[i] < PROCPS_SLABNODE_SIZE)
+ return 0;
+ if (items[i] > PROCPS_SLABNODE_stack_end)
+ return 0;
+ }
+ if (items[maxitems -1] != PROCPS_SLABNODE_stack_end)
+ return 0;
+ return 1;
+}
+
/*
- * procps_slabnode_chains_alloc():
+ * procps_slabnode_stacks_alloc():
*
- * Allocate and initialize one or more chains each of which is anchored in an
- * associated meminfo_chain structure (which may include extra user space).
+ * Allocate and initialize one or more stacks each of which is anchored in an
+ * associated slabnode_stack structure (which may include extra user space).
*
- * All such chains will will have their result structures properly primed with
- * 'items' and 'next' pointers, while the result itself will be zeroed.
+ * All such stacks will will have their result structures properly primed with
+ * 'items', while the result itself will be zeroed.
*
- * Returns an array of pointers representing the 'heads' of each new chain.
+ * Returns an array of pointers representing the 'heads' of each new stack.
*/
-PROCPS_EXPORT struct slabnode_chain **procps_slabnode_chains_alloc (
+PROCPS_EXPORT struct slabnode_stack **procps_slabnode_stacks_alloc (
struct procps_slabinfo *info,
- int maxchains,
- int chain_extra,
+ int maxstacks,
+ int stack_extra,
int maxitems,
enum slabnode_item *items)
{
- struct chains_anchor *p_blob;
- struct chain_vectors *p_vect;
- struct slabnode_chain *p_head;
+ struct stacks_anchor *p_blob;
+ struct stack_vectors *p_vect;
+ struct slabnode_stack *p_head;
size_t vect_size, head_size, list_size, blob_size;
void *v_head, *v_list;
int i;
if (info == NULL || items == NULL)
return NULL;
- if (maxchains < 1 || maxitems < 1)
+ if (maxstacks < 1 || maxitems < 1)
+ return NULL;
+ if (!stack_items_valid(maxitems, items))
return NULL;
- vect_size = sizeof(struct chain_vectors); // address vector struct
- vect_size += sizeof(void *) * maxchains; // plus vectors themselves
+ vect_size = sizeof(struct stack_vectors); // address vector struct
+ vect_size += sizeof(void *) * maxstacks; // plus vectors themselves
vect_size += sizeof(void *); // plus NULL delimiter
- head_size = sizeof(struct slabnode_chain) + chain_extra; // a head struct + user stuff
- list_size = sizeof(struct slabnode_result) * maxitems; // a results chain
- blob_size = sizeof(struct chains_anchor); // the anchor itself
+ head_size = sizeof(struct slabnode_stack) + stack_extra; // a head struct + user stuff
+ list_size = sizeof(struct slab_result) * maxitems; // a results stack
+ blob_size = sizeof(struct stacks_anchor); // the anchor itself
blob_size += vect_size; // all vectors + delims
- blob_size += head_size * maxchains; // all head structs + user stuff
- blob_size += list_size * maxchains; // all results chains
+ blob_size += head_size * maxstacks; // all head structs + user stuff
+ blob_size += list_size * maxstacks; // all results stacks
/* note: all memory is allocated in a single blob, facilitating a later free().
as a minimum, it's important that the result structures themselves always be
- contiguous for any given chain (just as they are when defined statically). */
+ contiguous for any given stack (just as they are when defined statically). */
if (NULL == (p_blob = calloc(1, blob_size)))
return NULL;
- p_blob->next = info->chained;
- info->chained = p_blob;
+ p_blob->next = info->stacked;
+ info->stacked = p_blob;
p_blob->self = p_blob;
p_blob->header_size = head_size;
- p_blob->vectors = (void *)p_blob + sizeof(struct chains_anchor);
+ p_blob->vectors = (void *)p_blob + sizeof(struct stacks_anchor);
p_vect = p_blob->vectors;
p_vect->owner = p_blob->self;
- p_vect->heads = (void *)p_vect + sizeof(struct chain_vectors);
+ p_vect->heads = (void *)p_vect + sizeof(struct stack_vectors);
v_head = (void *)p_vect + vect_size;
- v_list = v_head + (head_size * maxchains);
+ v_list = v_head + (head_size * maxstacks);
- for (i = 0; i < maxchains; i++) {
- p_head = (struct slabnode_chain *)v_head;
- p_head->head = chain_make((struct slabnode_result *)v_list, maxitems, items);
+ for (i = 0; i < maxstacks; i++) {
+ p_head = (struct slabnode_stack *)v_head;
+ p_head->head = stack_make((struct slab_result *)v_list, maxitems, items);
p_blob->vectors->heads[i] = p_head;
v_list += list_size;
v_head += head_size;
}
- p_blob->depth = maxchains;
- chains_validate(p_blob->vectors->heads, __func__);
+ p_blob->depth = maxstacks;
+ stacks_validate(p_blob->vectors->heads, __func__);
return p_blob->vectors->heads;
}
/*
- * procps_slabnode_chain_alloc():
+ * procps_slabnode_stack_alloc():
*
- * Allocate and initialize a single result chain under a simplified interface.
+ * Allocate and initialize a single result stack under a simplified interface.
*
- * Such a chain will will have its result structures properly primed with
- * 'items' and 'next' pointers, while the result itself will be zeroed.
+ * Such a stack will will have its result structures properly primed with
+ * 'items', while the result itself will be zeroed.
*
*/
-PROCPS_EXPORT struct slabnode_chain *procps_slabnode_chain_alloc (
+PROCPS_EXPORT struct slabnode_stack *procps_slabnode_stack_alloc (
struct procps_slabinfo *info,
int maxitems,
enum slabnode_item *items)
{
- struct slabnode_chain **v;
+ struct slabnode_stack **v;
if (info == NULL || items == NULL || maxitems < 1)
return NULL;
- v = procps_slabnode_chains_alloc(info, 1, 0, maxitems, items);
+ v = procps_slabnode_stacks_alloc(info, 1, 0, maxitems, items);
if (!v)
return NULL;
- chains_validate(v, __func__);
+ stacks_validate(v, __func__);
return v[0];
}
-static int chains_sort (
- const struct slabnode_chain **A,
- const struct slabnode_chain **B,
+static int stacks_sort (
+ const struct slabnode_stack **A,
+ const struct slabnode_stack **B,
enum slabnode_item *offset)
{
- const struct slabnode_result *a = (*A)->head + *offset;
- const struct slabnode_result *b = (*B)->head + *offset;
+ const struct slab_result *a = (*A)->head + *offset;
+ const struct slab_result *b = (*B)->head + *offset;
// note: everything will be sorted high-to-low
- if (a->item == PROCPS_SLABNODE_NAME)
- return strcoll(a->result.str, b->result.str);
- if ( a->result.num > b->result.num ) return -1;
- if ( a->result.num < b->result.num ) return +1;
+ switch (a->item) {
+ case PROCPS_SLABNODE_noop:
+ case PROCPS_SLABNODE_stack_end:
+ break;
+ case PROCPS_SLABNODE_NAME:
+ return strcoll(a->result.str, b->result.str);
+ case PROCPS_SLABNODE_SIZE:
+ if ( a->result.ul_int > b->result.ul_int ) return -1;
+ if ( a->result.ul_int < b->result.ul_int ) return +1;
+ break;
+ default:
+ if ( a->result.u_int > b->result.u_int ) return -1;
+ if ( a->result.u_int < b->result.u_int ) return +1;
+ break;
+ }
return 0;
}
/*
- * procps_slabnode_chains_sort():
+ * procps_slabnode_stacks_sort():
*
- * Sort chains anchored as 'heads' in the passed slabnode_chain pointers
+ * Sort stacks anchored as 'heads' in the passed slabnode_stack pointers
* array based on the designated sort enumerator.
*
* Returns those same addresses sorted.
*
- * Note: all of the chains must be homogeneous (of equal length and content).
+ * Note: all of the stacks must be homogeneous (of equal length and content).
*/
-PROCPS_EXPORT struct slabnode_chain **procps_slabnode_chains_sort (
+PROCPS_EXPORT struct slabnode_stack **procps_slabnode_stacks_sort (
struct procps_slabinfo *info,
- struct slabnode_chain **chains,
- int numchained,
+ struct slabnode_stack **stacks,
+ int numstacked,
enum slabnode_item sort)
{
#define QSORT_r int (*)(const void *, const void *, void *)
- struct slabnode_result *p = chains[0]->head;
+ struct slab_result *p = stacks[0]->head;
int offset = 0;;
- if (info == NULL || chains == NULL)
+ if (info == NULL || stacks == NULL)
return NULL;
if (sort < 0 || sort > PROCPS_SLABNODE_noop)
return NULL;
- if (numchained > info->chained->depth)
+ if (numstacked > info->stacked->depth)
return NULL;
- if (numchained < 2)
- return chains;
+ if (numstacked < 2)
+ return stacks;
- if (numchained > info->chained->inuse)
- numchained = info->chained->inuse;
+ if (numstacked > info->stacked->inuse)
+ numstacked = info->stacked->inuse;
for (;;) {
if (p->item == sort)
break;
++offset;
- if (!(p = p->next))
+ if (p->item == PROCPS_SLABNODE_stack_end)
return NULL;
+ ++p;
}
- qsort_r(chains, numchained, sizeof(void *), (QSORT_r)chains_sort, &offset);
- return chains;
+ qsort_r(stacks, numstacked, sizeof(void *), (QSORT_r)stacks_sort, &offset);
+ return stacks;
#undef QSORT_r
}
__BEGIN_DECLS
enum slabs_item {
- PROCPS_SLABS_OBJS,
- PROCPS_SLABS_AOBJS,
- PROCPS_SLABS_PAGES,
- PROCPS_SLABS_SLABS,
- PROCPS_SLABS_ASLABS,
- PROCPS_SLABS_CACHES,
- PROCPS_SLABS_ACACHES,
- PROCPS_SLABS_SIZE_AVG,
- PROCPS_SLABS_SIZE_MIN,
- PROCPS_SLABS_SIZE_MAX,
- PROCPS_SLABS_SIZE_TOTAL,
- PROCPS_SLABS_SIZE_ACTIVE,
- PROCPS_SLABS_noop
+ PROCPS_SLABS_OBJS, // u_int
+ PROCPS_SLABS_AOBJS, // u_int
+ PROCPS_SLABS_PAGES, // u_int
+ PROCPS_SLABS_SLABS, // u_int
+ PROCPS_SLABS_ASLABS, // u_int
+ PROCPS_SLABS_CACHES, // u_int
+ PROCPS_SLABS_ACACHES, // u_int
+ PROCPS_SLABS_SIZE_AVG, // u_int
+ PROCPS_SLABS_SIZE_MIN, // u_int
+ PROCPS_SLABS_SIZE_MAX, // u_int
+ PROCPS_SLABS_SIZE_TOTAL, // ul_int
+ PROCPS_SLABS_SIZE_ACTIVE, // ul_int
+ PROCPS_SLABS_noop, // n/a
+ PROCPS_SLABS_stack_end // n/a
};
enum slabnode_item {
- PROCPS_SLABNODE_SIZE,
- PROCPS_SLABNODE_OBJS,
- PROCPS_SLABNODE_AOBJS,
- PROCPS_SLABNODE_OBJ_SIZE,
- PROCPS_SLABNODE_OBJS_PER_SLAB,
- PROCPS_SLABNODE_PAGES_PER_SLAB,
- PROCPS_SLABNODE_SLABS,
- PROCPS_SLABNODE_ASLABS,
- PROCPS_SLABNODE_USE,
- PROCPS_SLABNODE_NAME,
- PROCPS_SLABNODE_noop
+ PROCPS_SLABNODE_SIZE, // ul_int
+ PROCPS_SLABNODE_OBJS, // u_int
+ PROCPS_SLABNODE_AOBJS, // u_int
+ PROCPS_SLABNODE_OBJ_SIZE, // u_int
+ PROCPS_SLABNODE_OBJS_PER_SLAB, // u_int
+ PROCPS_SLABNODE_PAGES_PER_SLAB, // u_int
+ PROCPS_SLABNODE_SLABS, // u_int
+ PROCPS_SLABNODE_ASLABS, // u_int
+ PROCPS_SLABNODE_USE, // u_int
+ PROCPS_SLABNODE_NAME, // str
+ PROCPS_SLABNODE_noop, // n/a
+ PROCPS_SLABNODE_stack_end // n/a
};
struct procps_slabinfo;
-struct slabs_result {
- enum slabs_item item;
- unsigned long result;
- struct slabs_result *next;
+struct slabnode_stack {
+ struct slab_result *head;
};
-struct slabnode_chain {
- struct slabnode_result *head;
-};
-
-struct slabnode_result {
- enum slabnode_item item;
+struct slab_result {
+ int item;
union {
- unsigned long num;
+ unsigned int u_int;
+ unsigned long ul_int;
char *str;
} result;
- struct slabnode_result *next;
};
int procps_slabinfo_new (struct procps_slabinfo **info);
struct procps_slabinfo *info,
enum slabs_item item);
-int procps_slabs_getchain (
+int procps_slabs_getstack (
struct procps_slabinfo *info,
- struct slabs_result *these);
+ struct slab_result *these);
-int procps_slabnode_count (const struct procps_slabinfo *info);
+int procps_slabnode_count (struct procps_slabinfo *info);
const char *procps_slabnode_getname (
struct procps_slabinfo *info,
enum slabnode_item item,
int nodeid);
-int procps_slabnode_getchain (
+int procps_slabnode_getstack (
struct procps_slabinfo *info,
- struct slabnode_result *these,
+ struct slab_result *these,
int nodeid);
-int procps_slabnode_chain_fill (
+int procps_slabnode_stack_fill (
struct procps_slabinfo *info,
- struct slabnode_chain *chain,
+ struct slabnode_stack *stack,
int nodeid);
-int procps_slabnode_chains_fill (
+int procps_slabnode_stacks_fill (
struct procps_slabinfo *info,
- struct slabnode_chain **chains,
- int maxchains);
+ struct slabnode_stack **stacks,
+ int maxstacks);
-struct slabnode_chain *procps_slabnode_chain_alloc (
+struct slabnode_stack *procps_slabnode_stack_alloc (
struct procps_slabinfo *info,
int maxitems,
enum slabnode_item *items);
-struct slabnode_chain **procps_slabnode_chains_alloc (
+struct slabnode_stack **procps_slabnode_stacks_alloc (
struct procps_slabinfo *info,
- int maxchains,
- int chain_extra,
+ int maxstacks,
+ int stack_extra,
int maxitems,
enum slabnode_item *items);
-struct slabnode_chain **procps_slabnode_chains_sort (
+struct slabnode_stack **procps_slabnode_stacks_sort (
struct procps_slabinfo *info,
- struct slabnode_chain **chains,
- int numchained,
+ struct slabnode_stack **stacks,
+ int numstacked,
enum slabnode_item sort);
__END_DECLS
PROCPS_SLABNODE_OBJS, PROCPS_SLABNODE_AOBJS, PROCPS_SLABNODE_USE,
PROCPS_SLABNODE_OBJ_SIZE, PROCPS_SLABNODE_SLABS, PROCPS_SLABNODE_OBJS_PER_SLAB,
PROCPS_SLABNODE_SIZE, PROCPS_SLABNODE_NAME,
- /* last 2 are sortable but are not displayable,
+ /* next 2 are sortable but are not displayable,
thus they need not be represented in the Relative_enums */
- PROCPS_SLABNODE_PAGES_PER_SLAB,
- PROCPS_SLABNODE_ASLABS };
+ PROCPS_SLABNODE_PAGES_PER_SLAB, PROCPS_SLABNODE_ASLABS,
+ PROCPS_SLABNODE_stack_end };
enum Relative_enums {
my_OBJS, my_AOBJS, my_USE, my_OSIZE,
static void print_summary (void)
{
- #define STAT_VAL(e) (int)stats[e].result
enum slabs_enums {
stat_AOBJS, stat_OBJS, stat_ASLABS, stat_SLABS,
stat_ACACHES, stat_CACHES, stat_ACTIVE, stat_TOTAL,
- stat_MIN, stat_AVG, stat_MAX,
+ stat_MIN, stat_AVG, stat_MAX
};
- static struct slabs_result stats[] = {
- { PROCPS_SLABS_AOBJS, 0, &stats[1] },
- { PROCPS_SLABS_OBJS, 0, &stats[2] },
- { PROCPS_SLABS_ASLABS, 0, &stats[3] },
- { PROCPS_SLABS_SLABS, 0, &stats[4] },
- { PROCPS_SLABS_ACACHES, 0, &stats[5] },
- { PROCPS_SLABS_CACHES, 0, &stats[6] },
- { PROCPS_SLABS_SIZE_ACTIVE, 0, &stats[7] },
- { PROCPS_SLABS_SIZE_TOTAL, 0, &stats[8] },
- { PROCPS_SLABS_SIZE_MIN, 0, &stats[9] },
- { PROCPS_SLABS_SIZE_AVG, 0, &stats[10] },
- { PROCPS_SLABS_SIZE_MAX, 0, NULL },
+ static struct slab_result stats[] = {
+ { PROCPS_SLABS_AOBJS, 0 },
+ { PROCPS_SLABS_OBJS, 0 },
+ { PROCPS_SLABS_ASLABS, 0 },
+ { PROCPS_SLABS_SLABS, 0 },
+ { PROCPS_SLABS_ACACHES, 0 },
+ { PROCPS_SLABS_CACHES, 0 },
+ { PROCPS_SLABS_SIZE_ACTIVE, 0 },
+ { PROCPS_SLABS_SIZE_TOTAL, 0 },
+ { PROCPS_SLABS_SIZE_MIN, 0 },
+ { PROCPS_SLABS_SIZE_AVG, 0 },
+ { PROCPS_SLABS_SIZE_MAX, 0 },
+ { PROCPS_SLABS_stack_end, 0 }
};
- if (procps_slabs_getchain(Slab_info, stats) < 0) \
+ if (procps_slabs_getstack(Slab_info, stats) < 0) \
xerrx(EXIT_FAILURE, _("Error getting slab summary results"));
- PRINT_line(" %-35s: %d / %d (%.1f%%)\n"
+ PRINT_line(" %-35s: %u / %u (%.1f%%)\n"
, /* Translation Hint: Next five strings must not
* exceed a length of 35 characters. */
/* xgettext:no-c-format */
_("Active / Total Objects (% used)")
- , STAT_VAL(stat_AOBJS)
- , STAT_VAL(stat_OBJS)
- , 100.0 * STAT_VAL(stat_AOBJS) / STAT_VAL(stat_OBJS));
- PRINT_line(" %-35s: %d / %d (%.1f%%)\n"
+ , stats[stat_AOBJS].result.u_int
+ , stats[stat_OBJS ].result.u_int
+ , 100.0 * stats[stat_AOBJS].result.u_int / stats[stat_OBJS].result.u_int);
+ PRINT_line(" %-35s: %u / %u (%.1f%%)\n"
, /* xgettext:no-c-format */
_("Active / Total Slabs (% used)")
- , STAT_VAL(stat_ASLABS)
- , STAT_VAL(stat_SLABS)
- , 100.0 * STAT_VAL(stat_ASLABS) / STAT_VAL(stat_SLABS));
- PRINT_line(" %-35s: %d / %d (%.1f%%)\n"
+ , stats[stat_ASLABS].result.u_int
+ , stats[stat_SLABS ].result.u_int
+ , 100.0 * stats[stat_ASLABS].result.u_int / stats[stat_SLABS].result.u_int);
+ PRINT_line(" %-35s: %u / %u (%.1f%%)\n"
, /* xgettext:no-c-format */
_("Active / Total Caches (% used)")
- , STAT_VAL(stat_ACACHES)
- , STAT_VAL(stat_CACHES)
- , 100.0 * STAT_VAL(stat_ACACHES) / STAT_VAL(stat_CACHES));
+ , stats[stat_ACACHES].result.u_int
+ , stats[stat_CACHES ].result.u_int
+ , 100.0 * stats[stat_ACACHES].result.u_int / stats[stat_CACHES].result.u_int);
PRINT_line(" %-35s: %.2fK / %.2fK (%.1f%%)\n"
, /* xgettext:no-c-format */
_("Active / Total Size (% used)")
- , STAT_VAL(stat_ACTIVE) / 1024.0
- , STAT_VAL(stat_TOTAL) / 1024.0
- , 100.0 * STAT_VAL(stat_ACTIVE) / STAT_VAL(stat_TOTAL));
+ , stats[stat_ACTIVE].result.ul_int / 1024.0
+ , stats[stat_TOTAL ].result.ul_int / 1024.0
+ , 100.0 * stats[stat_ACTIVE].result.ul_int / stats[stat_TOTAL].result.ul_int);
PRINT_line(" %-35s: %.2fK / %.2fK / %.2fK\n\n"
, _("Minimum / Average / Maximum Object")
- , STAT_VAL(stat_MIN) / 1024.0
- , STAT_VAL(stat_AVG) / 1024.0
- , STAT_VAL(stat_MAX) / 1024.0);
- #undef STAT_VAL
+ , stats[stat_MIN].result.u_int / 1024.0
+ , stats[stat_AVG].result.u_int / 1024.0
+ , stats[stat_MAX].result.u_int / 1024.0);
}
static void print_headings (void)
PRINT_line("%-78s\n", _(" OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME"));
}
-static void print_details (struct slabnode_chain *chain)
+static void print_details (struct slabnode_stack *stack)
{
- #define my_NUM(c,e) (unsigned)c->head[e].result.num
- #define my_STR(c,e) c->head[e].result.str
-
- PRINT_line("%6u %6u %3u%% %7.2fK %6u %8u %9uK %-23s\n"
- , my_NUM(chain, my_OBJS), my_NUM(chain, my_AOBJS)
- , my_NUM(chain, my_USE), my_NUM(chain, my_OSIZE) / 1024.0
- , my_NUM(chain, my_SLABS), my_NUM(chain, my_OPS)
- , my_NUM(chain, my_SIZE) / 1024
- , my_STR(chain, my_NAME));
+ PRINT_line("%6u %6u %3u%% %7.2fK %6u %8u %9luK %-23s\n"
+ , stack->head[my_OBJS ].result.u_int
+ , stack->head[my_AOBJS].result.u_int
+ , stack->head[my_USE ].result.u_int
+ , stack->head[my_OSIZE].result.u_int / 1024.0
+ , stack->head[my_SLABS].result.u_int
+ , stack->head[my_OPS ].result.u_int
+ , stack->head[my_SIZE ].result.ul_int / 1024
+ , stack->head[my_NAME ].result.str);
return;
- #undef my_NUM
- #undef my_STR
}
{
int is_tty, nr_slabs, rc = EXIT_SUCCESS;
unsigned short old_rows;
- struct slabnode_chain **v;
+ struct slabnode_stack **v;
#ifdef HAVE_PROGRAM_INVOCATION_NAME
program_invocation_name = program_invocation_short_name;
if (procps_slabinfo_new(&Slab_info) < 0)
xerrx(EXIT_FAILURE, _("Unable to create slabinfo structure"));
- if (!(v = procps_slabnode_chains_alloc(Slab_info, CHAINS_ALLOC, 0, MAX_ITEMS, Node_items)))
+ if (!(v = procps_slabnode_stacks_alloc(Slab_info, CHAINS_ALLOC, 0, MAX_ITEMS, Node_items)))
xerrx(EXIT_FAILURE, _("Unable to allocate slabinfo nodes"));
if (!Run_once) {
int i;
// this next guy also performs the procps_slabnode_read() call
- if ((nr_slabs = procps_slabnode_chains_fill(Slab_info, v, CHAINS_ALLOC)) < 0) {
+ if ((nr_slabs = procps_slabnode_stacks_fill(Slab_info, v, CHAINS_ALLOC)) < 0) {
xwarn(_("Unable to get slabinfo node data"));
rc = EXIT_FAILURE;
break;
}
- if (!(v = procps_slabnode_chains_sort(Slab_info, v, nr_slabs, Sort_item))) {
+ if (!(v = procps_slabnode_stacks_sort(Slab_info, v, nr_slabs, Sort_item))) {
xwarn(_("Unable to sort slab nodes"));
rc = EXIT_FAILURE;
break;