This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: mallinfo not 64-bit clean [PATCH]


Hi,

Ok, here is what I have coded up today for the mallinfo problem.  A
new test is also included.  I don't intend to change the
malloc_{arena,global}_info structs any time soon, but they shouldn't
be considered 'fixed' either.  I added the three new functions with
GLIBC_PRIVATE for now, but maybe GLIBC_2.3.x is justfied.  Your call.

Regards,
Wolfram.

2004-08-08  Wolfram Gloger  <wg@malloc.de>

	* include/malloc.h (mstate): Move type declaration from here...
	* malloc/malloc.h: ...to here.
	(struct malloc_arena_info, struct malloc_global_info): New types.
	(_int_get_arena, _int_get_arena_info, _int_get_global_info): New
	functions.
	* malloc/malloc.c (mSTATS, public_mSTATs, mALLINFo): Remove.
	(_int_get_arena_info, _int_get_global_info): New functions.
	* malloc/arena.c (_int_get_arena): New function.
	* malloc/malloc-stats.c: New file.
	* malloc/tst-mstats.c: New file.
	* malloc/Makefile (tests): Add tst-mstats.
	(distribute): Remove no-longer existing thread-m.h.
	(dist-routines): Add malloc-stats.
	* malloc/Versions: Add _int_get_arena, _int_get_arena_info,
	_int_get_global_info.

diff -urN -x *~ orig/libc/malloc/Makefile libc/malloc/Makefile
--- orig/libc/malloc/Makefile	Tue Sep 30 04:09:22 2003
+++ libc/malloc/Makefile	Sun Aug  8 16:53:16 2004
@@ -1,4 +1,4 @@
-# Copyright (C) 1991-1999,2000,2001,2002,2003 Free Software Foundation, Inc.
+# Copyright (C) 1991-2000,2001,2002,2003,2004 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 
 # The GNU C Library is free software; you can redistribute it and/or
@@ -26,16 +26,16 @@
 dist-headers := malloc.h
 headers := $(dist-headers) obstack.h mcheck.h
 tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
-	 tst-mallocstate
+	 tst-mallocstate tst-mstats
 test-srcs = tst-mtrace
 
-distribute = thread-m.h mtrace.pl mcheck-init.c stackinfo.h memusage.h \
+distribute = mtrace.pl mcheck-init.c stackinfo.h memusage.h \
 	     memusage.sh memusagestat.c tst-mtrace.sh arena.c hooks.c
 
 # Things which get pasted together into gmalloc.c.
 gmalloc-routines := malloc morecore
 # Things to include in the standalone distribution.
-dist-routines = $(gmalloc-routines) mcheck mtrace
+dist-routines = $(gmalloc-routines) malloc-stats mcheck mtrace
 routines = $(dist-routines) obstack
 
 install-lib := libmcheck.a
diff -urN -x *~ orig/libc/malloc/Versions libc/malloc/Versions
--- orig/libc/malloc/Versions	Sat Feb 22 01:53:40 2003
+++ libc/malloc/Versions	Sun Aug  8 15:42:44 2004
@@ -61,5 +61,8 @@
 
     # Internal destructor hook for libpthread.
     __libc_thread_freeres;
+
+    # Internal mallinfo functions.
+    _int_get_arena; _int_get_arena_info; _int_get_global_info;
   }
 }
diff -urN -x *~ orig/libc/malloc/arena.c libc/malloc/arena.c
--- orig/libc/malloc/arena.c	Tue Jul  1 10:27:54 2003
+++ libc/malloc/arena.c	Sun Aug  8 14:42:04 2004
@@ -808,6 +808,21 @@
   return a;
 }
 
+/* Obtain the arena number n.  Needed in malloc_stats.  */
+
+mstate
+_int_get_arena (int n)
+{
+  mstate a = &main_arena;
+
+  while (n-- != 0) {
+    a = a->next;
+    if (a == &main_arena)
+      return 0;
+  }
+  return a;
+}
+
 #endif /* USE_ARENAS */
 
 /*
diff -urN -x *~ orig/libc/malloc/malloc-stats.c libc/malloc/malloc-stats.c
--- orig/libc/malloc/malloc-stats.c	Thu Jan  1 01:00:00 1970
+++ libc/malloc/malloc-stats.c	Sun Aug  8 15:12:42 2004
@@ -0,0 +1,161 @@
+/* Malloc implementation for multiple threads; statistics printing.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Wolfram Gloger <wg@malloc.de>, 2004.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/* $Id: $ */
+
+#include <stdio.h>    /* needed for malloc_stats */
+
+#include <malloc-machine.h>
+
+#include "malloc.h"
+
+/*
+  Define HAVE_MMAP as true to optionally make malloc() use mmap() to
+  allocate very large blocks.  These will be returned to the
+  operating system immediately after a free(). Also, if mmap
+  is available, it is used as a backup strategy in cases where
+  MORECORE fails to provide space from system.
+
+  This malloc is best tuned to work with mmap for large requests.
+  If you do not have mmap, operations involving very large chunks (1MB
+  or so) may be slower than you'd like.
+*/
+
+#ifndef HAVE_MMAP
+#define HAVE_MMAP 1
+#endif
+
+#ifdef USE_DL_PREFIX
+
+#define public_mSTATs    dlmalloc_stats
+
+#else /* USE_DL_PREFIX */
+#ifdef _LIBC
+
+#define public_mSTATs    __malloc_stats
+
+#else /* !_LIBC */
+
+#define public_mSTATs    malloc_stats
+
+#endif /* _LIBC */
+#endif /* USE_DL_PREFIX */
+
+/*
+  malloc_stats();
+  Prints on stderr the amount of space obtained from the system (both
+  via sbrk and mmap), the maximum amount (which may be more than
+  current if malloc_trim and/or munmap got called), and the current
+  number of bytes allocated via malloc (or realloc, etc) but not yet
+  freed. Note that this is the number of bytes allocated, not the
+  number requested. It will be larger than the number requested
+  because of alignment and bookkeeping overhead. Because it includes
+  alignment wastage as being in use, this figure may be greater than
+  zero even when no user-level chunks are allocated.
+
+  The reported current and maximum system memory can be inaccurate if
+  a program makes other calls to system memory allocation functions
+  (normally sbrk) outside of malloc.
+
+  malloc_stats prints only the most commonly interesting statistics.
+  More information can be obtained by calling mallinfo.
+
+*/
+void     public_mSTATs __MALLOC_P((void));
+
+/*
+  ------------------------------ malloc_stats ------------------------------
+*/
+
+void public_mSTATs()
+{
+  int i;
+  mstate ar_ptr;
+  struct malloc_global_info mgi;
+  struct malloc_arena_info mai;
+  unsigned long in_use_b, system_b, avail_b;
+#if THREAD_STATS
+  long stat_lock_direct = 0, stat_lock_loop = 0, stat_lock_wait = 0;
+#endif
+
+#if 0
+  if(__malloc_initialized < 0)
+    ptmalloc_init ();
+#endif
+  _int_get_global_info(&mgi);
+  system_b = in_use_b = mgi.mmapped_mem;
+#ifdef _LIBC
+  _IO_flockfile (stderr);
+  int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+  ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
+#endif
+  for (i=0; (ar_ptr = _int_get_arena(i)); i++) {
+    _int_get_arena_info(ar_ptr, &mai);
+    avail_b = mai.fastavail + mai.binavail + mai.top_size;
+    fprintf(stderr, "Arena %d:\n", i);
+    fprintf(stderr, "system bytes     = %10lu\n",
+	    (unsigned long)mai.system_mem);
+    fprintf(stderr, "in use bytes     = %10lu\n",
+	    (unsigned long)(mai.system_mem - avail_b));
+#if MALLOC_DEBUG > 1
+    if (i > 0)
+      dump_heap(heap_for_ptr(top(ar_ptr)));
+#endif
+    system_b += mai.system_mem;
+    in_use_b += mai.system_mem - avail_b;
+#if THREAD_STATS
+    stat_lock_direct += mai.stat_lock_direct;
+    stat_lock_loop += mai.stat_lock_loop;
+    stat_lock_wait += mai.stat_lock_wait;
+#endif
+  }
+#if HAVE_MMAP
+  fprintf(stderr, "Total (incl. mmap):\n");
+#else
+  fprintf(stderr, "Total:\n");
+#endif
+  fprintf(stderr, "system bytes     = %10lu\n", system_b);
+  fprintf(stderr, "in use bytes     = %10lu\n", in_use_b);
+#ifdef NO_THREADS
+  fprintf(stderr, "max system bytes = %10lu\n",
+	  (unsigned long)mp_.max_total_mem);
+#endif
+#if HAVE_MMAP
+  fprintf(stderr, "max mmap regions = %10u\n", (unsigned int)mgi.max_n_mmaps);
+  fprintf(stderr, "max mmap bytes   = %10lu\n",
+	  (unsigned long)mgi.max_mmapped_mem);
+#endif
+#if THREAD_STATS
+  fprintf(stderr, "heaps created    = %10d\n",  mgi.stat_n_heaps);
+  fprintf(stderr, "locked directly  = %10ld\n", stat_lock_direct);
+  fprintf(stderr, "locked in loop   = %10ld\n", stat_lock_loop);
+  fprintf(stderr, "locked waiting   = %10ld\n", stat_lock_wait);
+  fprintf(stderr, "locked total     = %10ld\n",
+          stat_lock_direct + stat_lock_loop + stat_lock_wait);
+#endif
+#ifdef _LIBC
+  ((_IO_FILE *) stderr)->_flags2 |= old_flags2;
+  _IO_funlockfile (stderr);
+#endif
+}
+
+#ifdef _LIBC
+weak_alias (__malloc_stats, malloc_stats)
+#endif
diff -urN -x *~ orig/libc/malloc/malloc.c libc/malloc/malloc.c
--- orig/libc/malloc/malloc.c	Fri Mar 19 08:15:21 2004
+++ libc/malloc/malloc.c	Sun Aug  8 16:45:44 2004
@@ -38,8 +38,7 @@
   the ptmalloc2 distribution, which has pre-defined targets for some
   popular systems (e.g. "make posix" for Posix threads).  All that is
   typically required with regard to compiler flags is the selection of
-  the thread package via defining one out of USE_PTHREADS, USE_THR or
-  USE_SPROC.  Check the thread-m.h file for what effects this has.
+  an appropriate malloc-machine.h include file via -I directives.
   Many/most systems will additionally require USE_TSD_DATA_HACK to be
   defined, so this is the default for "make posix".
 
@@ -1495,9 +1494,7 @@
 static Void_t** _int_icomalloc(mstate, size_t, size_t*, Void_t**);
 static int      mTRIm(size_t);
 static size_t   mUSABLe(Void_t*);
-static void     mSTATs(void);
 static int      mALLOPt(int, int);
-static struct mallinfo mALLINFo(mstate);
 
 static Void_t* internal_function mem2mem_check(Void_t *p, size_t sz);
 static int internal_function top_check(void);
@@ -1543,9 +1540,7 @@
 static Void_t** _int_icomalloc();
 static int      mTRIm();
 static size_t   mUSABLe();
-static void     mSTATs();
 static int      mALLOPt();
-static struct mallinfo mALLINFo();
 
 #endif
 
@@ -3725,21 +3720,30 @@
   return result;
 }
 
-void
-public_mSTATs()
-{
-  mSTATs();
-}
-
-struct mallinfo public_mALLINFo()
+/* This exists mainly for backward compatibility.  Calling
+   _int_get_arena_info() directly is more useful.  */
+struct mallinfo
+public_mALLINFo()
 {
+  struct malloc_arena_info mai;
   struct mallinfo m;
+  size_t avail;
 
   if(__malloc_initialized < 0)
     ptmalloc_init ();
-  (void)mutex_lock(&main_arena.mutex);
-  m = mALLINFo(&main_arena);
-  (void)mutex_unlock(&main_arena.mutex);
+  _int_get_arena_info(&main_arena, &mai);
+  /* Account for top */
+  avail = mai.fastavail + mai.binavail + mai.top_size;
+  m.smblks = mai.nfastblocks;
+  m.ordblks = mai.nbinblocks + 1;
+  m.fordblks = avail;
+  m.uordblks = mai.system_mem - avail;
+  m.arena = mai.system_mem;
+  m.hblks = mp_.n_mmaps;
+  m.hblkhd = mp_.mmapped_mem;
+  m.fsmblks = mai.fastavail;
+  m.keepcost = mai.top_size;
+  m.usmblks = mp_.max_total_mem;
   return m;
 }
 
@@ -5071,33 +5075,27 @@
 }
 
 /*
-  ------------------------------ mallinfo ------------------------------
+  ---------------------- internal mallinfo -----------------------------
 */
 
-struct mallinfo mALLINFo(mstate av)
+void _int_get_arena_info(mstate av, struct malloc_arena_info *mai)
 {
-  struct mallinfo mi;
   size_t i;
   mbinptr b;
   mchunkptr p;
-  INTERNAL_SIZE_T avail;
-  INTERNAL_SIZE_T fastavail;
-  int nblocks;
-  int nfastblocks;
+  size_t binavail = 0;
+  size_t fastavail = 0;
+  int nbinblocks = 0;
+  int nfastblocks = 0;
+
+  (void)mutex_lock(&av->mutex);
 
   /* Ensure initialization */
   if (av->top == 0)  malloc_consolidate(av);
 
   check_malloc_state(av);
 
-  /* Account for top */
-  avail = chunksize(av->top);
-  nblocks = 1;  /* top always exists */
-
   /* traverse fastbins */
-  nfastblocks = 0;
-  fastavail = 0;
-
   for (i = 0; i < NFASTBINS; ++i) {
     for (p = av->fastbins[i]; p != 0; p = p->fd) {
       ++nfastblocks;
@@ -5105,101 +5103,49 @@
     }
   }
 
-  avail += fastavail;
-
   /* traverse regular bins */
   for (i = 1; i < NBINS; ++i) {
     b = bin_at(av, i);
     for (p = last(b); p != b; p = p->bk) {
-      ++nblocks;
-      avail += chunksize(p);
+      ++nbinblocks;
+      binavail += chunksize(p);
     }
   }
 
-  mi.smblks = nfastblocks;
-  mi.ordblks = nblocks;
-  mi.fordblks = avail;
-  mi.uordblks = av->system_mem - avail;
-  mi.arena = av->system_mem;
-  mi.hblks = mp_.n_mmaps;
-  mi.hblkhd = mp_.mmapped_mem;
-  mi.fsmblks = fastavail;
-  mi.keepcost = chunksize(av->top);
-  mi.usmblks = mp_.max_total_mem;
-  return mi;
-}
+  mai->nfastblocks = nfastblocks;
+  mai->nbinblocks = nbinblocks;
+  mai->fastavail = fastavail;
+  mai->binavail = binavail;
+  mai->top_size = chunksize(av->top);
+  mai->system_mem = av->system_mem;
+  mai->max_system_mem = av->max_system_mem;
+  mai->stat_lock_direct = av->stat_lock_direct;
+  mai->stat_lock_loop   = av->stat_lock_loop;
+  mai->stat_lock_wait   = av->stat_lock_wait;
 
-/*
-  ------------------------------ malloc_stats ------------------------------
-*/
+  (void)mutex_unlock(&av->mutex);
+}
 
-void mSTATs()
+void
+_int_get_global_info (struct malloc_global_info *mgi)
 {
-  int i;
-  mstate ar_ptr;
-  struct mallinfo mi;
-  unsigned int in_use_b = mp_.mmapped_mem, system_b = in_use_b;
+  mgi->n_mmaps = mp_.n_mmaps;
+  mgi->max_n_mmaps = mp_.max_n_mmaps;
+  mgi->mmapped_mem = mp_.mmapped_mem;
+  mgi->max_mmapped_mem = mp_.max_mmapped_mem;
+  mgi->max_total_mem = mp_.max_total_mem;
 #if THREAD_STATS
-  long stat_lock_direct = 0, stat_lock_loop = 0, stat_lock_wait = 0;
-#endif
-
-  if(__malloc_initialized < 0)
-    ptmalloc_init ();
-#ifdef _LIBC
-  _IO_flockfile (stderr);
-  int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
-  ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
-#endif
-  for (i=0, ar_ptr = &main_arena;; i++) {
-    (void)mutex_lock(&ar_ptr->mutex);
-    mi = mALLINFo(ar_ptr);
-    fprintf(stderr, "Arena %d:\n", i);
-    fprintf(stderr, "system bytes     = %10u\n", (unsigned int)mi.arena);
-    fprintf(stderr, "in use bytes     = %10u\n", (unsigned int)mi.uordblks);
-#if MALLOC_DEBUG > 1
-    if (i > 0)
-      dump_heap(heap_for_ptr(top(ar_ptr)));
-#endif
-    system_b += mi.arena;
-    in_use_b += mi.uordblks;
-#if THREAD_STATS
-    stat_lock_direct += ar_ptr->stat_lock_direct;
-    stat_lock_loop += ar_ptr->stat_lock_loop;
-    stat_lock_wait += ar_ptr->stat_lock_wait;
-#endif
-    (void)mutex_unlock(&ar_ptr->mutex);
-    ar_ptr = ar_ptr->next;
-    if(ar_ptr == &main_arena) break;
-  }
-#if HAVE_MMAP
-  fprintf(stderr, "Total (incl. mmap):\n");
+  mgi->stat_n_heaps = stat_n_heaps;
 #else
-  fprintf(stderr, "Total:\n");
-#endif
-  fprintf(stderr, "system bytes     = %10u\n", system_b);
-  fprintf(stderr, "in use bytes     = %10u\n", in_use_b);
-#ifdef NO_THREADS
-  fprintf(stderr, "max system bytes = %10u\n", (unsigned int)mp_.max_total_mem);
-#endif
-#if HAVE_MMAP
-  fprintf(stderr, "max mmap regions = %10u\n", (unsigned int)mp_.max_n_mmaps);
-  fprintf(stderr, "max mmap bytes   = %10lu\n",
-	  (unsigned long)mp_.max_mmapped_mem);
-#endif
-#if THREAD_STATS
-  fprintf(stderr, "heaps created    = %10d\n",  stat_n_heaps);
-  fprintf(stderr, "locked directly  = %10ld\n", stat_lock_direct);
-  fprintf(stderr, "locked in loop   = %10ld\n", stat_lock_loop);
-  fprintf(stderr, "locked waiting   = %10ld\n", stat_lock_wait);
-  fprintf(stderr, "locked total     = %10ld\n",
-          stat_lock_direct + stat_lock_loop + stat_lock_wait);
-#endif
-#ifdef _LIBC
-  ((_IO_FILE *) stderr)->_flags2 |= old_flags2;
-  _IO_funlockfile (stderr);
+  mgi->stat_n_heaps = 0;
 #endif
 }
 
+/*
+  ------------------------------ malloc_stats ------------------------------
+*/
+
+/* Now in separate file, malloc-stats.c. */
 
 /*
   ------------------------------ mallopt ------------------------------
@@ -5450,7 +5396,6 @@
 weak_alias (__libc_mallinfo, __mallinfo) weak_alias (__libc_mallinfo, mallinfo)
 weak_alias (__libc_mallopt, __mallopt) weak_alias (__libc_mallopt, mallopt)
 
-weak_alias (__malloc_stats, malloc_stats)
 weak_alias (__malloc_usable_size, malloc_usable_size)
 weak_alias (__malloc_trim, malloc_trim)
 weak_alias (__malloc_get_state, malloc_get_state)
diff -urN -x *~ orig/libc/malloc/malloc.h libc/malloc/malloc.h
--- orig/libc/malloc/malloc.h	Mon Aug 18 20:12:32 2003
+++ libc/malloc/malloc.h	Sun Aug  8 14:38:11 2004
@@ -1,5 +1,5 @@
 /* Prototypes and definition for malloc implementation.
-   Copyright (C) 1996,1997,1999,2000,2002,2003 Free Software Foundation, Inc.
+   Copyright (C) 1996,97,99,2000,2002,2003,2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -232,6 +232,41 @@
 /* Activate a standard set of debugging hooks. */
 extern void __malloc_check_init __MALLOC_P ((void));
 
+/* Internal routines, operating on "arenas".  */
+struct malloc_state;
+typedef struct malloc_state *mstate;
+
+/* Return arena number __n, or 0 if out of bounds.  Arena 0 is the
+   main arena.  */
+extern mstate         _int_get_arena __MALLOC_P ((int __n));
+
+/* Implementation-specific mallinfo.  More detailed than mallinfo, and
+   also works for size_t wider than int.  */
+struct malloc_arena_info {
+    int    nfastblocks;    /* number of freed "fastchunks" */
+    int    nbinblocks;     /* number of available chunks in bins */
+    size_t fastavail;      /* total space in freed "fastchunks" */
+    size_t binavail;       /* total space in binned chunks */
+    size_t top_size;       /* size of top chunk */
+    size_t system_mem;     /* bytes allocated from system in this arena */
+    size_t max_system_mem; /* max. bytes allocated from system */
+    /* Statistics for locking.  Only kept if THREAD_STATS is defined
+       at compile time.  */
+    long   stat_lock_direct, stat_lock_loop, stat_lock_wait;
+};
+
+struct malloc_global_info {
+    int    n_mmaps;         /* number of mmap'ed chunks */
+    int    max_n_mmaps;     /* max. number of mmap'ed chunks reached */
+    size_t mmapped_mem;     /* total bytes allocated in mmap'ed chunks */
+    size_t max_mmapped_mem; /* max. bytes allocated in mmap'ed chunks */
+    size_t max_total_mem;   /* only kept for NO_THREADS */
+    int    stat_n_heaps;    /* only kept if THREAD_STATS is defined */
+};
+
+extern void _int_get_arena_info __MALLOC_P ((mstate __m,
+					     struct malloc_arena_info *__ma));
+extern void _int_get_global_info __MALLOC_P ((struct malloc_global_info *__m));
 
 #ifdef __cplusplus
 } /* end of extern "C" */
