LCOV - code coverage report
Current view: top level - lib - memory.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 65 209 31.1 %
Date: 2015-11-19 Functions: 8 26 30.8 %

          Line data    Source code
       1             : /*
       2             :  * Memory management routine
       3             :  * Copyright (C) 1998 Kunihiro Ishiguro
       4             :  *
       5             :  * This file is part of GNU Zebra.
       6             :  *
       7             :  * GNU Zebra is free software; you can redistribute it and/or modify it
       8             :  * under the terms of the GNU General Public License as published by the
       9             :  * Free Software Foundation; either version 2, or (at your option) any
      10             :  * later version.
      11             :  *
      12             :  * GNU Zebra is distributed in the hope that it will be useful, but
      13             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15             :  * General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU General Public License
      18             :  * along with GNU Zebra; see the file COPYING.  If not, write to the Free
      19             :  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
      20             :  * 02111-1307, USA.  
      21             :  */
      22             : 
      23             : #include <zebra.h>
      24             : /* malloc.h is generally obsolete, however GNU Libc mallinfo wants it. */
      25             : #if !defined(HAVE_STDLIB_H) || (defined(GNU_LINUX) && defined(HAVE_MALLINFO))
      26             : #include <malloc.h>
      27             : #endif /* !HAVE_STDLIB_H || HAVE_MALLINFO */
      28             : 
      29             : #include "log.h"
      30             : #include "memory.h"
      31             : 
      32             : static void alloc_inc (int);
      33             : static void alloc_dec (int);
      34             : static void log_memstats(int log_priority);
      35             : 
      36             : static const struct message mstr [] =
      37             : {
      38             :   { MTYPE_THREAD, "thread" },
      39             :   { MTYPE_THREAD_MASTER, "thread_master" },
      40             :   { MTYPE_VECTOR, "vector" },
      41             :   { MTYPE_VECTOR_INDEX, "vector_index" },
      42             :   { MTYPE_IF, "interface" },
      43             :   { 0, NULL },
      44             : };
      45             : 
      46             : /* Fatal memory allocation error occured. */
      47             : static void __attribute__ ((noreturn))
      48           0 : zerror (const char *fname, int type, size_t size)
      49             : {
      50           0 :   zlog_err ("%s : can't allocate memory for `%s' size %d: %s\n", 
      51           0 :             fname, lookup (mstr, type), (int) size, safe_strerror(errno));
      52           0 :   log_memstats(LOG_WARNING);
      53             :   /* N.B. It might be preferable to call zlog_backtrace_sigsafe here, since
      54             :      that function should definitely be safe in an OOM condition.  But
      55             :      unfortunately zlog_backtrace_sigsafe does not support syslog logging at
      56             :      this time... */
      57           0 :   zlog_backtrace(LOG_WARNING);
      58           0 :   abort();
      59             : }
      60             : 
      61             : /*
      62             :  * Allocate memory of a given size, to be tracked by a given type.
      63             :  * Effects: Returns a pointer to usable memory.  If memory cannot
      64             :  * be allocated, aborts execution.
      65             :  */
      66             : void *
      67      220777 : zmalloc (int type, size_t size)
      68             : {
      69             :   void *memory;
      70             : 
      71      220777 :   memory = malloc (size);
      72             : 
      73      220777 :   if (memory == NULL)
      74           0 :     zerror ("malloc", type, size);
      75             : 
      76      220777 :   alloc_inc (type);
      77             : 
      78      220777 :   return memory;
      79             : }
      80             : 
      81             : /*
      82             :  * Allocate memory as in zmalloc, and also clear the memory.
      83             :  */
      84             : void *
      85      238503 : zcalloc (int type, size_t size)
      86             : {
      87             :   void *memory;
      88             : 
      89      238503 :   memory = calloc (1, size);
      90             : 
      91      238503 :   if (memory == NULL)
      92           0 :     zerror ("calloc", type, size);
      93             : 
      94      238503 :   alloc_inc (type);
      95             : 
      96      238503 :   return memory;
      97             : }
      98             : 
      99             : /* 
     100             :  * Given a pointer returned by zmalloc or zcalloc, free it and
     101             :  * return a pointer to a new size, basically acting like realloc().
     102             :  * Requires: ptr was returned by zmalloc, zcalloc, or zrealloc with the
     103             :  * same type.
     104             :  * Effects: Returns a pointer to the new memory, or aborts.
     105             :  */
     106             : void *
     107       74769 : zrealloc (int type, void *ptr, size_t size)
     108             : {
     109             :   void *memory;
     110             : 
     111       74769 :   memory = realloc (ptr, size);
     112       74769 :   if (memory == NULL)
     113           0 :     zerror ("realloc", type, size);
     114       74769 :   if (ptr == NULL)
     115         155 :     alloc_inc (type);
     116             : 
     117       74769 :   return memory;
     118             : }
     119             : 
     120             : /*
     121             :  * Free memory allocated by z*alloc or zstrdup.
     122             :  * Requires: ptr was returned by zmalloc, zcalloc, or zrealloc with the
     123             :  * same type.
     124             :  * Effects: The memory is freed and may no longer be referenced.
     125             :  */
     126             : void
     127       57111 : zfree (int type, void *ptr)
     128             : {
     129       57111 :   if (ptr != NULL)
     130             :     {
     131       56481 :       alloc_dec (type);
     132       56481 :       free (ptr);
     133             :     }
     134       57111 : }
     135             : 
     136             : /*
     137             :  * Duplicate a string, counting memory usage by type.
     138             :  * Effects: The string is duplicated, and the return value must
     139             :  * eventually be passed to zfree with the same type.  The function will
     140             :  * succeed or abort.
     141             :  */
     142             : char *
     143         840 : zstrdup (int type, const char *str)
     144             : {
     145             :   void *dup;
     146             : 
     147         840 :   dup = strdup (str);
     148         840 :   if (dup == NULL)
     149           0 :     zerror ("strdup", type, strlen (str));
     150         840 :   alloc_inc (type);
     151         840 :   return dup;
     152             : }
     153             : 
     154             : #ifdef MEMORY_LOG
     155             : static struct 
     156             : {
     157             :   const char *name;
     158             :   long alloc;
     159             :   unsigned long t_malloc;
     160             :   unsigned long c_malloc;
     161             :   unsigned long t_calloc;
     162             :   unsigned long c_calloc;
     163             :   unsigned long t_realloc;
     164             :   unsigned long t_free;
     165             :   unsigned long c_strdup;
     166             : } mstat [MTYPE_MAX];
     167             : 
     168             : static void
     169             : mtype_log (char *func, void *memory, const char *file, int line, int type)
     170             : {
     171             :   zlog_debug ("%s: %s %p %s %d", func, lookup (mstr, type), memory, file, line);
     172             : }
     173             : 
     174             : void *
     175             : mtype_zmalloc (const char *file, int line, int type, size_t size)
     176             : {
     177             :   void *memory;
     178             : 
     179             :   mstat[type].c_malloc++;
     180             :   mstat[type].t_malloc++;
     181             : 
     182             :   memory = zmalloc (type, size);
     183             :   mtype_log ("zmalloc", memory, file, line, type);
     184             : 
     185             :   return memory;
     186             : }
     187             : 
     188             : void *
     189             : mtype_zcalloc (const char *file, int line, int type, size_t size)
     190             : {
     191             :   void *memory;
     192             : 
     193             :   mstat[type].c_calloc++;
     194             :   mstat[type].t_calloc++;
     195             : 
     196             :   memory = zcalloc (type, size);
     197             :   mtype_log ("xcalloc", memory, file, line, type);
     198             : 
     199             :   return memory;
     200             : }
     201             : 
     202             : void *
     203             : mtype_zrealloc (const char *file, int line, int type, void *ptr, size_t size)
     204             : {
     205             :   void *memory;
     206             : 
     207             :   /* Realloc need before allocated pointer. */
     208             :   mstat[type].t_realloc++;
     209             : 
     210             :   memory = zrealloc (type, ptr, size);
     211             : 
     212             :   mtype_log ("xrealloc", memory, file, line, type);
     213             : 
     214             :   return memory;
     215             : }
     216             : 
     217             : /* Important function. */
     218             : void 
     219             : mtype_zfree (const char *file, int line, int type, void *ptr)
     220             : {
     221             :   mstat[type].t_free++;
     222             : 
     223             :   mtype_log ("xfree", ptr, file, line, type);
     224             : 
     225             :   zfree (type, ptr);
     226             : }
     227             : 
     228             : char *
     229             : mtype_zstrdup (const char *file, int line, int type, const char *str)
     230             : {
     231             :   char *memory;
     232             : 
     233             :   mstat[type].c_strdup++;
     234             : 
     235             :   memory = zstrdup (type, str);
     236             :   
     237             :   mtype_log ("xstrdup", memory, file, line, type);
     238             : 
     239             :   return memory;
     240             : }
     241             : #else
     242             : static struct 
     243             : {
     244             :   char *name;
     245             :   long alloc;
     246             : } mstat [MTYPE_MAX];
     247             : #endif /* MEMORY_LOG */
     248             : 
     249             : /* Increment allocation counter. */
     250             : static void
     251      460275 : alloc_inc (int type)
     252             : {
     253      460275 :   mstat[type].alloc++;
     254      460275 : }
     255             : 
     256             : /* Decrement allocation counter. */
     257             : static void
     258       56481 : alloc_dec (int type)
     259             : {
     260       56481 :   mstat[type].alloc--;
     261       56481 : }
     262             : 
     263             : /* Looking up memory status from vty interface. */
     264             : #include "vector.h"
     265             : #include "vty.h"
     266             : #include "command.h"
     267             : 
     268             : static void
     269           0 : log_memstats(int pri)
     270             : {
     271             :   struct mlist *ml;
     272             : 
     273           0 :   for (ml = mlists; ml->list; ml++)
     274             :     {
     275             :       struct memory_list *m;
     276             : 
     277           0 :       zlog (NULL, pri, "Memory utilization in module %s:", ml->name);
     278           0 :       for (m = ml->list; m->index >= 0; m++)
     279           0 :         if (m->index && mstat[m->index].alloc)
     280           0 :           zlog (NULL, pri, "  %-30s: %10ld", m->format, mstat[m->index].alloc);
     281             :     }
     282           0 : }
     283             : 
     284             : void
     285           0 : log_memstats_stderr (const char *prefix)
     286             : {
     287             :   struct mlist *ml;
     288             :   struct memory_list *m;
     289             :   int i;
     290           0 :   int j = 0;
     291             : 
     292           0 :   for (ml = mlists; ml->list; ml++)
     293             :     {
     294           0 :       i = 0;
     295             : 
     296           0 :       for (m = ml->list; m->index >= 0; m++)
     297           0 :         if (m->index && mstat[m->index].alloc)
     298             :           {
     299           0 :             if (!i)
     300           0 :               fprintf (stderr,
     301             :                        "%s: memstats: Current memory utilization in module %s:\n",
     302             :                        prefix,
     303             :                        ml->name);
     304           0 :             fprintf (stderr,
     305             :                      "%s: memstats:  %-30s: %10ld%s\n",
     306             :                      prefix,
     307             :                      m->format,
     308           0 :                      mstat[m->index].alloc,
     309           0 :                      mstat[m->index].alloc < 0 ? " (REPORT THIS BUG!)" : "");
     310           0 :             i = j = 1;
     311             :           }
     312             :     }
     313             : 
     314           0 :   if (j)
     315           0 :     fprintf (stderr,
     316             :              "%s: memstats: NOTE: If configuration exists, utilization may be "
     317             :              "expected.\n",
     318             :              prefix);
     319             :   else
     320           0 :     fprintf (stderr,
     321             :              "%s: memstats: No remaining tracked memory utilization.\n",
     322             :              prefix);
     323           0 : }
     324             : 
     325             : static void
     326           0 : show_separator(struct vty *vty)
     327             : {
     328           0 :   vty_out (vty, "-----------------------------\r\n");
     329           0 : }
     330             : 
     331             : static int
     332           0 : show_memory_vty (struct vty *vty, struct memory_list *list)
     333             : {
     334             :   struct memory_list *m;
     335           0 :   int needsep = 0;
     336             : 
     337           0 :   for (m = list; m->index >= 0; m++)
     338           0 :     if (m->index == 0)
     339             :       {
     340           0 :         if (needsep)
     341             :           {
     342           0 :             show_separator (vty);
     343           0 :             needsep = 0;
     344             :           }
     345             :       }
     346           0 :     else if (mstat[m->index].alloc)
     347             :       {
     348           0 :         vty_out (vty, "%-30s: %10ld\r\n", m->format, mstat[m->index].alloc);
     349           0 :         needsep = 1;
     350             :       }
     351           0 :   return needsep;
     352             : }
     353             : 
     354             : #ifdef HAVE_MALLINFO
     355             : static int
     356           0 : show_memory_mallinfo (struct vty *vty)
     357             : {
     358           0 :   struct mallinfo minfo = mallinfo();
     359             :   char buf[MTYPE_MEMSTR_LEN];
     360             :   
     361           0 :   vty_out (vty, "System allocator statistics:%s", VTY_NEWLINE);
     362           0 :   vty_out (vty, "  Total heap allocated:  %s%s",
     363           0 :            mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.arena),
     364           0 :            VTY_NEWLINE);
     365           0 :   vty_out (vty, "  Holding block headers: %s%s",
     366           0 :            mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.hblkhd),
     367           0 :            VTY_NEWLINE);
     368           0 :   vty_out (vty, "  Used small blocks:     %s%s",
     369           0 :            mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.usmblks),
     370           0 :            VTY_NEWLINE);
     371           0 :   vty_out (vty, "  Used ordinary blocks:  %s%s",
     372           0 :            mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.uordblks),
     373           0 :            VTY_NEWLINE);
     374           0 :   vty_out (vty, "  Free small blocks:     %s%s",
     375           0 :            mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.fsmblks),
     376           0 :            VTY_NEWLINE);
     377           0 :   vty_out (vty, "  Free ordinary blocks:  %s%s",
     378           0 :            mtype_memstr (buf, MTYPE_MEMSTR_LEN, minfo.fordblks),
     379           0 :            VTY_NEWLINE);
     380           0 :   vty_out (vty, "  Ordinary blocks:       %ld%s",
     381           0 :            (unsigned long)minfo.ordblks,
     382           0 :            VTY_NEWLINE);
     383           0 :   vty_out (vty, "  Small blocks:          %ld%s",
     384           0 :            (unsigned long)minfo.smblks,
     385           0 :            VTY_NEWLINE);
     386           0 :   vty_out (vty, "  Holding blocks:        %ld%s",
     387           0 :            (unsigned long)minfo.hblks,
     388           0 :            VTY_NEWLINE);
     389           0 :   vty_out (vty, "(see system documentation for 'mallinfo' for meaning)%s",
     390           0 :            VTY_NEWLINE);
     391           0 :   return 1;
     392             : }
     393             : #endif /* HAVE_MALLINFO */
     394             : 
     395           0 : DEFUN (show_memory_all,
     396             :        show_memory_all_cmd,
     397             :        "show memory all",
     398             :        "Show running system information\n"
     399             :        "Memory statistics\n"
     400             :        "All memory statistics\n")
     401             : {
     402             :   struct mlist *ml;
     403           0 :   int needsep = 0;
     404             :   
     405             : #ifdef HAVE_MALLINFO
     406           0 :   needsep = show_memory_mallinfo (vty);
     407             : #endif /* HAVE_MALLINFO */
     408             :   
     409           0 :   for (ml = mlists; ml->list; ml++)
     410             :     {
     411           0 :       if (needsep)
     412           0 :         show_separator (vty);
     413           0 :       needsep = show_memory_vty (vty, ml->list);
     414             :     }
     415             : 
     416           0 :   return CMD_SUCCESS;
     417             : }
     418             : 
     419             : ALIAS (show_memory_all,
     420             :        show_memory_cmd,
     421             :        "show memory",
     422             :        "Show running system information\n"
     423             :        "Memory statistics\n")
     424             : 
     425           0 : DEFUN (show_memory_lib,
     426             :        show_memory_lib_cmd,
     427             :        "show memory lib",
     428             :        SHOW_STR
     429             :        "Memory statistics\n"
     430             :        "Library memory\n")
     431             : {
     432           0 :   show_memory_vty (vty, memory_list_lib);
     433           0 :   return CMD_SUCCESS;
     434             : }
     435             : 
     436           0 : DEFUN (show_memory_zebra,
     437             :        show_memory_zebra_cmd,
     438             :        "show memory zebra",
     439             :        SHOW_STR
     440             :        "Memory statistics\n"
     441             :        "Zebra memory\n")
     442             : {
     443           0 :   show_memory_vty (vty, memory_list_zebra);
     444           0 :   return CMD_SUCCESS;
     445             : }
     446             : 
     447           0 : DEFUN (show_memory_rip,
     448             :        show_memory_rip_cmd,
     449             :        "show memory rip",
     450             :        SHOW_STR
     451             :        "Memory statistics\n"
     452             :        "RIP memory\n")
     453             : {
     454           0 :   show_memory_vty (vty, memory_list_rip);
     455           0 :   return CMD_SUCCESS;
     456             : }
     457             : 
     458           0 : DEFUN (show_memory_ripng,
     459             :        show_memory_ripng_cmd,
     460             :        "show memory ripng",
     461             :        SHOW_STR
     462             :        "Memory statistics\n"
     463             :        "RIPng memory\n")
     464             : {
     465           0 :   show_memory_vty (vty, memory_list_ripng);
     466           0 :   return CMD_SUCCESS;
     467             : }
     468             : 
     469           0 : DEFUN (show_memory_babel,
     470             :        show_memory_babel_cmd,
     471             :        "show memory babel",
     472             :        SHOW_STR
     473             :        "Memory statistics\n"
     474             :        "Babel memory\n")
     475             : {
     476           0 :   show_memory_vty (vty, memory_list_babel);
     477           0 :   return CMD_SUCCESS;
     478             : }
     479             : 
     480           0 : DEFUN (show_memory_bgp,
     481             :        show_memory_bgp_cmd,
     482             :        "show memory bgp",
     483             :        SHOW_STR
     484             :        "Memory statistics\n"
     485             :        "BGP memory\n")
     486             : {
     487           0 :   show_memory_vty (vty, memory_list_bgp);
     488           0 :   return CMD_SUCCESS;
     489             : }
     490             : 
     491           0 : DEFUN (show_memory_ospf,
     492             :        show_memory_ospf_cmd,
     493             :        "show memory ospf",
     494             :        SHOW_STR
     495             :        "Memory statistics\n"
     496             :        "OSPF memory\n")
     497             : {
     498           0 :   show_memory_vty (vty, memory_list_ospf);
     499           0 :   return CMD_SUCCESS;
     500             : }
     501             : 
     502           0 : DEFUN (show_memory_ospf6,
     503             :        show_memory_ospf6_cmd,
     504             :        "show memory ospf6",
     505             :        SHOW_STR
     506             :        "Memory statistics\n"
     507             :        "OSPF6 memory\n")
     508             : {
     509           0 :   show_memory_vty (vty, memory_list_ospf6);
     510           0 :   return CMD_SUCCESS;
     511             : }
     512             : 
     513           0 : DEFUN (show_memory_isis,
     514             :        show_memory_isis_cmd,
     515             :        "show memory isis",
     516             :        SHOW_STR
     517             :        "Memory statistics\n"
     518             :        "ISIS memory\n")
     519             : {
     520           0 :   show_memory_vty (vty, memory_list_isis);
     521           0 :   return CMD_SUCCESS;
     522             : }
     523             : 
     524             : void
     525          45 : memory_init (void)
     526             : {
     527          45 :   install_element (RESTRICTED_NODE, &show_memory_cmd);
     528          45 :   install_element (RESTRICTED_NODE, &show_memory_all_cmd);
     529          45 :   install_element (RESTRICTED_NODE, &show_memory_lib_cmd);
     530          45 :   install_element (RESTRICTED_NODE, &show_memory_rip_cmd);
     531          45 :   install_element (RESTRICTED_NODE, &show_memory_ripng_cmd);
     532          45 :   install_element (RESTRICTED_NODE, &show_memory_babel_cmd);
     533          45 :   install_element (RESTRICTED_NODE, &show_memory_bgp_cmd);
     534          45 :   install_element (RESTRICTED_NODE, &show_memory_ospf_cmd);
     535          45 :   install_element (RESTRICTED_NODE, &show_memory_ospf6_cmd);
     536          45 :   install_element (RESTRICTED_NODE, &show_memory_isis_cmd);
     537             : 
     538          45 :   install_element (VIEW_NODE, &show_memory_cmd);
     539          45 :   install_element (VIEW_NODE, &show_memory_all_cmd);
     540          45 :   install_element (VIEW_NODE, &show_memory_lib_cmd);
     541          45 :   install_element (VIEW_NODE, &show_memory_rip_cmd);
     542          45 :   install_element (VIEW_NODE, &show_memory_ripng_cmd);
     543          45 :   install_element (VIEW_NODE, &show_memory_babel_cmd);
     544          45 :   install_element (VIEW_NODE, &show_memory_bgp_cmd);
     545          45 :   install_element (VIEW_NODE, &show_memory_ospf_cmd);
     546          45 :   install_element (VIEW_NODE, &show_memory_ospf6_cmd);
     547          45 :   install_element (VIEW_NODE, &show_memory_isis_cmd);
     548             : 
     549          45 :   install_element (ENABLE_NODE, &show_memory_cmd);
     550          45 :   install_element (ENABLE_NODE, &show_memory_all_cmd);
     551          45 :   install_element (ENABLE_NODE, &show_memory_lib_cmd);
     552          45 :   install_element (ENABLE_NODE, &show_memory_zebra_cmd);
     553          45 :   install_element (ENABLE_NODE, &show_memory_rip_cmd);
     554          45 :   install_element (ENABLE_NODE, &show_memory_ripng_cmd);
     555          45 :   install_element (ENABLE_NODE, &show_memory_babel_cmd);
     556          45 :   install_element (ENABLE_NODE, &show_memory_bgp_cmd);
     557          45 :   install_element (ENABLE_NODE, &show_memory_ospf_cmd);
     558          45 :   install_element (ENABLE_NODE, &show_memory_ospf6_cmd);
     559          45 :   install_element (ENABLE_NODE, &show_memory_isis_cmd);
     560          45 : }
     561             : 
     562             : /* Stats querying from users */
     563             : /* Return a pointer to a human friendly string describing
     564             :  * the byte count passed in. E.g:
     565             :  * "0 bytes", "2048 bytes", "110kB", "500MiB", "11GiB", etc.
     566             :  * Up to 4 significant figures will be given.
     567             :  * The pointer returned may be NULL (indicating an error)
     568             :  * or point to the given buffer, or point to static storage.
     569             :  */
     570             : const char *
     571           0 : mtype_memstr (char *buf, size_t len, unsigned long bytes)
     572             : {
     573             :   unsigned int t, g, m, k;
     574             :   
     575             :   /* easy cases */
     576           0 :   if (!bytes)
     577           0 :     return "0 bytes";
     578           0 :   if (bytes == 1)
     579           0 :     return "1 byte";
     580             :     
     581             :   if (sizeof (unsigned long) >= 8)
     582             :     /* Hacked to make it not warn on ILP32 machines
     583             :      * Shift will always be 40 at runtime. See below too */
     584           0 :     t = bytes >> (sizeof (unsigned long) >= 8 ? 40 : 0);
     585             :   else
     586             :     t = 0;
     587           0 :   g = bytes >> 30;
     588           0 :   m = bytes >> 20;
     589           0 :   k = bytes >> 10;
     590             :   
     591           0 :   if (t > 10)
     592             :     {
     593             :       /* The shift will always be 39 at runtime.
     594             :        * Just hacked to make it not warn on 'smaller' machines. 
     595             :        * Static compiler analysis should mean no extra code
     596             :        */
     597           0 :       if (bytes & (1UL << (sizeof (unsigned long) >= 8 ? 39 : 0)))
     598           0 :         t++;
     599           0 :       snprintf (buf, len, "%4d TiB", t);
     600             :     }
     601           0 :   else if (g > 10)
     602             :     {
     603           0 :       if (bytes & (1 << 29))
     604           0 :         g++;
     605           0 :       snprintf (buf, len, "%d GiB", g);
     606             :     }
     607           0 :   else if (m > 10)
     608             :     {
     609           0 :       if (bytes & (1 << 19))
     610           0 :         m++;
     611           0 :       snprintf (buf, len, "%d MiB", m);
     612             :     }
     613           0 :   else if (k > 10)
     614             :     {
     615           0 :       if (bytes & (1 << 9))
     616           0 :         k++;
     617           0 :       snprintf (buf, len, "%d KiB", k);
     618             :     }
     619             :   else
     620           0 :     snprintf (buf, len, "%ld bytes", bytes);
     621             :   
     622           0 :   return buf;
     623             : }
     624             : 
     625             : unsigned long
     626           0 : mtype_stats_alloc (int type)
     627             : {
     628           0 :   return mstat[type].alloc;
     629             : }

Generated by: LCOV version 1.10