memmgr.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 614 行 · 第 1/2 页
C
614 行
MEMORYSTATUS info;
GlobalMemoryStatus( &info );
memory_available = info.dwAvailVirtual;
if( size_requested != 0 ) {
MemorySize = size_requested;
} else {
MemorySize = memory_available;
}
}
#elif defined( __OS2__ ) || defined( __OSI__ )
if( size_requested != 0 ) {
MemorySize = size_requested;
} else {
MemorySize = _16M;
}
memory_available = _16M;
#elif defined( __QNX__ )
{
struct _osinfo data;
qnx_osinfo( 0, &data );
memory_available = (unsigned long)data.freememk * 1024;
if( size_requested != 0 ) {
if( memory_available < size_requested ) {
NotEnoughMem();
}
MemorySize = size_requested;
} else {
MemorySize = memory_available;
}
}
#elif defined( __LINUX__ )
if( size_requested != 0 ) {
MemorySize = size_requested;
} else {
MemorySize = _16M;
}
memory_available = _16M;
#endif
if( max_size_queried || size_queried ) {
myitoa( (int)(memory_available/_1K), CopyStr( (char *)"Maximum WCGMEMORY=", (char *)buff ) );
write( 1, buff, Length( buff ) );
write( 1, "\r\n", 2 );
}
}
static void MemInit( void )
/*****************************/
{
if( !Initialized ) {
int i;
for( i = 0; i <= MAX_CLASS; ++i ) {
_FreeList[i] = NULL;
_ClassSizes[i] = 1 << ( MIN_SIZE + i );
}
Initialized = 1;
AllocSize = 0;
_Blks = NULL;
#if !defined( __QNX__ )
CalcMemSize();
#endif
}
}
static int SizeToClass( tag amount )
/**********************************/
{
int mem_class;
if( amount >= MAX_ALLOC ) {
return( MAX_CLASS );
}
if( amount <= ( 1 << MIN_SIZE ) ) {
return( 0 );
}
--amount;
amount >>= MIN_SIZE;
mem_class = 0;
for( ;; ) {
++mem_class;
amount >>= 1;
if( amount == 0 )
break;
}
return( mem_class );
}
static tag ClassToSize( int mem_class )
/*************************************/
{
return( _ClassSizes[mem_class] );
}
static pointer GetFromFrl( tag amount, int frl_class )
/*****************************************************/
{
frl *free;
free = _FreeList[ frl_class ];
if( free != NULL ) {
assert( !( free->length & ALLOCATED ) );
free->length |= ALLOCATED;
_FreeList[ frl_class ] = free->link;
return( free );
}
return( NULL );
}
static pointer GetFromBlk( tag amount )
/**************************************/
{
mem_blk *block;
tag *alloc;
block = _Blks;
while( block && (block->free < amount) )
block = block->next;
if( block ) {
alloc = (tag*)((char*)block + block->size - block->free);
assert( *alloc == 0 );
*alloc = amount | ALLOCATED;
block->free -= amount;
return( ++alloc );
}
if( MemFromSys( 0 ) == NULL) // Grab one empty block
return( NULL );
return( GetFromBlk( amount ) ); // We know this will now succeed
}
extern pointer MemAlloc( tag amount )
/************************************/
{
char *chunk;
int mem_class;
if( !Initialized )
MemInit();
if( amount == 0 )
return( NULL );
amount = ( amount + TAG_SIZE + (WORD_SIZE-1) ) & ~(WORD_SIZE-1);
if( amount > MAX_ALLOC ) {
return( (pointer)MemFromSys( amount ) );
}
if( amount < MIN_ALLOC )
amount = MIN_ALLOC;
mem_class = SizeToClass( amount );
chunk = GetFromFrl( amount, mem_class );
if( chunk != NULL )
return( chunk + TAG_SIZE );
return( GetFromBlk( ClassToSize( mem_class ) ) );
}
extern void MemFree( char *block )
/************************************/
{
frl *free;
int mem_class;
tag length;
free = (frl *)( block - TAG_SIZE );
assert( free->length & ALLOCATED );
free->length &= ~ALLOCATED;
length = free->length;
if( length > MAX_ALLOC ) { // This was a full block
blk_hdr *header;
mem_blk *blk;
header = (blk_hdr *)( block - sizeof( blk_hdr ) );
blk = header->block;
blk->free += header->size + sizeof( blk_hdr );
blk->size += header->size + sizeof( blk_hdr );
#ifndef NDEBUG
// Must zero the memory for later checks in GetFromBlk
memset( header, 0, length + sizeof( blk_hdr ) );
#endif
} else {
mem_class = SizeToClass( length );
free->link = _FreeList[ mem_class ];
_FreeList[ mem_class ] = free;
}
}
extern void MemCoalesce( void )
/*********************************/
{
return;
}
extern pointer_int MemInUse( void )
/**************************************/
{
if( !Initialized )
MemInit();
return( AllocSize );
}
extern pointer_int MemSize( void )
/*************************************/
{
switch( Initialized ) {
case 0:
MemInit();
#if defined( __QNX__ )
/* fall through */
case 1:
CalcMemSize();
#endif
}
return( MemorySize );
}
static char *MemFromSys( tag amount )
/***************************************/
{
char *ptr;
char *chunk;
blk_hdr *allocated;
mem_blk *blk;
unsigned size;
// round up size to multiple of 64K
size = (amount + sizeof( mem_blk ) + sizeof( blk_hdr ) + (_64K - 1)) & - _64K;
#ifdef NDEBUG
ptr = malloc( size );
#else
ptr = calloc( 1, size ); // Need to clear memory for later assert() calls
#endif
if( ptr != NULL ) {
AllocSize += size;
#ifdef MEMORY_STATS
if( AllocSize > PeakAlloc )
PeakAlloc = AllocSize;
#endif
blk = (void *)ptr;
// If amount was zero, this block will be chopped up into
// small chunks immediately. If nonzero, return pointer
// to memory at the end of the block and use the rest for
// small chunks. If the initial large allocation is freed,
// it will also be reused for small blocks.
blk->next = _Blks;
_Blks = blk;
blk->free = size - amount - sizeof( mem_blk );
blk->size = size;
if( amount ) {
blk->size -= amount + sizeof( blk_hdr );
blk->free -= sizeof( blk_hdr );
allocated = (blk_hdr*)((char*)blk + sizeof( mem_blk ) + blk->free);
allocated->block = blk;
allocated->size = amount | ALLOCATED;
chunk = (char*)allocated + sizeof( blk_hdr );
} else {
chunk = (char*)blk + sizeof( mem_blk );
}
return( chunk );
}
return( NULL );
}
static void MemToSys( mem_blk *what )
/************************************/
{
free( what );
}
extern void MemFini( void )
/*************************/
{
mem_blk *curr;
mem_blk *next;
curr = _Blks;
while( curr != NULL ) {
next = curr->next;
MemToSys( curr );
curr = next;
}
#ifdef MEMORY_STATS
{
char buff[80];
myitoa( (int)(PeakAlloc/_1K), CopyStr( "Peak WCG memory usage (KB): ", buff ) );
write( 1, buff, Length( buff ) );
write( 1, "\r\n", 2 );
PeakAlloc = 0;
}
#endif
Initialized = 0;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?