📄 malloc.cpp
字号:
}
}
size_t __malloc_set_block_size(size_t blocksz)
{
size_t oldsz = __malloc_blocksz;
/* Make block size a power of two */
while(blocksz > 0 && (blocksz & (blocksz-1)) != 0) {
blocksz |= blocksz >> 1;
blocksz++;
}
if(blocksz > 0) {
__malloc_blocksz = blocksz;
}
return oldsz;
}
//extern "C" void Mem_init(void);
void init_sbrk(void * pmem_buf, size_t size);
void Mem_init(void * pmem_buf/*=NULL*/, size_t size/*=0*/)
{
init_sbrk(pmem_buf, size);
_STI__05__malloc();
_STI__15__malloc();
mall_init();
}
/***********************************************************************/
/* Implementation module : sbrk.c
Copyright 1993 Diab Data AB, Sweden
Description :
Embedded version of the system call sbrk()
sbrk(incr) gets incr bytes of memory.
sbrk() is used by Malloc().
In this version (without an underlaying OS), sbrk can get
memory in 2 ways:
1. From a statically allocated buffer.
If the macro SBRK_SIZE is set, a local buffer is used.
2. Otherwise the identifiers __HEAP_START and __HEAP_END
must be set. See the link command file link.com for an
example on how to set these identifiers.
This file also contains the stack-grow function __sbrk_sp_grow().
This function is called by functions that needs more stack space
than is reserved in __sp_limit.
If the variable __sp_limit has the same value as __heap_end,
then stack memory is taken from the heap.
History :
When Who What
930323 teve initial
*/
/* never profile nor run-time check this code */
#pragma option -Xprof-all=0
#pragma option -Xrtc=0
/************** Imported modules ********************************/
#include "fileio.h"
/************** Local data, types, fns and macros ***************/
char *__heap_beg ;
char *__heap_ptr ;
static char *__heap_end ;
static char *__sp_limit;
void init_sbrk(void * pmem_buf, size_t size)
{
char * sbrk_buf =(char *)pmem_buf;
if(sbrk_buf != NULL)
{
__heap_beg = sbrk_buf;
__heap_ptr = sbrk_buf;
__heap_end = sbrk_buf+size;
__sp_limit = 0; /* works only with link file */
}
else
{
extern char __HEAP_START[], __HEAP_END[], __SP_END[];
__heap_beg = __HEAP_START;
__heap_ptr = __HEAP_START;
__heap_end = __HEAP_END;
__sp_limit = __SP_END;
}
}
/************** Implementation of exported functions ************/
void * SBRK(int incr)
{
char *ret;
char dummy;
if (__heap_ptr + incr > __heap_end) return (void *)-1;
if (__heap_ptr < &dummy && __heap_ptr + incr > &dummy) {
//WRERR("Heap overflow\n");
return (void *)-1;
}
ret = __heap_ptr;
__heap_ptr += incr;
return (void *)ret;
}
/************** Local data, types, fns and macros ***************/
static void *__realloc(void *ptr, size_t size)
{
NP np, v_new;
void *nptr;
size_t bsize;
int old_mxfast;
if (ptr == NULL) {
return Malloc(size);
}
if(__malloc_mutex) _lib_lock_mutex(__malloc_mutex);
// if (__malloc_check) __malloc_check_fn();
if (size <= __m_mxfast) {
if (size == 0) {
/* free(ptr); /* SVID and OCS do not want it freed, ANSI do! */
if(__malloc_mutex) _lib_unlock_mutex(__malloc_mutex);
return NULL;
}
if (size <= __m_mxfast) size = ((size+__m_grain-1)/__m_grain)*__m_grain;
np = (NP)((char *)ptr - BOFFSET - __m_keep);
bsize = SIZE(np);
if (bsize <= __m_mxfast) __mallopt_fix(bsize,0);
__mallopt_fix(size,1);
}
size += __m_keep;
if (size < MINSZ) size = MINSZ;
else size = (size + ALIGN-1) & ~(ALIGN-1);
np = (NP)((char *)ptr - BOFFSET - __m_keep);
if (!ISBUSY(np)) {
if (ISFREE(np)) {
if(__malloc_mutex) _lib_unlock_mutex(__malloc_mutex);
//MALLERR("Realloc: warning: points to free buffer\n");
return Malloc(size);
}
if (__m_keep) {
np = (NP)((char *)ptr - BOFFSET);
}
if (!ISBUSY(np)) {
if(__malloc_mutex) _lib_unlock_mutex(__malloc_mutex);
//MALLERR("Realloc: warning: not a valid pointer\n");
return Malloc(size);
}
}
v_new = np->next;
while(ISFREE(v_new)) {
Delete(v_new);
SETCLEAR(v_new);
np->next = v_new = v_new->next;
}
bsize = SIZE(np);
if (size <= bsize) {
if (bsize-size > sizeof(struct node) + __m_keep) {
/* split node */
v_new = (NP)(np->u.buf+size);
v_new->next = np->next;
np->next = v_new;
__insert(v_new);
SETFREE(v_new);
}
nptr = &np->u.buf[__m_keep];
if(__malloc_mutex) _lib_unlock_mutex(__malloc_mutex);
return nptr;
} else {
/* must find v_new space */
old_mxfast = __m_mxfast;
__m_mxfast = 0;
nptr = Malloc(size);
if (nptr != NULL) {
Memcpy(nptr,ptr,bsize);
Free(ptr);
}
__m_mxfast = old_mxfast;
if(__malloc_mutex) _lib_unlock_mutex(__malloc_mutex);
return nptr;
}
}
/************** Implementation of exported functions ************/
void *Realloc(void *ptr, size_t size)
{
void* p;
/* if RTEC is initialized, use Malloc/free to Realloc
if (__rtc_alloc_ptr) {
p = Malloc(size); /* get a v_new block
if (p && ptr) {
NP np;
size_t bsize;
if(__malloc_mutex) _lib_lock_mutex(__malloc_mutex);
np = (NP)((char *)ptr - BOFFSET - __m_keep);
if (!ISBUSY(np)) {
if (ISFREE(np)) {
if(__malloc_mutex) _lib_unlock_mutex(__malloc_mutex);
//MALLERR("Realloc: warning: points to free buffer\n");
return p;
}
if (__m_keep) {
np = (NP)((char *)ptr - BOFFSET);
}
if (!ISBUSY(np)) {
if(__malloc_mutex) _lib_unlock_mutex(__malloc_mutex);
//MALLERR("Realloc: warning: not a valid pointer\n");
return p;
}
}
if(__malloc_mutex) _lib_unlock_mutex(__malloc_mutex);
bsize = SIZE(np);
if(bsize > size) {
bsize = size;
}
Memcpy(p, ptr, bsize);
}
Free(ptr); /* free old block
} else */
{
p = __realloc(ptr, size); /* do a normal Realloc */
}
return p;
}
/***********************************************************************/
/* Implementation module : Memcpy.c
Copyright 1994 Diab Data AB, Sweden
Description :
Implemention of libc function
void *Memcpy(void *v1,const void *v2, size_t n);
History :
When Who What
941201 teve total rewrite
*/
/************** Imported modules ********************************/
#include <string.h>
#include "strmac.h"
/* Disable unrolling since it screws up the first loop's performance */
#pragma option -Xunroll=0
/************** Local data, types, fns and macros ***************/
/************** Implementation of exported functions ************/
void * Memcpy(void *v1,const void *v2, size_t n)
{
void *ret = v1;
char *s1 = (char *)v1;
const char *s2 = (const char *)v2;
if (sizeof(UL) == sizeof(char)*4 && n > 7) {
UL *lp1, *lp2;
UL l;
size_t i = (OPTALIGN - (size_t)s1) & (OPTALIGN-1);
n -= i;
while(i != 0) {
*s1++ = *s2++;
i--;
}
if (((int)s2 & (STRALIGN-1)) == 0) {
size_t m;
m = n >> 2;
n &= 3;
lp1 = (UL *)s1;
lp2 = (UL *)s2;
for(i = 0; i < m; i++) {
lp1[i] = lp2[i];
}
s1 = (char *)(lp1+m);
s2 = (const char *)(lp2+m);
}
}
s1 += INCINI; s2 += INCINI;
while(n) {
*INC(s1) = *INC(s2);
n--;
}
return ret;
}
/* Implementation module : Memset.c
Copyright 1994 Diab Data AB, Sweden
Description :
Implemention of libc function
void *Memset(void *v1, int c, size_t n);
History :
When Who What
941201 teve total rewrite
*/
/************** Imported modules ********************************/
#include <string.h>
#include "strmac.h"
/************** Local data, types, fns and macros ***************/
/* Disable unrolling since it screws up the first loop's performance */
#pragma option -Xunroll=0
/************** Implementation of exported functions ************/
void * Memset(void *v1, int c, size_t n)
{
void *ret = v1;
char *s1 = (char *)v1;
c = (unsigned char)c;
if (sizeof(UL) == sizeof(char)*4 && n > 7) {
UL *lp1, *lp2;
UL lc = FILLMEM(c);
size_t m;
size_t i = (OPTALIGN - (size_t)s1) & (OPTALIGN-1);
n -= i;
while(i != 0) {
*s1++ = c;
i--;
}
m = n >> 2;
n &= 3;
lp1 = (UL *)s1;
for(i = 0; i < m; i++) {
lp1[i] = lc;
}
s1 = (char *)(lp1+m);
}
s1 += INCINI;
while(n) {
*INC(s1) = c;
n--;
}
return ret;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -