acadia-newlib/newlib/libc/stdlib
Ola Olsson 84d068971d Nano-malloc: Fix for unwanted external heap fragmentation
The only reason why it is tough for us to use nano malloc
is because of the small shortcoming where nano_malloc()
splits a bigger chunk from the free list into two pieces
while handing back the second one (the tail) to the user.
This is error prone and especially bad for smaller heaps,
where nano malloc is supposed to be superior. The normal
malloc doesn't have this issue and we need to use it even
though it costs us ~2k bytes compared to nano-malloc.

The problem arise especially after giving back _every_
malloced memory to the heap and then starting to exercise
the heap again by allocating something small. This small
item might split the whole heap in two equally big parts
depending on how the heap has been exercised before.

I have uploaded the smallest possible application
(only tested on ST and Nordic devices) to show the issue
while the real customer applications are far more complicated:
https://drive.google.com/file/d/1kfSC2KOm3Os3mI7EBd-U0j63qVs8xMbt/view?usp=sharing

The application works like the following pseudo code,
where we assume a heap of 100 bytes
(I haven't taken padding and other nitty and gritty
details into account. Everything to simplify understanding):

void *ptr = malloc(52); // We get 52 bytes and we have
                        // 48 bytes to use.
free(ptr); // Hand back the 52 bytes to nano_malloc
           // This is the magic line that shows the issue of
           // nano_malloc
ptr = malloc(1); // Nano malloc will split the 52 bytes
                 // in the free list and hand you a pointer
                 // somewhere in the
                 // middle of the heap.
ptr2 = malloc(52); // Out of memory...

I have done a fix which hands back the first part of the
splitted chunk. Once this is fixed we obviously
have the 1 byte placed in position 0 of the heap instead
of somewhere in the middle.

However, this won't let us malloc 52 new bytes even though
we potentially have 99 bytes left to use in the heap. The
reason is that when we try to do the allocation,
nano-malloc looks into the free list and sees a 51 byte
chunk to be used.
This is not big enough so nano-malloc decides to call
sbrk for _another_ 52 bytes which is not possible since
there is only 48 bytes left to ask for.

The solution for this problem is to check if the last
item in the free list is adjacent to sbrk(0). If it is,
as it is in this case, we can just ask sbrk for the
remainder of what is needed. In this case 1 byte.

NB! I have only tested the solution on our ST device.
2021-05-03 13:00:33 +02:00
..
Makefile.am newlib: Build internal strtold code only if HAVE_LONG_DOUBLE defined 2018-10-10 18:01:22 +02:00
Makefile.in Add build mechanism to share common header files between machines 2021-04-13 12:55:33 +02:00
_Exit.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
__adjust.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
__atexit.c newlib: don't check malloc/free pointer 2018-08-08 10:50:19 +02:00
__call_atexit.c newlib: don't check malloc/free pointer 2018-08-08 10:50:19 +02:00
__exp10.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
__ten_mu.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
a64l.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
abort.c ansification: remove _VOID 2018-01-17 11:47:20 -06:00
abs.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
aligned_alloc.c Include malloc.h in libc/stdlib/aligned_alloc.c 2021-02-18 02:05:47 +01:00
arc4random.c Fix warnings when building for msp430-elf 2020-09-03 12:55:32 +02:00
arc4random.h Only define static locks in multithreaded mode 2017-02-13 17:04:17 -05:00
arc4random_uniform.c Add arc4random() etc. from OpenBSD 5.8 2016-03-18 12:33:41 +01:00
assert.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
atexit.c ansification: remove _EXFNPTR, _EXPARM 2018-01-17 11:47:27 -06:00
atexit.h ansification: remove _PTR 2018-01-17 11:47:16 -06:00
atof.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
atoff.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
atoi.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
atol.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
atoll.c Use remove-advertising-clause script to edit BSD licenses 2020-01-29 19:03:31 +01:00
btowc.c Consolidate wctomb/mbtowc calls for POSIX-1.2008 2016-08-15 10:56:57 +02:00
calloc.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
chacha_private.h Cleanup macros in chacha_private.h to be target-type independent 2016-03-18 21:20:06 +01:00
cxa_atexit.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
cxa_finalize.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
div.c Use remove-advertising-clause script to edit BSD licenses 2020-01-29 19:03:31 +01:00
drand48.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
dtoa.c Prevent NULL ptr accesses due to Balloc out of memory 2019-10-04 17:43:49 -04:00
dtoastub.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
ecvtbuf.c Don't display trailing '.' in _dcvt 2019-12-18 20:53:36 +01:00
efgcvt.c fix compile errors for efgcvt.c 2019-07-24 11:58:21 +02:00
environ.c 2002-12-20 Jeff Johnston <jjohnstn@redhat.com> 2002-12-20 21:07:56 +00:00
envlock.c stdlib: remove TRAD_SYNOPSIS 2017-12-01 03:41:52 -06:00
eprintf.c
erand48.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
exit.c Fix syntax error in exit.c 2018-01-19 19:58:10 +01:00
gdtoa-gethex.c Prevent more NULL ptr accesses due to Balloc out of memory 2020-01-09 15:18:14 -05:00
gdtoa-hexnan.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
gdtoa.h Import correctly working strtold from David M. Gay. 2015-11-20 18:14:58 +01:00
getenv.c Use remove-advertising-clause script to edit BSD licenses 2020-01-29 19:03:31 +01:00
getenv_r.c Use remove-advertising-clause script to edit BSD licenses 2020-01-29 19:03:31 +01:00
getopt.c newlib: getopt now permutes multi-flag options correctly 2018-06-18 18:45:44 +02:00
getsubopt.3 Use remove-advertising-clause script to edit BSD licenses 2020-01-29 19:03:31 +01:00
getsubopt.c Use remove-advertising-clause script to edit BSD licenses 2020-01-29 19:03:31 +01:00
imaxabs.c Importing imaxabs inttypes method from FreeBSD. 2017-07-28 12:23:08 +02:00
imaxdiv.c Importing imaxdiv inttypes method from FreeBSD. 2017-07-28 12:23:10 +02:00
itoa.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
jrand48.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
l64a.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
labs.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
lcong48.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
ldiv.c Use remove-advertising-clause script to edit BSD licenses 2020-01-29 19:03:31 +01:00
ldtoa.c Prevent more NULL ptr accesses due to Balloc out of memory 2020-01-09 15:18:14 -05:00
llabs.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
lldiv.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
local.h ansification: remove _EXFUN, _EXFUN_NOTHROW 2018-01-17 11:47:29 -06:00
lrand48.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
malign.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
malloc.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
mallocr.c malloc/nano-malloc: correctly check for out-of-bounds allocation reqs 2020-11-17 10:52:34 +01:00
mbctype.h ansification: remove _EXFUN, _EXFUN_NOTHROW 2018-01-17 11:47:29 -06:00
mblen.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
mblen_r.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
mbrlen.c 2013-11-26 Julio Gutierrez <jgutleyva@gmail.com> 2013-11-26 17:21:01 +00:00
mbrtowc.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
mbsinit.c * libc/stdlib/mbrlen.c: Change include order to prevent compiler errors when 2003-12-05 06:13:44 +00:00
mbsnrtowcs.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
mbsrtowcs.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
mbstowcs.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
mbstowcs_r.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
mbtowc.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
mbtowc_r.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
mlock.c stdlib: remove TRAD_SYNOPSIS 2017-12-01 03:41:52 -06:00
mprec.c Prevent NULL ptr accesses due to Balloc out of memory 2019-10-04 17:43:49 -04:00
mprec.h Prevent NULL ptr accesses due to Balloc out of memory 2019-10-04 17:43:49 -04:00
mrand48.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
msize.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
mstats.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
mtrim.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
nano-mallocr.c Nano-malloc: Fix for unwanted external heap fragmentation 2021-05-03 13:00:33 +02:00
nrand48.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
on_exit.c ansification: remove _EXFNPTR, _EXPARM 2018-01-17 11:47:27 -06:00
on_exit_args.c Add static instance of _on_exit_args for _REENT_SMALL platforms. 2015-12-21 11:49:28 -05:00
on_exit_args.h Add static instance of _on_exit_args for _REENT_SMALL platforms. 2015-12-21 11:49:28 -05:00
putenv.c Use remove-advertising-clause script to edit BSD licenses 2020-01-29 19:03:31 +01:00
putenv_r.c Use remove-advertising-clause script to edit BSD licenses 2020-01-29 19:03:31 +01:00
quick_exit.c Only define static locks in multithreaded mode 2017-02-13 17:04:17 -05:00
rand.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
rand48.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
rand48.h ansification: remove _EXFUN, _EXFUN_NOTHROW 2018-01-17 11:47:29 -06:00
rand_r.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
random.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
realloc.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
reallocarray.c libc/stdlib: Use __builtin_mul_overflow for reallocarray and calloc 2020-08-12 10:09:56 +02:00
reallocf.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
rpmatch.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
sb_charsets.c Actually return value from __cp_index 2016-10-22 21:08:44 +02:00
seed48.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
setenv.c Use remove-advertising-clause script to edit BSD licenses 2020-01-29 19:03:31 +01:00
setenv_r.c Use remove-advertising-clause script to edit BSD licenses 2020-01-29 19:03:31 +01:00
srand48.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
std.h ansification: remove _HAVE_STDC 2018-01-17 11:47:30 -06:00
stdlib.tex Add simple versions of random() and srandom() 2016-03-28 22:39:50 -05:00
strtod.c stdlib: Use __get_numeric_locale instead of __localeconv_l for decimal_point 2018-09-06 14:14:05 +02:00
strtodg.c Prevent more NULL ptr accesses due to Balloc out of memory 2020-01-09 15:18:14 -05:00
strtoimax.c Added Restriction on base value 2018-08-13 09:42:21 +02:00
strtol.c Use remove-advertising-clause script to edit BSD licenses 2020-01-29 19:03:31 +01:00
strtold.c Implement strto[dflu]_l/wcsto[dflu]_l 2016-08-15 17:35:21 +02:00
strtoll.c Use remove-advertising-clause script to edit BSD licenses 2020-01-29 19:03:31 +01:00
strtoll_r.c Implement strto[dflu]_l/wcsto[dflu]_l 2016-08-15 17:35:21 +02:00
strtorx.c newlib: strtold: use __builtin_nanl to avoid libm dependency 2018-10-10 17:53:55 +02:00
strtoul.c Use remove-advertising-clause script to edit BSD licenses 2020-01-29 19:03:31 +01:00
strtoull.c Use remove-advertising-clause script to edit BSD licenses 2020-01-29 19:03:31 +01:00
strtoull_r.c Implement strto[dflu]_l/wcsto[dflu]_l 2016-08-15 17:35:21 +02:00
strtoumax.c newlib: fix various gcc warnings 2018-08-08 10:50:19 +02:00
system.c ansification: remove _EXFUN, _EXFUN_NOTHROW 2018-01-17 11:47:29 -06:00
utoa.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
valloc.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
wcrtomb.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
wcsnrtombs.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
wcsrtombs.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
wcstod.c stdlib: Use __get_numeric_locale instead of __localeconv_l for decimal_point 2018-09-06 14:14:05 +02:00
wcstoimax.c Importing wcstoimax inttypes method from FreeBSD. 2017-08-02 13:02:26 +02:00
wcstol.c Use remove-advertising-clause script to edit BSD licenses 2020-01-29 19:03:31 +01:00
wcstold.c stdlib: Use __get_numeric_locale instead of __localeconv_l for decimal_point 2018-09-06 14:14:05 +02:00
wcstoll.c Use remove-advertising-clause script to edit BSD licenses 2020-01-29 19:03:31 +01:00
wcstoll_r.c Implement strto[dflu]_l/wcsto[dflu]_l 2016-08-15 17:35:21 +02:00
wcstombs.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
wcstombs_r.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
wcstoul.c Use remove-advertising-clause script to edit BSD licenses 2020-01-29 19:03:31 +01:00
wcstoull.c Use remove-advertising-clause script to edit BSD licenses 2020-01-29 19:03:31 +01:00
wcstoull_r.c Implement strto[dflu]_l/wcsto[dflu]_l 2016-08-15 17:35:21 +02:00
wcstoumax.c Importing wcstoumax inttypes method from FreeBSD. 2017-08-02 13:02:26 +02:00
wctob.c Consolidate wctomb/mbtowc calls for POSIX-1.2008 2016-08-15 10:56:57 +02:00
wctomb.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00
wctomb_r.c ansification: remove _DEFUN 2018-01-17 11:47:26 -06:00