summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/malloc.h9
-rw-r--r--libc/stdlib/malloc-standard/free.c31
-rw-r--r--libc/stdlib/malloc-standard/mallinfo.c25
3 files changed, 65 insertions, 0 deletions
diff --git a/include/malloc.h b/include/malloc.h
index 790390db7..610c47dc3 100644
--- a/include/malloc.h
+++ b/include/malloc.h
@@ -145,6 +145,15 @@ struct mallinfo {
/* Returns a copy of the updated current mallinfo. */
extern struct mallinfo mallinfo __MALLOC_P ((void));
+/* Release all but __pad bytes of freed top-most memory back to the
+ system. Return 1 if successful, else 0. */
+extern int malloc_trim(size_t pad);
+
+#include <stdio.h>
+/* Prints brief summary statistics to the specified file.
+ * Writes to stderr if file is NULL. */
+extern void malloc_stats(FILE *file);
+
/* SVID2/XPG mallopt options */
#ifndef M_MXFAST
# define M_MXFAST 1 /* UNUSED in this malloc */
diff --git a/libc/stdlib/malloc-standard/free.c b/libc/stdlib/malloc-standard/free.c
index 4277767fa..ec4debd56 100644
--- a/libc/stdlib/malloc-standard/free.c
+++ b/libc/stdlib/malloc-standard/free.c
@@ -17,6 +17,37 @@
#include "malloc.h"
+/* ------------------------- malloc_trim -------------------------
+ malloc_trim(size_t pad);
+
+ If possible, gives memory back to the system (via negative
+ arguments to sbrk) if there is unused memory at the `high' end of
+ the malloc pool. You can call this after freeing large blocks of
+ memory to potentially reduce the system-level memory requirements
+ of a program. However, it cannot guarantee to reduce memory. Under
+ some allocation patterns, some large free blocks of memory will be
+ locked between two used chunks, so they cannot be given back to
+ the system.
+
+ The `pad' argument to malloc_trim represents the amount of free
+ trailing space to leave untrimmed. If this argument is zero,
+ only the minimum amount of memory to maintain internal data
+ structures will be left (one page or less). Non-zero arguments
+ can be supplied to maintain enough trailing space to service
+ future expected allocations without having to re-obtain memory
+ from the system.
+
+ Malloc_trim returns 1 if it actually released any memory, else 0.
+ On systems that do not support "negative sbrks", it will always
+ return 0.
+*/
+int malloc_trim(size_t pad)
+{
+ mstate av = get_malloc_state();
+ __malloc_consolidate(av);
+ return __malloc_trim(pad, av);
+}
+
/* ------------------------- __malloc_trim -------------------------
__malloc_trim is an inverse of sorts to __malloc_alloc. It gives memory
back to the system (via negative arguments to sbrk) if there is unused
diff --git a/libc/stdlib/malloc-standard/mallinfo.c b/libc/stdlib/malloc-standard/mallinfo.c
index 89d6b68e1..f35aab00f 100644
--- a/libc/stdlib/malloc-standard/mallinfo.c
+++ b/libc/stdlib/malloc-standard/mallinfo.c
@@ -79,3 +79,28 @@ struct mallinfo mallinfo(void)
return mi;
}
+void malloc_stats(FILE *file)
+{
+ struct mallinfo mi;
+
+ if (file==NULL) {
+ file = stderr;
+ }
+
+ mi = mallinfo();
+ fprintf(file, "total bytes allocated = %10lu\n", (unsigned int)(mi.arena + mi.hblkhd));
+ fprintf(file, "total bytes in use bytes = %10lu\n", (unsigned int)(mi.uordblks + mi.hblkhd));
+ fprintf(file, "total non-mmapped bytes allocated = %10lu\n", (unsigned int)(mi.arena));
+ fprintf(file, "number of mmapped regions = %10lu\n", (unsigned int)(mi.hblks));
+ fprintf(file, "total allocated mmap space = %10lu\n", (unsigned int)(mi.hblkhd));
+ fprintf(file, "total allocated sbrk space = %10lu\n", (unsigned int)(mi.uordblks));
+#if 0
+ fprintf(file, "number of free chunks = %10lu\n", (unsigned int)(mi.ordblks));
+ fprintf(file, "number of fastbin blocks = %10lu\n", (unsigned int)(mi.smblks));
+ fprintf(file, "space in freed fastbin blocks = %10lu\n", (unsigned int)(mi.fsmblks));
+#endif
+ fprintf(file, "maximum total allocated space = %10lu\n", (unsigned int)(mi.usmblks));
+ fprintf(file, "total free space = %10lu\n", (unsigned int)(mi.fordblks));
+ fprintf(file, "memory releasable via malloc_trim = %10lu\n", (unsigned int)(mi.keepcost));
+}
+