This is the mail archive of the newlib@sourceware.org mailing list for the newlib 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]

[PATCH] malloc on top to consider already available memory


Hi,

This is my fist post. I suggest a patch for malloc considering already
available memory available on the top instead of always extending top
with the allocation request size when there is not enough space, which may
cause near double memory requirements in some cases. For an MCU with
small memory it may be quite crucial and for anyone it is a bit unexpected
behavior.

An example of the problem; Do malloc(30000); free(); malloc(40000);
free();  then without this patch then peak memory will become 70KB
but with the patch it will be only 40KB as second extend will only be
for 10KB extra  not 40K.

Newer versions of Doug Lea malloc, starting with version 2.7.0,
already contains similar fix since several years ago and it would be
nice if this fix could be included in Newlib also.

The patch below first try and extend top with the diff of what should
be needed, if that fails to extend top large enough for some reason
the behavior falls back on old behavior (a failure may happen if there
are intervening sbrk() or if out of memory).

br Petter

$ diff -up newlib-2.3.0.20160104/newlib/libc/stdlib/mallocr.c
newlib-patch/newlib/libc/stdlib/mallocr.c
--- newlib-2.3.0.20160104/newlib/libc/stdlib/mallocr.c  2016-02-12
15:32:05.380345800 +0100
+++ newlib-patch/newlib/libc/stdlib/mallocr.c   2016-02-12
15:36:17.184029400 +0100
@@ -2572,7 +2572,20 @@ Void_t* mALLOc(RARG bytes) RDECL size_t
 #endif

     /* Try to extend */
-    malloc_extend_top(RCALL nb);
+    if (bytes > chunksize(top)) {
+      /* extend including whats available on top */
+      INTERNAL_SIZE_T nb_diff  = request2size(long_sub_size_t(bytes,
chunksize(top)));
+      malloc_extend_top(RCALL nb_diff);
+      remainder_size = long_sub_size_t(chunksize(top), nb);
+      if (chunksize(top) < nb || remainder_size < (long)MINSIZE)
+      {
+        /* top not large enough; failure or intervening sbrk() */
+        malloc_trim(RCALL 0);
+        malloc_extend_top(RCALL nb);
+      }
+    }
+    else
+      malloc_extend_top(RCALL nb);
     remainder_size = long_sub_size_t(chunksize(top), nb);
     if (chunksize(top) < nb || remainder_size < (long)MINSIZE)
     {


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