405 lines
14 KiB
C
405 lines
14 KiB
C
#ifndef _CHIPRAM_MALLOC_H__
|
|||
|
|
#define _CHIPRAM_MALLOC_H__
|
||
|
|
|
||
|
|
/* Preliminaries */
|
||
|
|
|
||
|
|
#ifndef __STD_C
|
||
|
|
#ifdef __STDC__
|
||
|
|
#define __STD_C 1
|
||
|
|
#else
|
||
|
|
#if __cplusplus
|
||
|
|
#define __STD_C 1
|
||
|
|
#else
|
||
|
|
#define __STD_C 0
|
||
|
|
#endif /*__cplusplus*/
|
||
|
|
#endif /*__STDC__*/
|
||
|
|
#endif /*__STD_C*/
|
||
|
|
|
||
|
|
#ifndef Void_t
|
||
|
|
#if (__STD_C || defined(WIN32))
|
||
|
|
#define Void_t void
|
||
|
|
#else
|
||
|
|
#define Void_t char
|
||
|
|
#endif
|
||
|
|
#endif /*Void_t*/
|
||
|
|
|
||
|
|
#if __STD_C
|
||
|
|
#include <linux/stddef.h> /* for size_t */
|
||
|
|
#else
|
||
|
|
#include <sys/types.h>
|
||
|
|
#endif /* __STD_C */
|
||
|
|
|
||
|
|
#ifdef __cplusplus
|
||
|
|
extern "C" {
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#if 0 /* not for U-Boot */
|
||
|
|
#include <stdio.h> /* needed for malloc_stats */
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#ifdef DEBUG
|
||
|
|
#define assert(x) ((void)(0))
|
||
|
|
#else
|
||
|
|
#define assert(x) ((void)(0))
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#ifndef INTERNAL_SIZE_T
|
||
|
|
#define INTERNAL_SIZE_T size_t /* int */
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/* #define WIN32 */
|
||
|
|
#ifdef WIN32
|
||
|
|
#define MORECORE wsbrk
|
||
|
|
#define HAVE_MMAP 0 /* memory map */
|
||
|
|
|
||
|
|
#define LACKS_UNISTD_H /* lacks unistd */
|
||
|
|
#define LACKS_SYS_PARAM_H
|
||
|
|
|
||
|
|
#define WIN32_LEAN_AND_MEAN /* win32 lean and mean */
|
||
|
|
#include <windows.h>
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/* HAVE_MEMCPY */
|
||
|
|
#define HAVE_MEMCPY /* memcpy */
|
||
|
|
|
||
|
|
#ifndef USE_MEMCPY
|
||
|
|
#ifdef HAVE_MEMCPY
|
||
|
|
#define USE_MEMCPY 1 /* always 1 */
|
||
|
|
#else
|
||
|
|
#define USE_MEMCPY 0
|
||
|
|
#endif
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/* sprd func def */
|
||
|
|
#if (__STD_C || defined(HAVE_MEMCPY))
|
||
|
|
#if __STD_C
|
||
|
|
void* sprd_memset(void*, int, size_t);
|
||
|
|
void* sprd_memcpy(void*, const void*, size_t);
|
||
|
|
#else /* not standard c */
|
||
|
|
#ifdef WIN32
|
||
|
|
/* already have def in windows.h */
|
||
|
|
#else /* not stand c , not win32*/
|
||
|
|
Void_t* sprd_memset();
|
||
|
|
Void_t* sprd_memcpy();
|
||
|
|
#endif
|
||
|
|
#endif
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#if USE_MEMCPY
|
||
|
|
/* The following macros are only called by (2n+1)-multiples
|
||
|
|
INTERNAL_SIZE_T units, a positive integer n. This is being exploited
|
||
|
|
When n is very small, it is used for fast inline execution. */
|
||
|
|
|
||
|
|
#define MALLOC_ZERO(charp, mbytes) \
|
||
|
|
do { \
|
||
|
|
INTERNAL_SIZE_T mzerosz = (mbytes); \
|
||
|
|
if(mzerosz <= 9*sizeof(mzerosz)) { \
|
||
|
|
INTERNAL_SIZE_T* mz = (INTERNAL_SIZE_T*) (charp); \
|
||
|
|
if(mzerosz >= 5*sizeof(mzerosz)) { *mz++ = 0; \
|
||
|
|
*mz++ = 0; \
|
||
|
|
if(mzerosz >= 7*sizeof(mzerosz)) { *mz++ = 0; \
|
||
|
|
*mz++ = 0; \
|
||
|
|
if(mzerosz >= 9*sizeof(mzerosz)) { *mz++ = 0; \
|
||
|
|
*mz++ = 0; }}} \
|
||
|
|
*mz++ = 0; \
|
||
|
|
*mz++ = 0; \
|
||
|
|
*mz = 0; \
|
||
|
|
} else memset((charp), 0, mzerosz); \
|
||
|
|
} while(0)
|
||
|
|
|
||
|
|
#define MALLOC_COPY(dest,src,mbytes) \
|
||
|
|
do { \
|
||
|
|
INTERNAL_SIZE_T mcpysz = (mbytes); \
|
||
|
|
if(mcpysz <= 9*sizeof(mcpysz)) { \
|
||
|
|
INTERNAL_SIZE_T* mcpysrc = (INTERNAL_SIZE_T*) (src); \
|
||
|
|
INTERNAL_SIZE_T* mcpydst = (INTERNAL_SIZE_T*) (dest); \
|
||
|
|
if(mcpysz >= 5*sizeof(mcpysz)) { *mcpydst++ = *mcpysrc++; \
|
||
|
|
*mcpydst++ = *mcpysrc++; \
|
||
|
|
if(mcpysz >= 7*sizeof(mcpysz)) { *mcpydst++ = *mcpysrc++; \
|
||
|
|
*mcpydst++ = *mcpysrc++; \
|
||
|
|
if(mcpysz >= 9*sizeof(mcpysz)) { *mcpydst++ = *mcpysrc++; \
|
||
|
|
*mcpydst++ = *mcpysrc++; }}} \
|
||
|
|
*mcpydst++ = *mcpysrc++; \
|
||
|
|
*mcpydst++ = *mcpysrc++; \
|
||
|
|
*mcpydst = *mcpysrc ; \
|
||
|
|
} else sprd_memcpy(dest, src, mcpysz); \
|
||
|
|
} while(0)
|
||
|
|
|
||
|
|
#else /* !USE_MEMCPY */
|
||
|
|
|
||
|
|
/* Use Duff's device for good zeroing/copying performance. */
|
||
|
|
|
||
|
|
#define MALLOC_ZERO(charp, mbytes) \
|
||
|
|
do { \
|
||
|
|
INTERNAL_SIZE_T* mzerop = (INTERNAL_SIZE_T*)(charp); \
|
||
|
|
long mctmp = (mbytes)/sizeof(INTERNAL_SIZE_T), mcn; \
|
||
|
|
if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp %= 8; } \
|
||
|
|
switch (mctmp) { \
|
||
|
|
case 0: for(;;) { *mzerop++ = 0; \
|
||
|
|
case 7: *mzerop++ = 0; \
|
||
|
|
case 6: *mzerop++ = 0; \
|
||
|
|
case 5: *mzerop++ = 0; \
|
||
|
|
case 4: *mzerop++ = 0; \
|
||
|
|
case 3: *mzerop++ = 0; \
|
||
|
|
case 2: *mzerop++ = 0; \
|
||
|
|
case 1: *mzerop++ = 0; if(mcn <= 0) break; mcn--; } \
|
||
|
|
} \
|
||
|
|
} while(0)
|
||
|
|
|
||
|
|
#define MALLOC_COPY(dest,src,mbytes) \
|
||
|
|
do { \
|
||
|
|
INTERNAL_SIZE_T* mcpysrc = (INTERNAL_SIZE_T*) src; \
|
||
|
|
INTERNAL_SIZE_T* mcpydst = (INTERNAL_SIZE_T*) dest; \
|
||
|
|
long mctmp = (mbytes)/sizeof(INTERNAL_SIZE_T), mcn; \
|
||
|
|
if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp %= 8; } \
|
||
|
|
switch (mctmp) { \
|
||
|
|
case 0: for(;;) { *mcpydst++ = *mcpysrc++; \
|
||
|
|
case 7: *mcpydst++ = *mcpysrc++; \
|
||
|
|
case 6: *mcpydst++ = *mcpysrc++; \
|
||
|
|
case 5: *mcpydst++ = *mcpysrc++; \
|
||
|
|
case 4: *mcpydst++ = *mcpysrc++; \
|
||
|
|
case 3: *mcpydst++ = *mcpysrc++; \
|
||
|
|
case 2: *mcpydst++ = *mcpysrc++; \
|
||
|
|
case 1: *mcpydst++ = *mcpysrc++; if(mcn <= 0) break; mcn--; } \
|
||
|
|
} \
|
||
|
|
} while(0)
|
||
|
|
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#undef HAVE_MMAP /* Not available for U-Boot */
|
||
|
|
#undef HAVE_MREMAP /* Not available for U-Boot */
|
||
|
|
|
||
|
|
#define LACKS_UNISTD_H
|
||
|
|
#define malloc_getpagesize (4096)
|
||
|
|
|
||
|
|
#ifndef malloc_getpagesize
|
||
|
|
# ifdef _SC_PAGESIZE
|
||
|
|
# ifndef _SC_PAGE_SIZE
|
||
|
|
# define _SC_PAGE_SIZE _SC_PAGESIZE
|
||
|
|
# endif
|
||
|
|
# endif
|
||
|
|
# ifdef _SC_PAGE_SIZE
|
||
|
|
# define malloc_getpagesize sysconf(_SC_PAGE_SIZE)
|
||
|
|
# else /* ifdef malloc_getpagesize */
|
||
|
|
# if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE)
|
||
|
|
extern size_t getpagesize();
|
||
|
|
# define malloc_getpagesize getpagesize()
|
||
|
|
# else /* ifndef BSD DGUX HAVE_GETPAGESIZE */
|
||
|
|
# ifdef WIN32
|
||
|
|
# define malloc_getpagesize (4096) /* malloc_getpagesize */
|
||
|
|
# else /* not win32 */
|
||
|
|
# ifndef LACKS_SYS_PARAM_H /* include some file */
|
||
|
|
# include <sys/param.h>
|
||
|
|
# endif
|
||
|
|
# ifdef EXEC_PAGESIZE
|
||
|
|
# define malloc_getpagesize EXEC_PAGESIZE /* def malloc_getpagesize */
|
||
|
|
# else /* ifndef EXEC_PAGESIZE */
|
||
|
|
# ifdef NBPG
|
||
|
|
# ifndef CLSIZE
|
||
|
|
# define malloc_getpagesize NBPG /* def malloc_getpagesize */
|
||
|
|
# else /* ifdef CLSIZE */
|
||
|
|
# define malloc_getpagesize (NBPG * CLSIZE) /* def malloc_getpagesize */
|
||
|
|
# endif
|
||
|
|
# else /* ifndef NBPG */
|
||
|
|
# ifdef NBPC
|
||
|
|
# define malloc_getpagesize NBPC /* def malloc_getpagesize */
|
||
|
|
# else /* ifndef NBPC */
|
||
|
|
# ifdef PAGESIZE
|
||
|
|
# define malloc_getpagesize PAGESIZE /* def malloc_getpagesize */
|
||
|
|
# else /* ifndef PAGESIZE */
|
||
|
|
# define malloc_getpagesize (4096) /* not ecactly */
|
||
|
|
# endif
|
||
|
|
# endif
|
||
|
|
# endif
|
||
|
|
# endif
|
||
|
|
# endif
|
||
|
|
# endif
|
||
|
|
# endif
|
||
|
|
#endif
|
||
|
|
|
||
|
|
|
||
|
|
#if HAVE_USR_INCLUDE_MALLOC_H
|
||
|
|
#include "/usr/include/malloc.h"
|
||
|
|
#else
|
||
|
|
|
||
|
|
struct mallinfo {
|
||
|
|
int arena;
|
||
|
|
int ordblks;
|
||
|
|
int smblks; /* always zero */
|
||
|
|
int hblks;
|
||
|
|
int hblkhd;
|
||
|
|
int usmblks; /* always zero */
|
||
|
|
int fsmblks; /* always zero */
|
||
|
|
int uordblks;
|
||
|
|
int fordblks;
|
||
|
|
int keepcost;
|
||
|
|
};
|
||
|
|
|
||
|
|
#define M_MXFAST 1 /* useless */
|
||
|
|
#define M_NLBLKS 2 /* useless */
|
||
|
|
#define M_GRAIN 3 /* useless */
|
||
|
|
#define M_KEEP 4 /* useless */
|
||
|
|
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#define M_TRIM_THRESHOLD -1 /* actually do something */
|
||
|
|
#define M_TOP_PAD -2 /* actually do something */
|
||
|
|
#define M_MMAP_THRESHOLD -3 /* actually do something */
|
||
|
|
#define M_MMAP_MAX -4 /* actually do something */
|
||
|
|
|
||
|
|
/* DEFAULT_TRIM_THRESHOLD */
|
||
|
|
#ifndef DEFAULT_TRIM_THRESHOLD
|
||
|
|
#define DEFAULT_TRIM_THRESHOLD ((128) * (1024))
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/* DEFAULT_TOP_PAD */
|
||
|
|
#ifndef DEFAULT_TOP_PAD
|
||
|
|
#define DEFAULT_TOP_PAD (0)
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/* DEFAULT_MMAP_THRESHOLD */
|
||
|
|
#ifndef DEFAULT_MMAP_THRESHOLD
|
||
|
|
#define DEFAULT_MMAP_THRESHOLD ((128) * (1024))
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/* DEFAULT_MMAP_MAX */
|
||
|
|
#ifndef DEFAULT_MMAP_MAX
|
||
|
|
#if HAVE_MMAP
|
||
|
|
#define DEFAULT_MMAP_MAX (64)
|
||
|
|
#else
|
||
|
|
#define DEFAULT_MMAP_MAX (0)
|
||
|
|
#endif
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#ifdef INTERNAL_LINUX_C_LIB
|
||
|
|
#if __STD_C /* stand c*/
|
||
|
|
Void_t * __default_morecore_init (ptrdiff_t);
|
||
|
|
Void_t *(*__morecore)(ptrdiff_t) = __default_morecore_init;
|
||
|
|
#else /* not stand c*/
|
||
|
|
Void_t * __default_morecore_init ();
|
||
|
|
Void_t *(*__morecore)() = __default_morecore_init;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/* more core defination */
|
||
|
|
#define MORECORE (*__morecore)
|
||
|
|
#define MORECORE_FAILURE 0
|
||
|
|
#define MORECORE_CLEARS 1
|
||
|
|
#else /* #ifndef INTERNAL_LINUX_C_LIB */
|
||
|
|
#if __STD_C /* stand c */
|
||
|
|
extern Void_t* sbrk(ptrdiff_t);
|
||
|
|
#else /* not stand c*/
|
||
|
|
extern Void_t* sbrk();
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/* more core */
|
||
|
|
#ifndef MORECORE
|
||
|
|
#define MORECORE sbrk
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/* more failure */
|
||
|
|
#ifndef MORECORE_FAILURE
|
||
|
|
#define MORECORE_FAILURE -1
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/* more core clears */
|
||
|
|
#ifndef MORECORE_CLEARS
|
||
|
|
#define MORECORE_CLEARS 1
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#endif /* #ifdef INTERNAL_LINUX_C_LIB */
|
||
|
|
|
||
|
|
#if defined(INTERNAL_LINUX_C_LIB) && defined(__ELF__)
|
||
|
|
/* use libc def */
|
||
|
|
#define cALLOc __libc_calloc /* calloc */
|
||
|
|
#define fREe __libc_free /* free */
|
||
|
|
#define mALLOc __libc_malloc /* malloc */
|
||
|
|
#define mEMALIGn __libc_memalign /* memalign */
|
||
|
|
#define rEALLOc __libc_realloc /* realloc */
|
||
|
|
#define vALLOc __libc_valloc /* valloc */
|
||
|
|
#define pvALLOc __libc_pvalloc /* pvalloc */
|
||
|
|
#define mALLINFo __libc_mallinfo /* mallinfo */
|
||
|
|
#define mALLOPt __libc_mallopt /* mallopt */
|
||
|
|
|
||
|
|
#pragma weak calloc = __libc_calloc /* calloc */
|
||
|
|
#pragma weak free = __libc_free /* free */
|
||
|
|
#pragma weak cfree = __libc_free /* cfree */
|
||
|
|
#pragma weak malloc = __libc_malloc /* malloc */
|
||
|
|
#pragma weak memalign = __libc_memalign /* memalign */
|
||
|
|
#pragma weak realloc = __libc_realloc /* realloc */
|
||
|
|
#pragma weak valloc = __libc_valloc /* valloc */
|
||
|
|
#pragma weak pvalloc = __libc_pvalloc /* pvalloc */
|
||
|
|
#pragma weak mallinfo = __libc_mallinfo /* mallinfo */
|
||
|
|
#pragma weak mallopt = __libc_mallopt /* mallopt */
|
||
|
|
|
||
|
|
#else
|
||
|
|
|
||
|
|
#ifdef USE_DL_PREFIX
|
||
|
|
#define cALLOc dlcalloc /* calloc */
|
||
|
|
#define fREe dlfree /* free */
|
||
|
|
#define mALLOc dlmalloc /* malloc */
|
||
|
|
#define mEMALIGn dlmemalign /* memalign */
|
||
|
|
#define rEALLOc dlrealloc /* realloc */
|
||
|
|
#define vALLOc dlvalloc /* valloc */
|
||
|
|
#define pvALLOc dlpvalloc /* pvalloc */
|
||
|
|
#define mALLINFo dlmallinfo /* mallinfo */
|
||
|
|
#define mALLOPt dlmallopt /* malloppt */
|
||
|
|
#else /* #ifndef USE_DL_PREFIX */
|
||
|
|
#define cALLOc calloc /* calloc */
|
||
|
|
#define fREe free /* free */
|
||
|
|
#define mALLOc malloc /* malloc */
|
||
|
|
#define mEMALIGn memalign /* memalign */
|
||
|
|
#define rEALLOc realloc /* realloc */
|
||
|
|
#define vALLOc valloc /* valloc */
|
||
|
|
#define pvALLOc pvalloc /* pvalloc */
|
||
|
|
#define mALLINFo mallinfo /* mallinfo */
|
||
|
|
#define mALLOPt mallopt /* mallopt */
|
||
|
|
#endif /* USE_DL_PREFIX */
|
||
|
|
|
||
|
|
#endif /* defined(INTERNAL_LINUX_C_LIB) && defined(__ELF__) */
|
||
|
|
|
||
|
|
#if __STD_C
|
||
|
|
/*stand c */
|
||
|
|
Void_t* mALLOc(size_t); /* malloc */
|
||
|
|
void fREe(Void_t*); /* free */
|
||
|
|
Void_t* rEALLOc(Void_t*, size_t); /* realloc */
|
||
|
|
Void_t* mEMALIGn(size_t, size_t); /* memalign */
|
||
|
|
Void_t* vALLOc(size_t); /* valloc */
|
||
|
|
Void_t* pvALLOc(size_t); /* pvalloc */
|
||
|
|
Void_t* cALLOc(size_t, size_t); /* calloc */
|
||
|
|
void cfree(Void_t*); /* cfree */
|
||
|
|
int malloc_trim(size_t); /* malloc trim */
|
||
|
|
size_t malloc_usable_size(Void_t*); /* malloc useable size */
|
||
|
|
void malloc_stats(void); /* status */
|
||
|
|
int mALLOPt(int, int); /* mallopt */
|
||
|
|
struct mallinfo mALLINFo(void); /* malloc info */
|
||
|
|
#else
|
||
|
|
/* not stand c */
|
||
|
|
Void_t* mALLOc(); /* malloc */
|
||
|
|
void fREe(); /* free */
|
||
|
|
Void_t* rEALLOc(); /* realloc */
|
||
|
|
Void_t* mEMALIGn();
|
||
|
|
Void_t* vALLOc();
|
||
|
|
Void_t* pvALLOc(); /* pvalloc */
|
||
|
|
Void_t* cALLOc();
|
||
|
|
void cfree(); /* cfree */
|
||
|
|
int malloc_trim();
|
||
|
|
size_t malloc_usable_size();
|
||
|
|
void malloc_stats();
|
||
|
|
int mALLOPt();
|
||
|
|
struct mallinfo mALLINFo(); /* malloc info */
|
||
|
|
#endif
|
||
|
|
/*
|
||
|
|
* begin end and current of malloc area
|
||
|
|
*/
|
||
|
|
extern ulong mem_malloc_start;
|
||
|
|
extern ulong mem_malloc_end;
|
||
|
|
extern ulong mem_malloc_brk;
|
||
|
|
/* mem init */
|
||
|
|
void mem_malloc_init(ulong start, ulong size);
|
||
|
|
|
||
|
|
#ifdef __cplusplus
|
||
|
|
}; /* end of extern "C" */
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#endif /*_CHIPRAM_MALLOC_H__ */
|