diff -urN -x *~ orig/libc/malloc/tst-mstats.c libc/malloc/tst-mstats.c
--- orig/libc/malloc/tst-mstats.c	Thu Jan  1 01:00:00 1970
+++ libc/malloc/tst-mstats.c	Sun Aug  8 14:54:56 2004
@@ -0,0 +1,100 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Wolfram Gloger <wg@malloc.de>, 2004.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include <stdio.h>
+#include "malloc.h"
+
+static int errors = 0;
+
+static void
+merror (const char *msg)
+{
+  ++errors;
+  printf ("Error: %s\n", msg);
+}
+
+int
+main (void)
+{
+  void *p1, *p2;
+  long i;
+  mstate a;
+  struct malloc_arena_info mai;
+  int nfree;
+  unsigned long navail;
+
+  errno = 0;
+
+  malloc_stats(); /* check that it works even without initialization */
+  a = _int_get_arena(0);
+  if (!a) {
+    merror ("Can't get main arena.");
+    return 1;
+  }
+  free (malloc (10));
+  _int_get_arena_info(a, &mai);
+  printf("nfree     = %d\navail     = %lu\nfastavail = %lu\ntop_size  = %lu\n",
+	 mai.nbinblocks + mai.nfastblocks,
+	 (unsigned long)mai.binavail,
+	 (unsigned long)mai.fastavail,
+	 (unsigned long)mai.top_size);
+  if (mai.nfastblocks+mai.nbinblocks < 1)
+    merror ("initial _int_get_arena_info() failed.");
+  nfree = mai.nbinblocks + mai.nfastblocks;
+  navail = mai.binavail + mai.fastavail;
+
+  p1 = malloc (10);
+  if (p1 == NULL)
+    merror ("malloc (10) failed.");
+  p2 = malloc (30);
+  if (p2 == NULL)
+    merror ("malloc (30) failed.");
+
+  free (malloc (10));
+
+  for (i=0; i<100; ++i)
+    {
+      p1 = realloc (p1, i*7 + 3);
+      if (p1 == NULL)
+	merror ("realloc (i*7 + 3) failed.");
+    }
+  free (p2);
+
+  _int_get_arena_info(a, &mai);
+  printf("nfree     = %d\navail     = %lu\nfastavail = %lu\ntop_size  = %lu\n",
+	 mai.nbinblocks + mai.nfastblocks,
+	 (unsigned long)mai.binavail,
+	 (unsigned long)mai.fastavail,
+	 (unsigned long)mai.top_size);
+  /* Assume that no memory is returned to the system from these small
+     chunks.  */
+  if (mai.nbinblocks+mai.nfastblocks < nfree ||
+      mai.binavail+mai.fastavail < navail)
+    merror ("final _int_get_arena_info() failed.");
+  malloc_stats();
+
+  return errors != 0;
+}
+
+/*
+ * Local variables:
+ * c-basic-offset: 2
+ * End:
+ */
diff -urN -x *~ orig/libc/include/malloc.h libc/include/malloc.h
--- orig/libc/include/malloc.h	Mon Jan 13 04:42:17 2003
+++ libc/include/malloc.h	Sun Aug  8 14:59:35 2004
@@ -8,10 +8,6 @@
 /* Nonzero if the malloc is already initialized.  */
 extern int __malloc_initialized attribute_hidden;
 
-/* Internal routines, operating on "arenas".  */
-struct malloc_state;
-typedef struct malloc_state *mstate;
-
 extern mstate         _int_new_arena (size_t __ini_size) attribute_hidden;
 extern __malloc_ptr_t _int_malloc (mstate __m, size_t __size) attribute_hidden;
 extern void           _int_free (mstate __m, __malloc_ptr_t __ptr)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]