📄 memory.c
字号:
((PACKET *)pptr)->packet_size = newsize | BLOCK_USED;
oldsize -= newsize + BLOCK_OVERHEAD;
pptr += newsize + BLOCK_OVERHEAD;
((PACKET *)pptr)->packet_size = oldsize | BLOCK_USED;
free(pptr + BLOCK_OVERHEAD);
_unlock();
return packet;
}
/*-----------------------------------------------------------------------*/
/* IF NEW SIZE IS BIGGER THAN CURRENT PACKET, */
/* 1) CHECK NEXT PACKET IN LIST, SEE IF PACKET CAN BE EXPANDED */
/* 2) IF NOT, MOVE PACKET TO NEW LOCATION. */
/*-----------------------------------------------------------------------*/
else
{
PACKET *next = (PACKET *)(pptr + oldsize + BLOCK_OVERHEAD);
int temp;
if (((char *)next < &heap_mem[_memory_size - BLOCK_OVERHEAD]) &&
(!(next->packet_size & BLOCK_USED)) &&
((temp = oldsize +next->packet_size +BLOCK_OVERHEAD -newsize) >= 0))
{
mremove(next);
if (temp < MIN_BLOCK + BLOCK_OVERHEAD)
{
((PACKET *)pptr)->packet_size = newsize + temp | BLOCK_USED;
_unlock();
return packet;
}
((PACKET *)pptr)->packet_size = newsize | BLOCK_USED;
pptr += newsize + BLOCK_OVERHEAD;
((PACKET *)pptr)->packet_size = temp - BLOCK_OVERHEAD;
minsert((PACKET *)pptr);
_unlock();
return packet;
}
else
{
/*---------------------------------------------------------------*/
/* ALLOCATE NEW PACKET AND MOVE DATA INTO IT. */
/*---------------------------------------------------------------*/
register char *new_packet = (char *)malloc(size);
if (new_packet == 0) { _unlock(); return NULL; }
memcpy(new_packet, packet, oldsize);
free(packet);
_unlock();
return new_packet;
}
}
}
/*****************************************************************************/
/* */
/* FREE - Return a packet allocated by malloc to free memory pool. */
/* Return NULL if successful, -1 if not successful. */
/* */
/*****************************************************************************/
void free(void *packet)
{
register char *ptr = (char *)packet;
register PACKET *last; /* POINT TO PREVIOUS PACKET */
register PACKET *current; /* POINTER TO THIS PACKET */
register PACKET *next; /* POINTER TO NEXT PACKET */
if (ptr == NULL) return;
last = next = NULL; /* INITIALIZE POINTERS */
ptr -= BLOCK_OVERHEAD; /* ADJUST POINT TO BEGINNING OF PACKET */
_lock();
current = _sys_memory;
/*-----------------------------------------------------------------------*/
/* SEARCH FOR THE POINTER IN THE PACKET POINTED TO */
/*-----------------------------------------------------------------------*/
while (current < (PACKET *) ptr)
{
last = current;
current = (PACKET *)((char *)current +
(current->packet_size & ~BLOCK_USED) + BLOCK_OVERHEAD);
}
/*-----------------------------------------------------------------------*/
/* CHECK FOR POINTER OR PACKET ERRORS. */
/*-----------------------------------------------------------------------*/
if ((current != (PACKET *) ptr) || (!(current->packet_size & BLOCK_USED)))
{
_unlock();
return;
}
current->packet_size &= ~BLOCK_USED; /* MARK PACKET AS FREE */
/*-----------------------------------------------------------------------*/
/* GET POINTER TO NEXT PACKET IN MEMORY, IF ANY. */
/*-----------------------------------------------------------------------*/
next = (PACKET *) ((char *)current + BLOCK_OVERHEAD +current->packet_size);
if (next > (PACKET *) &heap_mem[_memory_size - BLOCK_OVERHEAD])
next = NULL;
if (last->packet_size & BLOCK_USED) last = NULL;
if (next->packet_size & BLOCK_USED) next = NULL;
/*-----------------------------------------------------------------------*/
/* ATTEMPT TO COLLESCE THE THREE PACKETS (PREVIOUS, CURRENT, NEXT) */
/*-----------------------------------------------------------------------*/
if (last && next)
{
mremove(last);
mremove(next);
last->packet_size += current->packet_size + next->packet_size +
BLOCK_OVERHEAD + BLOCK_OVERHEAD;
minsert(last);
_unlock();
return;
}
/*-----------------------------------------------------------------------*/
/* ATTEMPT TO COLLESCE THE CURRENT WITH LAST PACKET. (LAST, CURRENT) */
/*-----------------------------------------------------------------------*/
if (last)
{
mremove(last);
last->packet_size += current->packet_size + BLOCK_OVERHEAD;
minsert(last);
_unlock();
return;
}
/*-----------------------------------------------------------------------*/
/* ATTEMPT TO COLLESCE THE CURRENT WITH NEXT PACKET. (CURRENT, NEXT) */
/*-----------------------------------------------------------------------*/
if (next)
{
mremove(next);
current->packet_size += next->packet_size + BLOCK_OVERHEAD;
minsert(current);
_unlock();
return;
}
/*-----------------------------------------------------------------------*/
/* NO COLLESCENCE POSSIBLE, JUST INSERT THIS PACKET INTO LIST */
/*-----------------------------------------------------------------------*/
minsert(current);
_unlock();
}
/*****************************************************************************/
/* */
/* MEMALIGN - Allocate a packet of a given size, and on a given boundary. */
/* */
/*****************************************************************************/
void *memalign(size_t alignment, size_t size)
{
PACKET *aln_packet;
PACKET *current;
size_t newsize = (size + BLOCK_MASK) & ~BLOCK_MASK;
size_t aln_mask = alignment - 1;
int leftover = -1;
char *aln_start;
char *un_aln_start;
if (size <= 0) return NULL;
/*--------------------------------------------------------------------*/
/* IF ALIGNMENT IS NOT A POWER OF TWO OR IS LESS THAN THE DEFAULT */
/* ALIGNMENT OF MALLOC, THEN SIMPLY RETURN WHAT MALLOC RETURNS. */
/*--------------------------------------------------------------------*/
if (alignment <= BLOCK_OVERHEAD || (alignment & (alignment-1)))
return malloc(size);
_lock();
current = sys_free;
/*-----------------------------------------------------------------------*/
/* SCAN THROUGH FREE LIST FOR PACKET LARGE ENOUGH TO CONTAIN ALIGNED */
/* PACKET */
/*-----------------------------------------------------------------------*/
for ( ; current ; current = current->size_ptr)
{
un_aln_start = (char *) current + BLOCK_OVERHEAD;
aln_start = (char *)(((size_t) un_aln_start + aln_mask) & ~aln_mask);
leftover = un_aln_start + current->packet_size - aln_start -newsize;
/*--------------------------------------------------------------------*/
/* MAKE SURE THAT THE PRE BLOCK SPACE IS LARGE ENOUGH TO BE A BLOCK */
/* OF ITS OWN. */
/*--------------------------------------------------------------------*/
for ( ; (char *)current+sizeof(PACKET) > aln_start-BLOCK_OVERHEAD ;
aln_start += alignment, leftover -= alignment);
if (leftover >= 0) break;
}
if (!current) { _unlock(); return NULL; }
/*-----------------------------------------------------------------------*/
/* SETUP NEW PACKET FOR ALIGNED MEMORY. */
/*-----------------------------------------------------------------------*/
mremove(current);
aln_packet = (PACKET *) (aln_start - BLOCK_OVERHEAD);
aln_packet->packet_size = newsize | BLOCK_USED;
/*-----------------------------------------------------------------------*/
/* HANDLE THE FREE SPACE BEFORE THE ALIGNED BLOCK. IF THE ORIGINAL */
/* BLOCK WAS ALIGNED, THERE WON'T BE FREE SPACE BEFORE THE ALIGNED BLOCK.*/
/*-----------------------------------------------------------------------*/
if (aln_start != un_aln_start)
{
current->packet_size = (char *)aln_packet - un_aln_start;
minsert(current);
}
/*-----------------------------------------------------------------------*/
/* HANDLE THE FREE SPACE AFTER THE ALIGNED BLOCK. IF IT IS LARGE ENOUGH */
/* TO BE A BLOCK OF ITS OWN, THEN MAKE IT ONE, OTHERWISE ADD THE */
/* LEFTOVER SIZE TO THE ALIGNED BLOCK. */
/*-----------------------------------------------------------------------*/
if (leftover >= BLOCK_OVERHEAD + MIN_BLOCK)
{
register PACKET *next = (PACKET *) (aln_start + newsize);
next->packet_size = leftover - BLOCK_OVERHEAD;
minsert(next);
}
else aln_packet->packet_size += leftover;
_unlock();
return aln_start;
}
#ifdef MALLOC_DEBUG
/*****************************************************************************/
/* */
/* MEMMAP - Print dynamic memory allocation statistics */
/* */
/*****************************************************************************/
#include <stdio.h>
#ifndef MAX
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#endif
void memmap()
{
PACKET *current;
int free_block_num = 0;
int free_block_space = 0;
int free_block_max = 0;
int used_block_num = 0;
int used_block_space = 0;
int used_block_max = 0;
_lock();
current = _sys_memory;
/*-----------------------------------------------------------------------*/
/* LOOP THROUGH ALL PACKETS */
/*-----------------------------------------------------------------------*/
while (current < (PACKET *) &heap_mem[_memory_size-BLOCK_OVERHEAD])
{
int size = current->packet_size & ~BLOCK_USED;
int used = current->packet_size & BLOCK_USED;
printf(">> Used:%1d size:%d addr:%x\n", used, size, current);
if (used)
{
used_block_num++;
used_block_space += size;
used_block_max = MAX(used_block_max, size);
}
else
{
free_block_num++;
free_block_space += size;
free_block_max = MAX(free_block_max, size);
}
current = (PACKET *)((char *)current + size + BLOCK_OVERHEAD);
}
printf("fr_nm:%d fr_sp:%d fr_mx:%d us_nm:%d us_sp:%d us_mx:%d ovr:%d\n\n",
free_block_num, free_block_space, free_block_max,
used_block_num, used_block_space, used_block_max,
(free_block_num + used_block_num) * BLOCK_OVERHEAD);
_unlock();
fflush(stdout);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -