library: meminfo redesigned to use 'stack' vs. 'chain'
In addition to that text shown below the line which is common to several commit messages, this patch contains the following additional change without an API impact: . The #include header files are ordered alphabetically now, with all those <sys/??> types separately grouped. ------------------------------------------------------ . The former 'chains' have now become 'stacks' without the 'next' pointer in each result struct. The pointers initially seemed to offer some flexibility with memory allocations and benefits for the library access logic. However, user access was always via displacement and a a statically allocated chain was cumbersome to define. . An enumerator ending in '_noop' will no longer serve as a fencepost delimiter. Rather, it has become a much more important and flexible user oriented tool. Adding one or more such 'items' in any items list passed into the library becomes the means of extending the 'stack' to also include user (not just library) data. Any such data is guaranteed to never be altered by the library. . Anticipating PID support, where many different types must be represented in a result structure, we'll adopt a common naming standard. And, while not every results structure currently needs to reflect disparate types a union will be employed so the same dot qualifier ('.') can be used consistently when accessing all such data. Signed-off-by: Jim Warner <james.warner@comcast.net>
This commit is contained in:
parent
887f2a81d7
commit
b8c688fb36
@ -39,9 +39,9 @@ global:
|
|||||||
procps_meminfo_ref;
|
procps_meminfo_ref;
|
||||||
procps_meminfo_unref;
|
procps_meminfo_unref;
|
||||||
procps_meminfo_get;
|
procps_meminfo_get;
|
||||||
procps_meminfo_getchain;
|
procps_meminfo_getstack;
|
||||||
procps_meminfo_chain_fill;
|
procps_meminfo_stack_fill;
|
||||||
procps_meminfo_chain_alloc;
|
procps_meminfo_stack_alloc;
|
||||||
procps_slabinfo_new;
|
procps_slabinfo_new;
|
||||||
procps_slabinfo_read;
|
procps_slabinfo_read;
|
||||||
procps_slabinfo_ref;
|
procps_slabinfo_ref;
|
||||||
|
230
proc/meminfo.c
230
proc/meminfo.c
@ -19,13 +19,15 @@
|
|||||||
* License along with this library; if not, write to the Free Software
|
* License along with this library; if not, write to the Free Software
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <proc/meminfo.h>
|
#include <proc/meminfo.h>
|
||||||
#include "procps-private.h"
|
#include "procps-private.h"
|
||||||
@ -56,20 +58,20 @@ struct procps_meminfo {
|
|||||||
int refcount;
|
int refcount;
|
||||||
int meminfo_fd;
|
int meminfo_fd;
|
||||||
struct meminfo_data data;
|
struct meminfo_data data;
|
||||||
struct chains_anchor *chained;
|
struct stacks_anchor *stacked;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct chain_vectors {
|
struct stack_vectors {
|
||||||
struct chains_anchor *owner;
|
struct stacks_anchor *owner;
|
||||||
struct meminfo_chain **heads;
|
struct meminfo_stack **heads;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct chains_anchor {
|
struct stacks_anchor {
|
||||||
int depth;
|
int depth;
|
||||||
int header_size;
|
int header_size;
|
||||||
struct chain_vectors *vectors;
|
struct stack_vectors *vectors;
|
||||||
struct chains_anchor *self;
|
struct stacks_anchor *self;
|
||||||
struct chains_anchor *next;
|
struct stacks_anchor *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -243,12 +245,12 @@ PROCPS_EXPORT int procps_meminfo_unref (
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
(*info)->refcount--;
|
(*info)->refcount--;
|
||||||
if ((*info)->refcount == 0) {
|
if ((*info)->refcount == 0) {
|
||||||
if ((*info)->chained) {
|
if ((*info)->stacked) {
|
||||||
do {
|
do {
|
||||||
struct chains_anchor *p = (*info)->chained;
|
struct stacks_anchor *p = (*info)->stacked;
|
||||||
(*info)->chained = (*info)->chained->next;
|
(*info)->stacked = (*info)->stacked->next;
|
||||||
free(p);
|
free(p);
|
||||||
} while((*info)->chained);
|
} while((*info)->stacked);
|
||||||
}
|
}
|
||||||
free(*info);
|
free(*info);
|
||||||
*info = NULL;
|
*info = NULL;
|
||||||
@ -307,140 +309,139 @@ PROCPS_EXPORT unsigned long procps_meminfo_get (
|
|||||||
if (info->data.swap_free > info->data.swap_total)
|
if (info->data.swap_free > info->data.swap_total)
|
||||||
return 0;
|
return 0;
|
||||||
return info->data.swap_total - info->data.swap_free;
|
return info->data.swap_total - info->data.swap_free;
|
||||||
case PROCPS_MEM_noop:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PROCPS_EXPORT int procps_meminfo_getchain (
|
PROCPS_EXPORT int procps_meminfo_getstack (
|
||||||
struct procps_meminfo *info,
|
struct procps_meminfo *info,
|
||||||
struct meminfo_result *these)
|
struct meminfo_result *these)
|
||||||
{
|
{
|
||||||
if (info == NULL || these == NULL)
|
if (info == NULL || these == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
do {
|
for (;;) {
|
||||||
switch (these->item) {
|
switch (these->item) {
|
||||||
case PROCPS_MEM_ACTIVE:
|
case PROCPS_MEM_ACTIVE:
|
||||||
these->result = info->data.active;
|
these->result.ul_int = info->data.active;
|
||||||
break;
|
break;
|
||||||
case PROCPS_MEM_INACTIVE:
|
case PROCPS_MEM_INACTIVE:
|
||||||
these->result = info->data.inactive;
|
these->result.ul_int = info->data.inactive;
|
||||||
break;
|
break;
|
||||||
case PROCPS_MEMHI_FREE:
|
case PROCPS_MEMHI_FREE:
|
||||||
these->result = info->data.high_free;
|
these->result.ul_int = info->data.high_free;
|
||||||
break;
|
break;
|
||||||
case PROCPS_MEMHI_TOTAL:
|
case PROCPS_MEMHI_TOTAL:
|
||||||
these->result = info->data.high_total;
|
these->result.ul_int = info->data.high_total;
|
||||||
break;
|
break;
|
||||||
case PROCPS_MEMHI_USED:
|
case PROCPS_MEMHI_USED:
|
||||||
if (info->data.high_free > info->data.high_total)
|
if (info->data.high_free > info->data.high_total)
|
||||||
these->result = 0;
|
these->result.ul_int = 0;
|
||||||
else
|
else
|
||||||
these->result = info->data.high_total - info->data.high_free;
|
these->result.ul_int = info->data.high_total - info->data.high_free;
|
||||||
break;
|
break;
|
||||||
case PROCPS_MEMLO_FREE:
|
case PROCPS_MEMLO_FREE:
|
||||||
these->result = info->data.low_free;
|
these->result.ul_int = info->data.low_free;
|
||||||
break;
|
break;
|
||||||
case PROCPS_MEMLO_TOTAL:
|
case PROCPS_MEMLO_TOTAL:
|
||||||
these->result = info->data.low_total;
|
these->result.ul_int = info->data.low_total;
|
||||||
break;
|
break;
|
||||||
case PROCPS_MEMLO_USED:
|
case PROCPS_MEMLO_USED:
|
||||||
if (info->data.low_free > info->data.low_total)
|
if (info->data.low_free > info->data.low_total)
|
||||||
these->result = 0;
|
these->result.ul_int = 0;
|
||||||
else
|
else
|
||||||
these->result = info->data.low_total - info->data.low_free;
|
these->result.ul_int = info->data.low_total - info->data.low_free;
|
||||||
break;
|
break;
|
||||||
case PROCPS_MEM_AVAILABLE:
|
case PROCPS_MEM_AVAILABLE:
|
||||||
these->result = info->data.available;
|
these->result.ul_int = info->data.available;
|
||||||
break;
|
break;
|
||||||
case PROCPS_MEM_BUFFERS:
|
case PROCPS_MEM_BUFFERS:
|
||||||
these->result = info->data.buffers;
|
these->result.ul_int = info->data.buffers;
|
||||||
break;
|
break;
|
||||||
case PROCPS_MEM_CACHED:
|
case PROCPS_MEM_CACHED:
|
||||||
these->result = info->data.cached;
|
these->result.ul_int = info->data.cached;
|
||||||
break;
|
break;
|
||||||
case PROCPS_MEM_FREE:
|
case PROCPS_MEM_FREE:
|
||||||
these->result = info->data.free;
|
these->result.ul_int = info->data.free;
|
||||||
break;
|
break;
|
||||||
case PROCPS_MEM_SHARED:
|
case PROCPS_MEM_SHARED:
|
||||||
these->result = info->data.shared;
|
these->result.ul_int = info->data.shared;
|
||||||
break;
|
break;
|
||||||
case PROCPS_MEM_TOTAL:
|
case PROCPS_MEM_TOTAL:
|
||||||
these->result = info->data.total;
|
these->result.ul_int = info->data.total;
|
||||||
break;
|
break;
|
||||||
case PROCPS_MEM_USED:
|
case PROCPS_MEM_USED:
|
||||||
these->result = info->data.used;
|
these->result.ul_int = info->data.used;
|
||||||
break;
|
break;
|
||||||
case PROCPS_SWAP_FREE:
|
case PROCPS_SWAP_FREE:
|
||||||
these->result = info->data.swap_free;
|
these->result.ul_int = info->data.swap_free;
|
||||||
break;
|
break;
|
||||||
case PROCPS_SWAP_TOTAL:
|
case PROCPS_SWAP_TOTAL:
|
||||||
these->result = info->data.swap_total;
|
these->result.ul_int = info->data.swap_total;
|
||||||
break;
|
break;
|
||||||
case PROCPS_SWAP_USED:
|
case PROCPS_SWAP_USED:
|
||||||
if (info->data.swap_free > info->data.swap_total)
|
if (info->data.swap_free > info->data.swap_total)
|
||||||
these->result = 0;
|
these->result.ul_int = 0;
|
||||||
else
|
else
|
||||||
these->result = info->data.swap_total - info->data.swap_free;
|
these->result.ul_int = info->data.swap_total - info->data.swap_free;
|
||||||
break;
|
break;
|
||||||
case PROCPS_MEM_noop:
|
case PROCPS_MEM_noop:
|
||||||
|
// don't disturb potential user data in the result struct
|
||||||
break;
|
break;
|
||||||
|
case PROCPS_MEM_stack_end:
|
||||||
|
return 0;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
these = these->next;
|
++these;
|
||||||
} while (these);
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PROCPS_EXPORT int procps_meminfo_chain_fill (
|
PROCPS_EXPORT int procps_meminfo_stack_fill (
|
||||||
struct procps_meminfo *info,
|
struct procps_meminfo *info,
|
||||||
struct meminfo_chain *chain)
|
struct meminfo_stack *stack)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (info == NULL || chain == NULL || chain->head == NULL)
|
if (info == NULL || stack == NULL || stack->head == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if ((rc == procps_meminfo_read(info)) < 0)
|
if ((rc == procps_meminfo_read(info)) < 0)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
return procps_meminfo_getchain(info, chain->head);
|
return procps_meminfo_getstack(info, stack->head);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void chains_validate (struct meminfo_chain **v, const char *who)
|
static void stacks_validate (struct meminfo_stack **v, const char *who)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
int i, x, n = 0;
|
int i, t, x, n = 0;
|
||||||
struct chain_vectors *p = (struct chain_vectors *)v - 1;
|
struct stack_vectors *p = (struct stack_vectors *)v - 1;
|
||||||
|
|
||||||
fprintf(stderr, "%s: called by '%s'\n", __func__, who);
|
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);
|
fprintf(stderr, "%s: owned by %p (whose self = %p)\n", __func__, p->owner, p->owner->self);
|
||||||
for (x = 0; v[x]; x++) {
|
for (x = 0; v[x]; x++) {
|
||||||
struct meminfo_chain *h = v[x];
|
struct meminfo_stack *h = v[x];
|
||||||
struct meminfo_result *r = h->head;
|
struct meminfo_result *r = h->head;
|
||||||
fprintf(stderr, "%s: vector[%02d] = %p", __func__, x, h);
|
fprintf(stderr, "%s: vector[%02d] = %p", __func__, x, h);
|
||||||
i = 0;
|
i = 0;
|
||||||
do {
|
for (i = 0; r->item < PROCPS_MEM_stack_end; i++, r++)
|
||||||
i++;
|
;
|
||||||
r = r->next;
|
t = i + 1;
|
||||||
} while (r);
|
fprintf(stderr, ", stack %d found %d elements\n", n, i);
|
||||||
fprintf(stderr, ", chain %d found %d elements\n", n, i);
|
|
||||||
++n;
|
++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 meminfo_result) * t);
|
||||||
fprintf(stderr, "%s: this header size = %2d\n", __func__, (int)p->owner->header_size);
|
fprintf(stderr, "%s: this header size = %2d\n", __func__, (int)p->owner->header_size);
|
||||||
fprintf(stderr, "%s: sizeof(struct meminfo_chain) = %2d\n", __func__, (int)sizeof(struct meminfo_chain));
|
fprintf(stderr, "%s: sizeof(struct meminfo_stack) = %2d\n", __func__, (int)sizeof(struct meminfo_stack));
|
||||||
fprintf(stderr, "%s: sizeof(struct meminfo_result) = %2d\n", __func__, (int)sizeof(struct meminfo_result));
|
fprintf(stderr, "%s: sizeof(struct meminfo_result) = %2d\n", __func__, (int)sizeof(struct meminfo_result));
|
||||||
fputc('\n', stderr);
|
fputc('\n', stderr);
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct meminfo_result *chain_make (
|
static struct meminfo_result *stack_make (
|
||||||
struct meminfo_result *p,
|
struct meminfo_result *p,
|
||||||
int maxitems,
|
int maxitems,
|
||||||
enum meminfo_item *items)
|
enum meminfo_item *items)
|
||||||
@ -449,105 +450,118 @@ static struct meminfo_result *chain_make (
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < maxitems; i++) {
|
for (i = 0; i < maxitems; i++) {
|
||||||
if (i > PROCPS_MEM_noop)
|
|
||||||
p->item = PROCPS_MEM_noop;
|
|
||||||
else
|
|
||||||
p->item = items[i];
|
p->item = items[i];
|
||||||
p->result = 0;
|
// note: we rely on calloc to initialize actual result
|
||||||
p->next = p + 1;
|
|
||||||
++p;
|
++p;
|
||||||
}
|
}
|
||||||
(--p)->next = NULL;
|
|
||||||
|
|
||||||
return p_sav;
|
return p_sav;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static int stack_items_valid (
|
||||||
* procps_meminfo_chains_alloc():
|
|
||||||
*
|
|
||||||
* A local copy of code borrowed from slab.c to support the public version
|
|
||||||
* representing a single chain. Currently there is no conceivable need
|
|
||||||
* for multiple chains in the 'memory' arena.
|
|
||||||
*/
|
|
||||||
static struct meminfo_chain **procps_meminfo_chains_alloc (
|
|
||||||
struct procps_meminfo *info,
|
|
||||||
int maxchains,
|
|
||||||
int chain_extra,
|
|
||||||
int maxitems,
|
int maxitems,
|
||||||
enum meminfo_item *items)
|
enum meminfo_item *items)
|
||||||
{
|
{
|
||||||
struct chains_anchor *p_blob;
|
int i;
|
||||||
struct chain_vectors *p_vect;
|
|
||||||
struct meminfo_chain *p_head;
|
for (i = 0; i < maxitems; i++) {
|
||||||
|
if (items[i] < PROCPS_MEMHI_FREE)
|
||||||
|
return 0;
|
||||||
|
if (items[i] > PROCPS_MEM_stack_end)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (items[maxitems -1] != PROCPS_MEM_stack_end)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* procps_meminfo_stacks_alloc():
|
||||||
|
*
|
||||||
|
* A local copy of code borrowed from slab.c to support the public version
|
||||||
|
* representing a single stack. Currently there is no conceivable need
|
||||||
|
* for multiple stacks in the 'memory' arena.
|
||||||
|
*/
|
||||||
|
static struct meminfo_stack **procps_meminfo_stacks_alloc (
|
||||||
|
struct procps_meminfo *info,
|
||||||
|
int maxstacks,
|
||||||
|
int stack_extra,
|
||||||
|
int maxitems,
|
||||||
|
enum meminfo_item *items)
|
||||||
|
{
|
||||||
|
struct stacks_anchor *p_blob;
|
||||||
|
struct stack_vectors *p_vect;
|
||||||
|
struct meminfo_stack *p_head;
|
||||||
size_t vect_size, head_size, list_size, blob_size;
|
size_t vect_size, head_size, list_size, blob_size;
|
||||||
void *v_head, *v_list;
|
void *v_head, *v_list;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (info == NULL || items == NULL)
|
if (info == NULL || items == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (maxchains < 1 || maxitems < 1)
|
if (maxstacks < 1 || maxitems < 1)
|
||||||
|
return NULL;
|
||||||
|
if (!stack_items_valid(maxitems, items))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
vect_size = sizeof(struct chain_vectors); // address vector struct
|
vect_size = sizeof(struct stack_vectors); // address vector struct
|
||||||
vect_size += sizeof(void *) * maxchains; // plus vectors themselves
|
vect_size += sizeof(void *) * maxstacks; // plus vectors themselves
|
||||||
vect_size += sizeof(void *); // plus NULL delimiter
|
vect_size += sizeof(void *); // plus NULL delimiter
|
||||||
head_size = sizeof(struct meminfo_chain) + chain_extra; // a head struct + user stuff
|
head_size = sizeof(struct meminfo_stack) + stack_extra; // a head struct + user stuff
|
||||||
list_size = sizeof(struct meminfo_result) * maxitems; // a results chain
|
list_size = sizeof(struct meminfo_result) * maxitems; // a results stack
|
||||||
blob_size = sizeof(struct chains_anchor); // the anchor itself
|
blob_size = sizeof(struct stacks_anchor); // the anchor itself
|
||||||
blob_size += vect_size; // all vectors + delims
|
blob_size += vect_size; // all vectors + delims
|
||||||
blob_size += head_size * maxchains; // all head structs + user stuff
|
blob_size += head_size * maxstacks; // all head structs + user stuff
|
||||||
blob_size += list_size * maxchains; // all results chains
|
blob_size += list_size * maxstacks; // all results stacks
|
||||||
|
|
||||||
/* note: all memory is allocated in a single blob, facilitating a later free().
|
/* 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
|
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)))
|
if (NULL == (p_blob = calloc(1, blob_size)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
p_blob->next = info->chained;
|
p_blob->next = info->stacked;
|
||||||
info->chained = p_blob;
|
info->stacked = p_blob;
|
||||||
p_blob->self = p_blob;
|
p_blob->self = p_blob;
|
||||||
p_blob->header_size = head_size;
|
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 = p_blob->vectors;
|
||||||
p_vect->owner = p_blob->self;
|
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_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++) {
|
for (i = 0; i < maxstacks; i++) {
|
||||||
p_head = (struct meminfo_chain *)v_head;
|
p_head = (struct meminfo_stack *)v_head;
|
||||||
p_head->head = chain_make((struct meminfo_result *)v_list, maxitems, items);
|
p_head->head = stack_make((struct meminfo_result *)v_list, maxitems, items);
|
||||||
p_blob->vectors->heads[i] = p_head;
|
p_blob->vectors->heads[i] = p_head;
|
||||||
v_list += list_size;
|
v_list += list_size;
|
||||||
v_head += head_size;
|
v_head += head_size;
|
||||||
}
|
}
|
||||||
p_blob->depth = maxchains;
|
p_blob->depth = maxstacks;
|
||||||
chains_validate(p_blob->vectors->heads, __func__);
|
stacks_validate(p_blob->vectors->heads, __func__);
|
||||||
return p_blob->vectors->heads;
|
return p_blob->vectors->heads;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* procps_meminfo_chain_alloc():
|
* procps_meminfo_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
|
* Such a stack will will have its result structures properly primed with
|
||||||
* 'items' and 'next' pointers, while the result itself will be zeroed.
|
* 'items', while the result itself will be zeroed.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
PROCPS_EXPORT struct meminfo_chain *procps_meminfo_chain_alloc (
|
PROCPS_EXPORT struct meminfo_stack *procps_meminfo_stack_alloc (
|
||||||
struct procps_meminfo *info,
|
struct procps_meminfo *info,
|
||||||
int maxitems,
|
int maxitems,
|
||||||
enum meminfo_item *items)
|
enum meminfo_item *items)
|
||||||
{
|
{
|
||||||
struct meminfo_chain **v;
|
struct meminfo_stack **v;
|
||||||
|
|
||||||
if (info == NULL || items == NULL || maxitems < 1)
|
v = procps_meminfo_stacks_alloc(info, 1, 0, maxitems, items);
|
||||||
return NULL;
|
|
||||||
v = procps_meminfo_chains_alloc(info, 1, 0, maxitems, items);
|
|
||||||
if (!v)
|
if (!v)
|
||||||
return NULL;
|
return NULL;
|
||||||
chains_validate(v, __func__);
|
stacks_validate(v, __func__);
|
||||||
return v[0];
|
return v[0];
|
||||||
}
|
}
|
||||||
|
@ -28,36 +28,38 @@
|
|||||||
__BEGIN_DECLS
|
__BEGIN_DECLS
|
||||||
|
|
||||||
enum meminfo_item {
|
enum meminfo_item {
|
||||||
PROCPS_MEMHI_FREE,
|
PROCPS_MEMHI_FREE, // ul_int
|
||||||
PROCPS_MEMHI_TOTAL,
|
PROCPS_MEMHI_TOTAL, // ul_int
|
||||||
PROCPS_MEMHI_USED,
|
PROCPS_MEMHI_USED, // ul_int
|
||||||
PROCPS_MEMLO_FREE,
|
PROCPS_MEMLO_FREE, // ul_int
|
||||||
PROCPS_MEMLO_TOTAL,
|
PROCPS_MEMLO_TOTAL, // ul_int
|
||||||
PROCPS_MEMLO_USED,
|
PROCPS_MEMLO_USED, // ul_int
|
||||||
PROCPS_MEM_ACTIVE,
|
PROCPS_MEM_ACTIVE, // ul_int
|
||||||
PROCPS_MEM_AVAILABLE,
|
PROCPS_MEM_AVAILABLE, // ul_int
|
||||||
PROCPS_MEM_BUFFERS,
|
PROCPS_MEM_BUFFERS, // ul_int
|
||||||
PROCPS_MEM_CACHED,
|
PROCPS_MEM_CACHED, // ul_int
|
||||||
PROCPS_MEM_FREE,
|
PROCPS_MEM_FREE, // ul_int
|
||||||
PROCPS_MEM_INACTIVE,
|
PROCPS_MEM_INACTIVE, // ul_int
|
||||||
PROCPS_MEM_SHARED,
|
PROCPS_MEM_SHARED, // ul_int
|
||||||
PROCPS_MEM_TOTAL,
|
PROCPS_MEM_TOTAL, // ul_int
|
||||||
PROCPS_MEM_USED,
|
PROCPS_MEM_USED, // ul_int
|
||||||
PROCPS_SWAP_FREE,
|
PROCPS_SWAP_FREE, // ul_int
|
||||||
PROCPS_SWAP_TOTAL,
|
PROCPS_SWAP_TOTAL, // ul_int
|
||||||
PROCPS_SWAP_USED,
|
PROCPS_SWAP_USED, // ul_int
|
||||||
PROCPS_MEM_noop
|
PROCPS_MEM_noop, // n/a
|
||||||
|
PROCPS_MEM_stack_end // n/a
|
||||||
};
|
};
|
||||||
|
|
||||||
struct procps_meminfo;
|
struct procps_meminfo;
|
||||||
|
|
||||||
struct meminfo_result {
|
struct meminfo_result {
|
||||||
enum meminfo_item item;
|
enum meminfo_item item;
|
||||||
unsigned long result;
|
union {
|
||||||
struct meminfo_result *next;
|
unsigned long ul_int;
|
||||||
|
} result;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct meminfo_chain {
|
struct meminfo_stack {
|
||||||
struct meminfo_result *head;
|
struct meminfo_result *head;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -72,15 +74,15 @@ unsigned long procps_meminfo_get (
|
|||||||
struct procps_meminfo *info,
|
struct procps_meminfo *info,
|
||||||
enum meminfo_item item);
|
enum meminfo_item item);
|
||||||
|
|
||||||
int procps_meminfo_getchain (
|
int procps_meminfo_getstack (
|
||||||
struct procps_meminfo *info,
|
struct procps_meminfo *info,
|
||||||
struct meminfo_result *these);
|
struct meminfo_result *these);
|
||||||
|
|
||||||
int procps_meminfo_chain_fill (
|
int procps_meminfo_stack_fill (
|
||||||
struct procps_meminfo *info,
|
struct procps_meminfo *info,
|
||||||
struct meminfo_chain *chain);
|
struct meminfo_stack *stack);
|
||||||
|
|
||||||
struct meminfo_chain *procps_meminfo_chain_alloc (
|
struct meminfo_stack *procps_meminfo_stack_alloc (
|
||||||
struct procps_meminfo *info,
|
struct procps_meminfo *info,
|
||||||
int maxitems,
|
int maxitems,
|
||||||
enum meminfo_item *items);
|
enum meminfo_item *items);
|
||||||
|
13
top/top.c
13
top/top.c
@ -252,16 +252,17 @@ static const char Graph_bars[] = "||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||
/* Support for the new library API -- acquired (if necessary)
|
/* Support for the new library API -- acquired (if necessary)
|
||||||
at program startup and referenced throughout our lifetime */
|
at program startup and referenced throughout our lifetime */
|
||||||
static struct procps_meminfo *Mem_ctx;
|
static struct procps_meminfo *Mem_ctx;
|
||||||
static struct meminfo_chain *Mem_chain;
|
static struct meminfo_stack *Mem_stack;
|
||||||
static enum meminfo_item Mem_items[] = {
|
static enum meminfo_item Mem_items[] = {
|
||||||
PROCPS_MEM_FREE, PROCPS_MEM_USED, PROCPS_MEM_TOTAL,
|
PROCPS_MEM_FREE, PROCPS_MEM_USED, PROCPS_MEM_TOTAL,
|
||||||
PROCPS_MEM_CACHED, PROCPS_MEM_BUFFERS, PROCPS_MEM_AVAILABLE,
|
PROCPS_MEM_CACHED, PROCPS_MEM_BUFFERS, PROCPS_MEM_AVAILABLE,
|
||||||
PROCPS_SWAP_TOTAL, PROCPS_SWAP_FREE, PROCPS_SWAP_USED };
|
PROCPS_SWAP_TOTAL, PROCPS_SWAP_FREE, PROCPS_SWAP_USED,
|
||||||
|
PROCPS_MEM_stack_end };
|
||||||
enum Rel_items {
|
enum Rel_items {
|
||||||
mem_FREE, mem_USED, mem_TOTAL, mem_CACHE, mem_BUFFS,
|
mem_FREE, mem_USED, mem_TOTAL, mem_CACHE, mem_BUFFS,
|
||||||
mem_AVAIL, swp_TOTAL, swp_FREE, swp_USED
|
mem_AVAIL, swp_TOTAL, swp_FREE, swp_USED
|
||||||
};
|
};
|
||||||
#define MEM_VAL(e) Mem_chain->head[e].result
|
#define MEM_VAL(e) Mem_stack->head[e].result.ul_int
|
||||||
|
|
||||||
static struct procps_stat *Cpu_ctx;
|
static struct procps_stat *Cpu_ctx;
|
||||||
static struct procps_jiffs_hist *Cpu_jiffs;
|
static struct procps_jiffs_hist *Cpu_jiffs;
|
||||||
@ -2663,8 +2664,8 @@ static void sysinfo_refresh (int forced) {
|
|||||||
|
|
||||||
/*** hotplug_acclimated ***/
|
/*** hotplug_acclimated ***/
|
||||||
if (3 <= cur_secs - mem_secs) {
|
if (3 <= cur_secs - mem_secs) {
|
||||||
// 'chain_fill' also implies 'read', saving us one more call
|
// 'stack_fill' also implies 'read', saving us one more call
|
||||||
if ((procps_meminfo_chain_fill(Mem_ctx, Mem_chain) < 0))
|
if ((procps_meminfo_stack_fill(Mem_ctx, Mem_stack) < 0))
|
||||||
error_exit(N_txt(LIB_errormem_txt));
|
error_exit(N_txt(LIB_errormem_txt));
|
||||||
mem_secs = cur_secs;
|
mem_secs = cur_secs;
|
||||||
}
|
}
|
||||||
@ -3265,7 +3266,7 @@ static void before (char *me) {
|
|||||||
// prepare for new library API ...
|
// prepare for new library API ...
|
||||||
if (procps_meminfo_new(&Mem_ctx) < 0)
|
if (procps_meminfo_new(&Mem_ctx) < 0)
|
||||||
error_exit(N_txt(LIB_errormem_txt));
|
error_exit(N_txt(LIB_errormem_txt));
|
||||||
if (!(Mem_chain = procps_meminfo_chain_alloc(Mem_ctx, MAXTBL(Mem_items), Mem_items)))
|
if (!(Mem_stack = procps_meminfo_stack_alloc(Mem_ctx, MAXTBL(Mem_items), Mem_items)))
|
||||||
error_exit(N_txt(LIB_errormem_txt));
|
error_exit(N_txt(LIB_errormem_txt));
|
||||||
if (procps_stat_new(&Cpu_ctx) < 0)
|
if (procps_stat_new(&Cpu_ctx) < 0)
|
||||||
error_exit(N_txt(LIB_errorcpu_txt));
|
error_exit(N_txt(LIB_errorcpu_txt));
|
||||||
|
Loading…
Reference in New Issue
Block a user