forked from Mirror/frr
[lib/memory] Add mallinfo support
2006-02-15 Paul Jakma <paul.jakma@sun.com> * configure.ac: Check for mallinfo, being careful to link test so we can detect things like umem being used (which doesn't provide a mallinfo). * lib/memory.c: (mtype_memstr) new helper function to return human friendly string for a byte count. (mtype_stats_alloc) new function, for users to retrieve number of objects allocated. (show_memory_mallinfo) New function, show mallinfo statistics if available. (show_memory_all_cmd) Call show_memory_mallinfo, if mallinfo is available. * lib/memory.h: Export mtype_memstr and mtype_stats_alloc. Provide a define for a reasonable buffer size for mtype_memstr.
This commit is contained in:
parent
b5b628c1fa
commit
41be32bfe6
|
@ -1,3 +1,9 @@
|
||||||
|
2006-02-15 Paul Jakma <paul.jakma@sun.com>
|
||||||
|
|
||||||
|
* configure.ac: Check for mallinfo, being careful to link test
|
||||||
|
so we can detect things like umem being used (which doesn't
|
||||||
|
provide a mallinfo).
|
||||||
|
|
||||||
2006-01-31 Paul Jakma <paul.jakma@sun.com>
|
2006-01-31 Paul Jakma <paul.jakma@sun.com>
|
||||||
|
|
||||||
* configure.ac: Cleanup the hideous {net,ucd}-snmp section
|
* configure.ac: Cleanup the hideous {net,ucd}-snmp section
|
||||||
|
|
20
configure.ac
20
configure.ac
|
@ -5,7 +5,7 @@
|
||||||
## Copyright (c) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
|
## Copyright (c) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
|
||||||
## Portions Copyright (c) 2003 Paul Jakma <paul@dishone.st>
|
## Portions Copyright (c) 2003 Paul Jakma <paul@dishone.st>
|
||||||
##
|
##
|
||||||
## $Id: configure.ac,v 1.118 2006/01/31 10:09:27 paul Exp $
|
## $Id: configure.ac,v 1.119 2006/03/30 13:53:59 paul Exp $
|
||||||
AC_PREREQ(2.53)
|
AC_PREREQ(2.53)
|
||||||
|
|
||||||
AC_INIT(Quagga, 0.99.3, [http://bugzilla.quagga.net])
|
AC_INIT(Quagga, 0.99.3, [http://bugzilla.quagga.net])
|
||||||
|
@ -1236,6 +1236,24 @@ if test x"${ac_cv_header_execinfo_h}" = x"yes"; then
|
||||||
)
|
)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
dnl -----------------------------------------
|
||||||
|
dnl check for malloc mallinfo struct and call
|
||||||
|
dnl this must try and link using LIBS, in
|
||||||
|
dnl order to check no alternative allocator
|
||||||
|
dnl has been specified, which might not provide
|
||||||
|
dnl mallinfo, e.g. such as Umem on Solaris.
|
||||||
|
dnl -----------------------------------------
|
||||||
|
AC_CHECK_HEADERS(malloc.h,
|
||||||
|
[AC_MSG_CHECKING(whether mallinfo is available)
|
||||||
|
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <malloc.h>]],
|
||||||
|
[[struct mallinfo ac_x; ac_x = mallinfo ();]])],
|
||||||
|
[AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_MALLINFO,,mallinfo)],
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
dnl ----------
|
dnl ----------
|
||||||
dnl configure date
|
dnl configure date
|
||||||
dnl ----------
|
dnl ----------
|
||||||
|
|
|
@ -1,3 +1,17 @@
|
||||||
|
2006-03-15 Paul Jakma <paul.jakma@sun.com>
|
||||||
|
|
||||||
|
* memory.c: (mtype_memstr) new helper function to
|
||||||
|
return human friendly string for a byte count.
|
||||||
|
(mtype_stats_alloc) new function, for users to retrieve
|
||||||
|
number of objects allocated.
|
||||||
|
(show_memory_mallinfo) New function, show mallinfo statistics
|
||||||
|
if available.
|
||||||
|
(show_memory_all_cmd) Call show_memory_mallinfo, if mallinfo
|
||||||
|
is available.
|
||||||
|
* memory.h: Export mtype_memstr and mtype_stats_alloc.
|
||||||
|
Provide a define for a reasonable buffer size for
|
||||||
|
mtype_memstr.
|
||||||
|
|
||||||
2006-03-14 Paul Jakma <paul.jakma@sun.com>
|
2006-03-14 Paul Jakma <paul.jakma@sun.com>
|
||||||
|
|
||||||
* privs.c: (zprivs_caps_init) Change user IDs before lowering
|
* privs.c: (zprivs_caps_init) Change user IDs before lowering
|
||||||
|
|
115
lib/memory.c
115
lib/memory.c
|
@ -21,6 +21,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <zebra.h>
|
#include <zebra.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
@ -278,6 +279,47 @@ show_memory_vty (struct vty *vty, struct memory_list *list)
|
||||||
return needsep;
|
return needsep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_MALLINFO
|
||||||
|
static int
|
||||||
|
show_memory_mallinfo (struct vty *vty)
|
||||||
|
{
|
||||||
|
struct mallinfo minfo = mallinfo();
|
||||||
|
char buf[MTYPE_MEMSTR_LEN];
|
||||||
|
|
||||||
|
vty_out (vty, "System allocator statistics:%s", VTY_NEWLINE);
|
||||||
|
vty_out (vty, " Total heap allocated: %s%s",
|
||||||
|
mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.arena),
|
||||||
|
VTY_NEWLINE);
|
||||||
|
vty_out (vty, " Holding block headers: %s%s",
|
||||||
|
mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.hblkhd),
|
||||||
|
VTY_NEWLINE);
|
||||||
|
vty_out (vty, " Used small blocks: %s%s",
|
||||||
|
mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.usmblks),
|
||||||
|
VTY_NEWLINE);
|
||||||
|
vty_out (vty, " Used ordinary blocks: %s%s",
|
||||||
|
mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.uordblks),
|
||||||
|
VTY_NEWLINE);
|
||||||
|
vty_out (vty, " Free small blocks: %s%s",
|
||||||
|
mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.fsmblks),
|
||||||
|
VTY_NEWLINE);
|
||||||
|
vty_out (vty, " Free ordinary blocks: %s%s",
|
||||||
|
mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.fordblks),
|
||||||
|
VTY_NEWLINE);
|
||||||
|
vty_out (vty, " Ordinary blocks: %ld%s",
|
||||||
|
(unsigned long)minfo.ordblks,
|
||||||
|
VTY_NEWLINE);
|
||||||
|
vty_out (vty, " Small blocks: %ld%s",
|
||||||
|
(unsigned long)minfo.smblks,
|
||||||
|
VTY_NEWLINE);
|
||||||
|
vty_out (vty, " Holding blocks: %ld%s",
|
||||||
|
(unsigned long)minfo.hblks,
|
||||||
|
VTY_NEWLINE);
|
||||||
|
vty_out (vty, "(see system documentation for 'mallinfo' for meaning)%s",
|
||||||
|
VTY_NEWLINE);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_MALLINFO */
|
||||||
|
|
||||||
DEFUN (show_memory_all,
|
DEFUN (show_memory_all,
|
||||||
show_memory_all_cmd,
|
show_memory_all_cmd,
|
||||||
"show memory all",
|
"show memory all",
|
||||||
|
@ -288,6 +330,10 @@ DEFUN (show_memory_all,
|
||||||
struct mlist *ml;
|
struct mlist *ml;
|
||||||
int needsep = 0;
|
int needsep = 0;
|
||||||
|
|
||||||
|
#ifdef HAVE_MALLINFO
|
||||||
|
needsep = show_memory_mallinfo (vty);
|
||||||
|
#endif /* HAVE_MALLINFO */
|
||||||
|
|
||||||
for (ml = mlists; ml->list; ml++)
|
for (ml = mlists; ml->list; ml++)
|
||||||
{
|
{
|
||||||
if (needsep)
|
if (needsep)
|
||||||
|
@ -416,3 +462,72 @@ memory_init (void)
|
||||||
install_element (ENABLE_NODE, &show_memory_ospf6_cmd);
|
install_element (ENABLE_NODE, &show_memory_ospf6_cmd);
|
||||||
install_element (ENABLE_NODE, &show_memory_isis_cmd);
|
install_element (ENABLE_NODE, &show_memory_isis_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Stats querying from users */
|
||||||
|
/* Return a pointer to a human friendly string describing
|
||||||
|
* the byte count passed in. E.g:
|
||||||
|
* "0 bytes", "2048 bytes", "110kB", "500MiB", "11GiB", etc.
|
||||||
|
* Up to 4 significant figures will be given.
|
||||||
|
* The pointer returned may be NULL (indicating an error)
|
||||||
|
* or point to the given buffer, or point to static storage.
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
mtype_memstr (char *buf, size_t len, unsigned long bytes)
|
||||||
|
{
|
||||||
|
unsigned int t, g, m, k;
|
||||||
|
|
||||||
|
/* easy cases */
|
||||||
|
if (!bytes)
|
||||||
|
return "0 bytes";
|
||||||
|
if (bytes == 1)
|
||||||
|
return "1 byte";
|
||||||
|
|
||||||
|
if (sizeof (unsigned long) >= 8)
|
||||||
|
/* Hacked to make it not warn on ILP32 machines
|
||||||
|
* Shift will always be 40 at runtime. See below too */
|
||||||
|
t = bytes >> (sizeof (unsigned long) >= 8 ? 40 : 0);
|
||||||
|
else
|
||||||
|
t = 0;
|
||||||
|
g = bytes >> 30;
|
||||||
|
m = bytes >> 20;
|
||||||
|
k = bytes >> 10;
|
||||||
|
|
||||||
|
if (t > 10)
|
||||||
|
{
|
||||||
|
/* The shift will always be 39 at runtime.
|
||||||
|
* Just hacked to make it not warn on 'smaller' machines.
|
||||||
|
* Static compiler analysis should mean no extra code
|
||||||
|
*/
|
||||||
|
if (bytes & (1 << (sizeof (unsigned long) >= 8 ? 39 : 0)))
|
||||||
|
t++;
|
||||||
|
snprintf (buf, len, "%4d TiB", t);
|
||||||
|
}
|
||||||
|
else if (g > 10)
|
||||||
|
{
|
||||||
|
if (bytes & (1 << 29))
|
||||||
|
g++;
|
||||||
|
snprintf (buf, len, "%d GiB", g);
|
||||||
|
}
|
||||||
|
else if (m > 10)
|
||||||
|
{
|
||||||
|
if (bytes & (1 << 19))
|
||||||
|
m++;
|
||||||
|
snprintf (buf, len, "%d MiB", m);
|
||||||
|
}
|
||||||
|
else if (k > 10)
|
||||||
|
{
|
||||||
|
if (bytes & (1 << 9))
|
||||||
|
k++;
|
||||||
|
snprintf (buf, len, "%d KiB", k);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
snprintf (buf, len, "%ld bytes", bytes);
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long
|
||||||
|
mtype_stats_alloc (int type)
|
||||||
|
{
|
||||||
|
return mstat[type].alloc;
|
||||||
|
}
|
||||||
|
|
|
@ -79,4 +79,10 @@ extern char *mtype_zstrdup (const char *file, int line, int type,
|
||||||
const char *str);
|
const char *str);
|
||||||
extern void memory_init (void);
|
extern void memory_init (void);
|
||||||
|
|
||||||
|
/* return number of allocations outstanding for the type */
|
||||||
|
extern unsigned long mtype_stats_alloc (int);
|
||||||
|
|
||||||
|
/* Human friendly string for given byte count */
|
||||||
|
#define MTYPE_MEMSTR_LEN 20
|
||||||
|
extern const char *mtype_memstr (char *, size_t, unsigned long);
|
||||||
#endif /* _ZEBRA_MEMORY_H */
|
#endif /* _ZEBRA_MEMORY_H */
|
||||||
|
|
Loading…
Reference in a new issue