This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
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)