diff options
author | cvs2svn <> | 2013-06-05 11:57:40 +0400 |
---|---|---|
committer | cvs2svn <> | 2013-06-05 11:57:40 +0400 |
commit | 310a2eeef1d094d59ea9897be0ddb1b33869b885 (patch) | |
tree | 6c061f692be2a0be45d81351d4b9dfc06ec9fe9c /newlib/libc/stdlib/nano-mallocr.c | |
parent | c82eac05c783fa1cb82eac9216dab1ed8aa482ae (diff) |
This commit was manufactured by cvs2svn to create tag 'cygwin-cygwin-1_7_19-release
1_7_19-release'.
Sprout from cygwin-64bit-premerge-branch 2013-04-22 17:11:23 UTC cvs2svn 'This commit was manufactured by cvs2svn to create branch 'cygwin-64bit-'
Cherrypick from master 2013-06-05 07:57:39 UTC Corinna Vinschen <corinna@vinschen.de> ' * faq-programming.xml: Convert url to refer to new flat faq.html file.':
COPYING.NEWLIB
ChangeLog
config.guess
config.sub
config/ChangeLog
config/bootstrap-asan.mk
config/dfp.m4
config/picflag.m4
include/ChangeLog
include/elf/ChangeLog
include/elf/aarch64.h
include/elf/common.h
include/elf/mips.h
include/elf/msp430.h
include/opcode/ChangeLog
include/opcode/avr.h
include/opcode/mips.h
include/opcode/msp430.h
newlib/ChangeLog
newlib/MAINTAINERS
newlib/configure
newlib/configure.host
newlib/configure.in
newlib/libc/configure
newlib/libc/configure.in
newlib/libc/ctype/ctype_.c
newlib/libc/ctype/isalnum.c
newlib/libc/ctype/isalpha.c
newlib/libc/ctype/isblank.c
newlib/libc/ctype/iscntrl.c
newlib/libc/ctype/isdigit.c
newlib/libc/ctype/islower.c
newlib/libc/ctype/isprint.c
newlib/libc/ctype/ispunct.c
newlib/libc/ctype/isxdigit.c
newlib/libc/include/machine/ieeefp.h
newlib/libc/include/machine/setjmp.h
newlib/libc/include/reent.h
newlib/libc/include/sys/cdefs.h
newlib/libc/include/sys/config.h
newlib/libc/include/sys/features.h
newlib/libc/include/sys/reent.h
newlib/libc/include/sys/stat.h
newlib/libc/libc.texinfo
newlib/libc/machine/arm/Makefile.am
newlib/libc/machine/arm/Makefile.in
newlib/libc/machine/arm/memcpy-armv7a.S
newlib/libc/machine/arm/memcpy-armv7m.S
newlib/libc/machine/arm/memcpy-stub.c
newlib/libc/machine/arm/memcpy.S
newlib/libc/machine/arm/strcmp.S
newlib/libc/machine/configure
newlib/libc/machine/configure.in
newlib/libc/machine/powerpc/Makefile.am
newlib/libc/machine/powerpc/Makefile.in
newlib/libc/reent/reent.c
newlib/libc/stdio/fgetc.c
newlib/libc/stdio/fgetwc.c
newlib/libc/stdio/fgetws.c
newlib/libc/stdio/findfp.c
newlib/libc/stdio/fputc.c
newlib/libc/stdio/fputwc.c
newlib/libc/stdio/fputws.c
newlib/libc/stdio/getc.c
newlib/libc/stdio/getchar.c
newlib/libc/stdio/local.h
newlib/libc/stdio/putc.c
newlib/libc/stdio/putchar.c
newlib/libc/stdio/scanf.c
newlib/libc/stdio/setvbuf.c
newlib/libc/stdio/ungetwc.c
newlib/libc/stdio/vfscanf.c
newlib/libc/stdio/vfwscanf.c
newlib/libc/stdio/viprintf.c
newlib/libc/stdio/viscanf.c
newlib/libc/stdio/vprintf.c
newlib/libc/stdio/vscanf.c
newlib/libc/stdio/vwprintf.c
newlib/libc/stdio/vwscanf.c
newlib/libc/stdio/wscanf.c
newlib/libc/stdlib/Makefile.am
newlib/libc/stdlib/Makefile.in
newlib/libc/stdlib/__atexit.c
newlib/libc/stdlib/__call_atexit.c
newlib/libc/stdlib/ecvtbuf.c
newlib/libc/stdlib/mblen.c
newlib/libc/stdlib/mbrlen.c
newlib/libc/stdlib/mbrtowc.c
newlib/libc/stdlib/mbtowc.c
newlib/libc/stdlib/nano-mallocr.c
newlib/libc/stdlib/rand.c
newlib/libc/stdlib/strtod.c
newlib/libc/stdlib/wcrtomb.c
newlib/libc/stdlib/wctob.c
newlib/libc/stdlib/wctomb.c
newlib/libc/string/strtok.c
newlib/libc/time/asctime.c
newlib/libc/time/gmtime.c
newlib/libc/time/lcltime.c
newlib/libm/libm.texinfo
winsup/cygserver/ChangeLog
winsup/cygserver/ChangeLog.64bit
winsup/cygserver/Makefile.in
winsup/cygserver/bsd_helper.cc
winsup/cygserver/bsd_helper.h
winsup/cygserver/bsd_log.cc
winsup/cygserver/bsd_log.h
winsup/cygserver/bsd_mutex.cc
winsup/cygserver/client.cc
winsup/cygserver/cygserver.cc
winsup/cygserver/msg.cc
winsup/cygserver/process.h
winsup/cygserver/sem.cc
winsup/cygserver/shm.cc
winsup/cygserver/sysv_shm.cc
winsup/cygserver/threaded_queue.h
winsup/cygwin/ChangeLog
winsup/cygwin/ChangeLog.64bit
winsup/cygwin/Makefile.in
winsup/cygwin/aclocal.m4
winsup/cygwin/advapi32.cc
winsup/cygwin/autoload.cc
winsup/cygwin/automode.c
winsup/cygwin/binmode.c
winsup/cygwin/child_info.h
winsup/cygwin/common.din
winsup/cygwin/configure
winsup/cygwin/configure.ac
winsup/cygwin/cpuid.h
winsup/cygwin/cygerrno.h
winsup/cygwin/cygheap.cc
winsup/cygwin/cygheap.h
winsup/cygwin/cygmagic
winsup/cygwin/cygmalloc.h
winsup/cygwin/cygserver.h
winsup/cygwin/cygserver_ipc.h
winsup/cygwin/cygthread.cc
winsup/cygwin/cygtls.cc
winsup/cygwin/cygtls.h
winsup/cygwin/cygwin.sc.in
winsup/cygwin/dcrt0.cc
winsup/cygwin/debug.h
winsup/cygwin/devices.cc
winsup/cygwin/devices.h
winsup/cygwin/devices.in
winsup/cygwin/dir.cc
winsup/cygwin/dlfcn.cc
winsup/cygwin/dll_init.cc
winsup/cygwin/dll_init.h
winsup/cygwin/dtable.cc
winsup/cygwin/environ.cc
winsup/cygwin/environ.h
winsup/cygwin/errno.cc
winsup/cygwin/exception.h
winsup/cygwin/exceptions.cc
winsup/cygwin/external.cc
winsup/cygwin/fcntl.cc
winsup/cygwin/fenv.cc
winsup/cygwin/fhandler.cc
winsup/cygwin/fhandler.h
winsup/cygwin/fhandler_clipboard.cc
winsup/cygwin/fhandler_console.cc
winsup/cygwin/fhandler_dev.cc
winsup/cygwin/fhandler_disk_file.cc
winsup/cygwin/fhandler_dsp.cc
winsup/cygwin/fhandler_fifo.cc
winsup/cygwin/fhandler_floppy.cc
winsup/cygwin/fhandler_mailslot.cc
winsup/cygwin/fhandler_mem.cc
winsup/cygwin/fhandler_netdrive.cc
winsup/cygwin/fhandler_proc.cc
winsup/cygwin/fhandler_process.cc
winsup/cygwin/fhandler_procnet.cc
winsup/cygwin/fhandler_procsys.cc
winsup/cygwin/fhandler_procsysvipc.cc
winsup/cygwin/fhandler_random.cc
winsup/cygwin/fhandler_raw.cc
winsup/cygwin/fhandler_registry.cc
winsup/cygwin/fhandler_serial.cc
winsup/cygwin/fhandler_socket.cc
winsup/cygwin/fhandler_tape.cc
winsup/cygwin/fhandler_termios.cc
winsup/cygwin/fhandler_tty.cc
winsup/cygwin/fhandler_virtual.cc
winsup/cygwin/fhandler_virtual.h
winsup/cygwin/fhandler_windows.cc
winsup/cygwin/fhandler_zero.cc
winsup/cygwin/flock.cc
winsup/cygwin/fork.cc
winsup/cygwin/gendef
winsup/cygwin/gentls_offsets
winsup/cygwin/glob.cc
winsup/cygwin/globals.cc
winsup/cygwin/grp.cc
winsup/cygwin/heap.cc
winsup/cygwin/hookapi.cc
winsup/cygwin/i686.din
winsup/cygwin/include/a.out.h
winsup/cygwin/include/asm/byteorder.h
winsup/cygwin/include/bits/wordsize.h
winsup/cygwin/include/cygwin/acl.h
winsup/cygwin/include/cygwin/config.h
winsup/cygwin/include/cygwin/cygwin_dll.h
winsup/cygwin/include/cygwin/grp.h
winsup/cygwin/include/cygwin/if.h
winsup/cygwin/include/cygwin/ipc.h
winsup/cygwin/include/cygwin/msg.h
winsup/cygwin/include/cygwin/sem.h
winsup/cygwin/include/cygwin/shm.h
winsup/cygwin/include/cygwin/signal.h
winsup/cygwin/include/cygwin/socket.h
winsup/cygwin/include/cygwin/stat.h
winsup/cygwin/include/cygwin/stdlib.h
winsup/cygwin/include/cygwin/sysproto.h
winsup/cygwin/include/cygwin/time.h
winsup/cygwin/include/cygwin/types.h
winsup/cygwin/include/cygwin/version.h
winsup/cygwin/include/fcntl.h
winsup/cygwin/include/fts.h
winsup/cygwin/include/ftw.h
winsup/cygwin/include/glob.h
winsup/cygwin/include/inttypes.h
winsup/cygwin/include/io.h
winsup/cygwin/include/limits.h
winsup/cygwin/include/mntent.h
winsup/cygwin/include/stdint.h
winsup/cygwin/include/sys/cygwin.h
winsup/cygwin/include/sys/dirent.h
winsup/cygwin/include/sys/resource.h
winsup/cygwin/include/sys/socket.h
winsup/cygwin/include/sys/strace.h
winsup/cygwin/init.cc
winsup/cygwin/ioctl.cc
winsup/cygwin/ipc.cc
winsup/cygwin/kernel32.cc
winsup/cygwin/lc_msg.h
winsup/cygwin/lib/_cygwin_crt0_common.cc
winsup/cygwin/lib/crt0.h
winsup/cygwin/lib/cygwin_attach_dll.c
winsup/cygwin/lib/premain0.c
winsup/cygwin/lib/premain1.c
winsup/cygwin/lib/premain2.c
winsup/cygwin/lib/premain3.c
winsup/cygwin/libc/arc4random.cc
winsup/cygwin/libc/base64.c
winsup/cygwin/libc/bsdlib.cc
winsup/cygwin/libc/fts.c
winsup/cygwin/libc/ftw.c
winsup/cygwin/libc/inet_network.c
winsup/cygwin/libc/minires-os-if.c
winsup/cygwin/libc/minires.c
winsup/cygwin/libc/nftw.c
winsup/cygwin/libc/rcmd.cc
winsup/cygwin/libc/rexec.cc
winsup/cygwin/libstdcxx_wrapper.cc
winsup/cygwin/localtime.cc
winsup/cygwin/malloc_wrapper.cc
winsup/cygwin/miscfuncs.cc
winsup/cygwin/mkimport
winsup/cygwin/mktemp.cc
winsup/cygwin/mmap.cc
winsup/cygwin/mount.cc
winsup/cygwin/mount.h
winsup/cygwin/msg.cc
winsup/cygwin/mtinfo.h
winsup/cygwin/net.cc
winsup/cygwin/netdb.cc
winsup/cygwin/nfs.h
winsup/cygwin/nlsfuncs.cc
winsup/cygwin/ntdll.h
winsup/cygwin/ntea.cc
winsup/cygwin/passwd.cc
winsup/cygwin/path.cc
winsup/cygwin/path.h
winsup/cygwin/perprocess.h
winsup/cygwin/pinfo.cc
winsup/cygwin/pinfo.h
winsup/cygwin/pipe.cc
winsup/cygwin/poll.cc
winsup/cygwin/posix.sgml
winsup/cygwin/posix_ipc.cc
winsup/cygwin/profil.c
winsup/cygwin/profil.h
winsup/cygwin/pseudo-reloc.cc
winsup/cygwin/pwdgrp.h
winsup/cygwin/regex/engine.c
winsup/cygwin/regex/regcomp.c
winsup/cygwin/registry.cc
winsup/cygwin/regparm.h
winsup/cygwin/release/1.7.19
winsup/cygwin/resource.cc
winsup/cygwin/sched.cc
winsup/cygwin/sec_acl.cc
winsup/cygwin/sec_auth.cc
winsup/cygwin/sec_helper.cc
winsup/cygwin/security.cc
winsup/cygwin/security.h
winsup/cygwin/select.cc
winsup/cygwin/select.h
winsup/cygwin/sem.cc
winsup/cygwin/shared.cc
winsup/cygwin/shared_info.h
winsup/cygwin/shm.cc
winsup/cygwin/signal.cc
winsup/cygwin/sigproc.cc
winsup/cygwin/sigproc.h
winsup/cygwin/smallprint.cc
winsup/cygwin/spawn.cc
winsup/cygwin/speclib
winsup/cygwin/spinlock.h
winsup/cygwin/strace.cc
winsup/cygwin/strfuncs.cc
winsup/cygwin/strsig.cc
winsup/cygwin/sync.cc
winsup/cygwin/sync.h
winsup/cygwin/syscalls.cc
winsup/cygwin/sysconf.cc
winsup/cygwin/syslog.cc
winsup/cygwin/termios.cc
winsup/cygwin/textmode.c
winsup/cygwin/textreadmode.c
winsup/cygwin/thread.cc
winsup/cygwin/thread.h
winsup/cygwin/timer.cc
winsup/cygwin/times.cc
winsup/cygwin/tlsoffsets.h
winsup/cygwin/tlsoffsets64.h
winsup/cygwin/tty.cc
winsup/cygwin/tty.h
winsup/cygwin/uinfo.cc
winsup/cygwin/wait.cc
winsup/cygwin/winbase.h
winsup/cygwin/wincap.cc
winsup/cygwin/wincap.h
winsup/cygwin/window.cc
winsup/cygwin/winlean.h
winsup/cygwin/winsup.h
winsup/cygwin/wow64.cc
winsup/cygwin/wow64.h
winsup/cygwin/x86_64.din
winsup/doc/.cvsignore
winsup/doc/ChangeLog
winsup/doc/Makefile.in
winsup/doc/Wishlist
winsup/doc/bodysnatcher.pl
winsup/doc/configure
winsup/doc/configure.ac
winsup/doc/cygserver.xml
winsup/doc/cygwin-api.in.xml
winsup/doc/cygwin-ug-net.xml
winsup/doc/cygwin.xsl
winsup/doc/cygwinenv.xml
winsup/doc/dll.xml
winsup/doc/effectively.xml
winsup/doc/faq-api.xml
winsup/doc/faq-copyright.xml
winsup/doc/faq-programming.xml
winsup/doc/faq-resources.xml
winsup/doc/faq-setup.xml
winsup/doc/faq-using.xml
winsup/doc/faq-what.xml
winsup/doc/faq.xml
winsup/doc/filemodes.xml
winsup/doc/gcc.xml
winsup/doc/gdb.xml
winsup/doc/highlights.xml
winsup/doc/legal.xml
winsup/doc/new-features.xml
winsup/doc/ntsec.xml
winsup/doc/ov-ex-unix.xml
winsup/doc/ov-ex-win.xml
winsup/doc/overview.xml
winsup/doc/pathnames.xml
winsup/doc/programming.xml
winsup/doc/setup-env.xml
winsup/doc/setup-files.xml
winsup/doc/setup-locale.xml
winsup/doc/setup-maxmem.xml
winsup/doc/setup-net.xml
winsup/doc/specialnames.xml
winsup/doc/textbinary.xml
winsup/doc/ug-info.xml
winsup/doc/using.xml
winsup/doc/windres.xml
winsup/doc/xidepend
winsup/lsaauth/ChangeLog
winsup/lsaauth/ChangeLog.64bit
winsup/lsaauth/Makefile.in
winsup/lsaauth/configure
winsup/lsaauth/configure.ac
winsup/utils/ChangeLog
winsup/utils/ChangeLog.64bit
winsup/utils/Makefile.in
winsup/utils/aclocal.m4
winsup/utils/configure
winsup/utils/cygcheck.cc
winsup/utils/dumper.cc
winsup/utils/dumper.h
winsup/utils/kill.cc
winsup/utils/ldd.cc
winsup/utils/locale.cc
winsup/utils/mkgroup.c
winsup/utils/mkpasswd.c
winsup/utils/module_info.cc
winsup/utils/mount.cc
winsup/utils/parse_pe.cc
winsup/utils/passwd.c
winsup/utils/path.cc
winsup/utils/ps.cc
winsup/utils/regtool.cc
winsup/utils/ssp.c
winsup/utils/strace.cc
winsup/utils/tzset.c
winsup/utils/utils.xml
Delete:
COPYING3
COPYING3.LIB
config.rpath
configure.ac
ltgcc.m4
newlib/libc/machine/aarch64/Makefile.am
newlib/libc/machine/aarch64/Makefile.in
newlib/libc/machine/aarch64/aclocal.m4
newlib/libc/machine/aarch64/configure
newlib/libc/machine/aarch64/configure.in
newlib/libc/machine/aarch64/memcmp-stub.c
newlib/libc/machine/aarch64/memcmp.S
newlib/libc/machine/aarch64/memcpy-stub.c
newlib/libc/machine/aarch64/memcpy.S
newlib/libc/machine/aarch64/memmove-stub.c
newlib/libc/machine/aarch64/memmove.S
newlib/libc/machine/aarch64/memset-stub.c
newlib/libc/machine/aarch64/memset.S
newlib/libc/machine/aarch64/setjmp.S
newlib/libc/machine/aarch64/strcmp-stub.c
newlib/libc/machine/aarch64/strcmp.S
newlib/libc/machine/aarch64/strlen-stub.c
newlib/libc/machine/aarch64/strlen.S
newlib/libc/machine/aarch64/strncmp-stub.c
newlib/libc/machine/aarch64/strncmp.S
newlib/libc/machine/aarch64/strnlen-stub.c
newlib/libc/machine/aarch64/strnlen.S
newlib/libc/machine/epiphany/Makefile.am
newlib/libc/machine/epiphany/Makefile.in
newlib/libc/machine/epiphany/aclocal.m4
newlib/libc/machine/epiphany/configure
newlib/libc/machine/epiphany/configure.in
newlib/libc/machine/epiphany/machine/stdlib.h
newlib/libc/machine/epiphany/setjmp.S
newlib/libc/machine/powerpc/times.c
newlib/libc/sys/epiphany/Makefile.am
newlib/libc/sys/epiphany/Makefile.in
newlib/libc/sys/epiphany/aclocal.m4
newlib/libc/sys/epiphany/configure
newlib/libc/sys/epiphany/configure.in
newlib/libc/sys/epiphany/e_printf.c
newlib/libm/machine/aarch64/Makefile.am
newlib/libm/machine/aarch64/Makefile.in
newlib/libm/machine/aarch64/aclocal.m4
newlib/libm/machine/aarch64/configure
newlib/libm/machine/aarch64/configure.in
newlib/libm/machine/aarch64/s_ceil.c
newlib/libm/machine/aarch64/s_floor.c
newlib/libm/machine/aarch64/s_fma.c
newlib/libm/machine/aarch64/s_fmax.c
newlib/libm/machine/aarch64/s_fmin.c
newlib/libm/machine/aarch64/s_llrint.c
newlib/libm/machine/aarch64/s_llround.c
newlib/libm/machine/aarch64/s_lrint.c
newlib/libm/machine/aarch64/s_lround.c
newlib/libm/machine/aarch64/s_nearbyint.c
newlib/libm/machine/aarch64/s_rint.c
newlib/libm/machine/aarch64/s_round.c
newlib/libm/machine/aarch64/s_trunc.c
newlib/libm/machine/aarch64/sf_ceil.c
newlib/libm/machine/aarch64/sf_floor.c
newlib/libm/machine/aarch64/sf_fma.c
newlib/libm/machine/aarch64/sf_fmax.c
newlib/libm/machine/aarch64/sf_fmin.c
newlib/libm/machine/aarch64/sf_llrint.c
newlib/libm/machine/aarch64/sf_llround.c
newlib/libm/machine/aarch64/sf_lrint.c
newlib/libm/machine/aarch64/sf_lround.c
newlib/libm/machine/aarch64/sf_nearbyint.c
newlib/libm/machine/aarch64/sf_rint.c
newlib/libm/machine/aarch64/sf_round.c
newlib/libm/machine/aarch64/sf_trunc.c
winsup/cygwin/cygwin.din
winsup/cygwin/cygwin.sc
winsup/doc/cygserver.sgml
winsup/doc/cygwin-api.in.sgml
winsup/doc/cygwin-ug-net.in.sgml
winsup/doc/cygwin-ug.in.sgml
winsup/doc/cygwin.dsl
winsup/doc/cygwinenv.sgml
winsup/doc/dll.sgml
winsup/doc/effectively.sgml
winsup/doc/faq-sections.xml
winsup/doc/filemodes.sgml
winsup/doc/gcc.sgml
winsup/doc/gdb.sgml
winsup/doc/legal.sgml
winsup/doc/new-features.sgml
winsup/doc/ntsec.sgml
winsup/doc/overview.sgml
winsup/doc/overview2.sgml
winsup/doc/pathnames.sgml
winsup/doc/programming.sgml
winsup/doc/setup-net.sgml
winsup/doc/setup.sgml
winsup/doc/setup2.sgml
winsup/doc/textbinary.sgml
winsup/doc/using.sgml
winsup/doc/windres.sgml
winsup/utils/utils.sgml
Diffstat (limited to 'newlib/libc/stdlib/nano-mallocr.c')
-rw-r--r-- | newlib/libc/stdlib/nano-mallocr.c | 581 |
1 files changed, 581 insertions, 0 deletions
diff --git a/newlib/libc/stdlib/nano-mallocr.c b/newlib/libc/stdlib/nano-mallocr.c new file mode 100644 index 000000000..e0a919590 --- /dev/null +++ b/newlib/libc/stdlib/nano-mallocr.c @@ -0,0 +1,581 @@ +/* + * Copyright (c) 2012, 2013 ARM Ltd + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the company may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* Implementation of <<malloc>> <<free>> <<calloc>> <<realloc>>, optional + * as to be reenterable. + * + * Interface documentation refer to malloc.c. + */ + +#include <stdio.h> +#include <string.h> +#include <errno.h> + +#if DEBUG +#include <assert.h> +#else +#define assert(x) ((void)0) +#endif + +#ifndef MAX +#define MAX(a,b) ((a) >= (b) ? (a) : (b)) +#endif + +#ifdef INTERNAL_NEWLIB + +#include <sys/config.h> +#include <reent.h> + +#define RARG struct _reent *reent_ptr, +#define RONEARG struct _reent *reent_ptr +#define RCALL reent_ptr, + +/* Disable MALLOC_LOCK so far. So it won't be thread safe */ +#define MALLOC_LOCK /*__malloc_lock(reent_ptr) */ +#define MALLOC_UNLOCK /*__malloc_unlock(reent_ptr) */ + +#define RERRNO reent_ptr->_errno + +#define nano_malloc _malloc_r +#define nano_free _free_r +#define nano_realloc _realloc_r +#define nano_memalign _memalign_r +#define nano_valloc _valloc_r +#define nano_pvalloc _pvalloc_r +#define nano_calloc _calloc_r +#define nano_cfree _cfree_r +#define nano_malloc_usable_size _malloc_usable_size_r +#define nano_malloc_stats _malloc_stats_r +#define nano_mallinfo _mallinfo_r +#define nano_allopt _mallopt_r + +#else /* ! INTERNAL_NEWLIB */ + +#define RARG +#define RONEARG +#define RCALL +#define MALLOC_LOCK +#define MALLOC_UNLOCK +#define RERRNO errno + +#define nano_malloc malloc +#define nano_free free +#define nano_realloc realloc +#define nano_memalign memalign +#define nano_valloc valloc +#define nano_pvalloc pvalloc +#define nano_calloc calloc +#define nano_cfree cfree +#define nano_malloc_usable_size malloc_usable_size +#define nano_malloc_stats malloc_stats +#define nano_mallinfo mallinfo +#define nano_allopt mallopt +#endif /* ! INTERNAL_NEWLIB */ + +/* Define free_list as internal name to avoid conflict with user names */ +#define free_list __malloc_free_list + +#define ALIGN_TO(size, align) \ + (((size) + (align) -1) & ~((align) -1)) + +/* Alignment of allocated block */ +#define MALLOC_ALIGN (8U) +#define CHUNK_ALIGN (sizeof(void*)) +#define MALLOC_PADDING ((MAX(MALLOC_ALIGN, CHUNK_ALIGN)) - CHUNK_ALIGN) + +/* as well as the minimal allocation size + * to hold a free pointer */ +#define MALLOC_MINSIZE (sizeof(void *)) +#define MALLOC_PAGE_ALIGN (0x1000) +#define MAX_ALLOC_SIZE (0x80000000U) + +typedef size_t malloc_size_t; + +typedef struct malloc_chunk +{ + /* ------------------ + * chunk->| size (4 bytes) | + * ------------------ + * | Padding for | + * | alignment | + * | holding neg | + * | offset to size | + * ------------------ + * mem_ptr->| point to next | + * | free when freed| + * | or data load | + * | when allocated | + * ------------------ + */ + /* size of the allocated payload area, including size before + CHUNK_OFFSET */ + int size; + + /* since here, the memory is either the next free block, or data load */ + struct malloc_chunk * next; +}chunk; + +#define CHUNK_OFFSET ((malloc_size_t)(&(((struct malloc_chunk *)0)->next))) + +/* size of smallest possible chunk. A memory piece smaller than this size + * won't be able to create a chunk */ +#define MALLOC_MINCHUNK (CHUNK_OFFSET + MALLOC_PADDING + MALLOC_MINSIZE) + +static chunk * get_chunk_from_ptr(void * ptr) +{ + chunk * c = (chunk *)((char *)ptr - CHUNK_OFFSET); + /* Skip the padding area */ + if (c->size < 0) c = (chunk *)((char *)c + c->size); + return c; +} + +#ifdef DEFINE_MALLOC +chunk * free_list = NULL; + +/** Function sbrk_aligned + * Algorithm: + * Use sbrk() to obtain more memory and ensure it is CHUNK_ALIGN aligned + * Optimise for the case that it is already aligned - only ask for extra + * padding after we know we need it + */ +static void* sbrk_aligned(RARG malloc_size_t s) +{ + char *p, *align_p; + + p = _sbrk_r(RCALL s); + + /* sbrk returns -1 if fail to allocate */ + if (p == (void *)-1) + return p; + + align_p = (char*)ALIGN_TO((unsigned long)p, CHUNK_ALIGN); + if (align_p != p) + { + /* p is not aligned, ask for a few more bytes so that we have s + * bytes reserved from align_p. */ + p = _sbrk_r(RCALL align_p - p); + if (p == (void *)-1) + return p; + } + return align_p; +} + +/** Function nano_malloc + * Algorithm: + * Walk through the free list to find the first match. If fails to find + * one, call sbrk to allocate a new chunk. + */ +void * nano_malloc(RARG malloc_size_t s) +{ + chunk *p, *r; + char * ptr, * align_ptr; + int offset; + + malloc_size_t alloc_size; + + alloc_size = ALIGN_TO(s, CHUNK_ALIGN); /* size of aligned data load */ + alloc_size += MALLOC_PADDING; /* padding */ + alloc_size += CHUNK_OFFSET; /* size of chunk head */ + alloc_size = MAX(alloc_size, MALLOC_MINCHUNK); + + if (alloc_size >= MAX_ALLOC_SIZE || alloc_size < s) + { + RERRNO = ENOMEM; + return NULL; + } + + MALLOC_LOCK; + + p = free_list; + r = p; + + while (r) + { + int rem = r->size - alloc_size; + if (rem >= 0) + { + if (rem >= MALLOC_MINCHUNK) + { + /* Find a chunk that much larger than required size, break + * it into two chunks and return the second one */ + r->size = rem; + r = (chunk *)((char *)r + rem); + r->size = alloc_size; + } + /* Find a chunk that is exactly the size or slightly bigger + * than requested size, just return this chunk */ + else if (p == r) + { + /* Now it implies p==r==free_list. Move the free_list + * to next chunk */ + free_list = r->next; + } + else + { + /* Normal case. Remove it from free_list */ + p->next = r->next; + } + break; + } + p=r; + r=r->next; + } + + /* Failed to find a appropriate chunk. Ask for more memory */ + if (r == NULL) + { + r = sbrk_aligned(RCALL alloc_size); + + /* sbrk returns -1 if fail to allocate */ + if (r == (void *)-1) + { + RERRNO = ENOMEM; + MALLOC_UNLOCK; + return NULL; + } + r->size = alloc_size; + } + MALLOC_UNLOCK; + + ptr = (char *)r + CHUNK_OFFSET; + + align_ptr = (char *)ALIGN_TO((unsigned long)ptr, MALLOC_ALIGN); + offset = align_ptr - ptr; + + if (offset) + { + *(int *)((char *)r + offset) = -offset; + } + + assert(align_ptr + size <= (char *)r + alloc_size); + return align_ptr; +} +#endif /* DEFINE_MALLOC */ + +#ifdef DEFINE_FREE +#define MALLOC_CHECK_DOUBLE_FREE + +extern chunk * free_list; +/** Function nano_free + * Implementation of libc free. + * Algorithm: + * Maintain a global free chunk single link list, headed by global + * variable free_list. + * When free, insert the to-be-freed chunk into free list. The place to + * insert should make sure all chunks are sorted by address from low to + * high. Then merge with neighbor chunks if adjacent. + */ +void nano_free (RARG void * free_p) +{ + chunk * p_to_free; + chunk * p, * q; + + if (free_p == NULL) return; + + p_to_free = get_chunk_from_ptr(free_p); + + MALLOC_LOCK; + if (free_list == NULL) + { + /* Set first free list element */ + p_to_free->next = free_list; + free_list = p_to_free; + MALLOC_UNLOCK; + return; + } + + if (p_to_free < free_list) + { + if ((char *)p_to_free + p_to_free->size == (char *)free_list) + { + /* Chunk to free is just before the first element of + * free list */ + p_to_free->size += free_list->size; + p_to_free->next = free_list->next; + } + else + { + /* Insert before current free_list */ + p_to_free->next = free_list; + } + free_list = p_to_free; + MALLOC_UNLOCK; + return; + } + + q = free_list; + /* Walk through the free list to find the place for insert. */ + do + { + p = q; + q = q->next; + } while (q && q <= p_to_free); + + /* Now p <= p_to_free and either q == NULL or q > p_to_free + * Try to merge with chunks immediately before/after it. */ + + if ((char *)p + p->size == (char *)p_to_free) + { + /* Chunk to be freed is adjacent + * to a free chunk before it */ + p->size += p_to_free->size; + /* If the merged chunk is also adjacent + * to the chunk after it, merge again */ + if ((char *)p + p->size == (char *) q) + { + p->size += q->size; + p->next = q->next; + } + } +#ifdef MALLOC_CHECK_DOUBLE_FREE + else if ((char *)p + p->size > (char *)p_to_free) + { + /* Report double free fault */ + RERRNO = ENOMEM; + MALLOC_UNLOCK; + return; + } +#endif + else if ((char *)p_to_free + p_to_free->size == (char *) q) + { + /* Chunk to be freed is adjacent + * to a free chunk after it */ + p_to_free->size += q->size; + p_to_free->next = q->next; + p->next = p_to_free; + } + else + { + /* Not adjacent to any chunk. Just insert it. Resulting + * a fragment. */ + p_to_free->next = q; + p->next = p_to_free; + } + MALLOC_UNLOCK; +} +#endif /* DEFINE_FREE */ + +#ifdef DEFINE_CFREE +void nano_free (RARG void * free_p); + +void nano_cfree(RARG void * ptr) +{ + nano_free(RCALL ptr); +} +#endif /* DEFINE_CFREE */ + +#ifdef DEFINE_CALLOC +void * nano_malloc(RARG malloc_size_t s); + +/* Function nano_calloc + * Implement calloc simply by calling malloc and set zero */ +void * nano_calloc(RARG malloc_size_t n, malloc_size_t elem) +{ + void * mem = nano_malloc(RCALL n * elem); + if (mem != NULL) memset(mem, 0, n * elem); + return mem; +} +#endif /* DEFINE_CALLOC */ + +#ifdef DEFINE_REALLOC +void * nano_malloc(RARG malloc_size_t s); +void nano_free (RARG void * free_p); +malloc_size_t nano_malloc_usable_size(RARG void * ptr); + +/* Function nano_realloc + * Implement realloc by malloc + memcpy */ +void * nano_realloc(RARG void * ptr, malloc_size_t size) +{ + void * mem; + chunk * p_to_realloc; + + if (ptr == NULL) return nano_malloc(RCALL size); + + if (size == 0) + { + nano_free(RCALL ptr); + return NULL; + } + + /* TODO: There is chance to shrink the chunk if newly requested + * size is much small */ + if (nano_malloc_usable_size(RCALL ptr) >= size) + return ptr; + + mem = nano_malloc(RCALL size); + if (mem != NULL) + { + memcpy(mem, ptr, size); + nano_free(RCALL ptr); + } + return mem; +} +#endif /* DEFINE_REALLOC */ + +#ifdef DEFINE_MALLINFO +struct mallinfo +{ + int arena; /* total space allocated from system */ + int ordblks; /* number of non-inuse chunks */ + int smblks; /* unused -- always zero */ + int hblks; /* number of mmapped regions */ + int hblkhd; /* total space in mmapped regions */ + int usmblks; /* unused -- always zero */ + int fsmblks; /* unused -- always zero */ + int uordblks; /* total allocated space */ + int fordblks; /* total non-inuse space */ + int keepcost; /* top-most, releasable (via malloc_trim) space */ +}; + +static struct mallinfo current_mallinfo={0,0,0,0,0,0,0,0,0,0}; + +struct mallinfo nano_mallinfo(RONEARG) +{ + return current_mallinfo; +} + +#endif /* DEFINE_MALLINFO */ + +#ifdef DEFINE_MALLOC_STATS +void nano_malloc_stats(RONEARG) +{ +} +#endif /* DEFINE_MALLOC_STATS */ + +#ifdef DEFINE_MALLOC_USABLE_SIZE +malloc_size_t nano_malloc_usable_size(RARG void * ptr) +{ + chunk * c = (chunk *)((char *)ptr - CHUNK_OFFSET); + int size_or_offset = c->size; + + if (size_or_offset < 0) + { + /* Padding is used. Excluding the padding size */ + c = (chunk *)((char *)c + c->size); + return c->size - CHUNK_OFFSET + size_or_offset; + } + return c->size - CHUNK_OFFSET; +} +#endif /* DEFINE_MALLOC_USABLE_SIZE */ + +#ifdef DEFINE_MEMALIGN +void * nano_malloc(RARG malloc_size_t s); + +/* Function nano_memalign + * Allocate memory block aligned at specific boundary. + * align: required alignment. Must be power of 2. Return NULL + * if not power of 2. Undefined behavior is bigger than + * pointer value range. + * s: required size. + * Return: allocated memory pointer aligned to align + * Algorithm: Malloc a big enough block, padding pointer to aligned + * address, then truncate and free the tail if too big. + * Record the offset of align pointer and original pointer + * in the padding area. + */ +void * nano_memalign(RARG size_t align, size_t s) +{ + chunk * chunk_p; + malloc_size_t size_allocated, offset, ma_size, size_with_padding; + char * allocated, * aligned_p; + + /* Return NULL if align isn't power of 2 */ + if ((align & (align-1)) != 0) return NULL; + + align = MAX(align, MALLOC_ALIGN); + ma_size = ALIGN_TO(MAX(s, MALLOC_MINSIZE), CHUNK_ALIGN); + size_with_padding = ma_size + align - MALLOC_ALIGN; + + allocated = nano_malloc(RCALL size_with_padding); + if (allocated == NULL) return NULL; + + chunk_p = get_chunk_from_ptr(allocated); + aligned_p = (char *)ALIGN_TO( + (unsigned long)((char *)chunk_p + CHUNK_OFFSET), + (unsigned long)align); + offset = aligned_p - ((char *)chunk_p + CHUNK_OFFSET); + + if (offset) + { + if (offset >= MALLOC_MINCHUNK) + { + /* Padding is too large, free it */ + chunk * front_chunk = chunk_p; + chunk_p = (chunk *)((char *)chunk_p + offset); + chunk_p->size = front_chunk->size - offset; + front_chunk->size = offset; + nano_free(RCALL (char *)front_chunk + CHUNK_OFFSET); + } + else + { + /* Padding is used. Need to set a jump offset for aligned pointer + * to get back to chunk head */ + assert(offset >= sizeof(int)); + *(int *)((char *)chunk_p + offset) = -offset; + } + } + + size_allocated = chunk_p->size; + if ((char *)chunk_p + size_allocated > + (aligned_p + ma_size + MALLOC_MINCHUNK)) + { + /* allocated much more than what's required for padding, free + * tail part */ + chunk * tail_chunk = (chunk *)(aligned_p + ma_size); + chunk_p->size = aligned_p + ma_size - (char *)chunk_p; + tail_chunk->size = size_allocated - chunk_p->size; + nano_free(RCALL (char *)tail_chunk + CHUNK_OFFSET); + } + return aligned_p; +} +#endif /* DEFINE_MEMALIGN */ + +#ifdef DEFINE_MALLOPT +int nano_mallopt(RARG int parameter_number, int parameter_value) +{ + return 0; +} +#endif /* DEFINE_MALLOPT */ + +#ifdef DEFINE_VALLOC +void * nano_memalign(RARG size_t align, size_t s); + +void * nano_valloc(RARG size_t s) +{ + return nano_memalign(RCALL MALLOC_PAGE_ALIGN, s); +} +#endif /* DEFINE_VALLOC */ + +#ifdef DEFINE_PVALLOC +void * nano_valloc(RARG size_t s); + +void * nano_pvalloc(RARG size_t s) +{ + return nano_valloc(RCALL ALIGN_TO(s, MALLOC_PAGE_ALIGN)); +} +#endif /* DEFINE_PVALLOC */ |