Files correlati : cb6.dll Ricompilazione Demo : [ ] Commento : Modifiche per la compilazione Linux git-svn-id: svn://10.65.10.50/trunk@11080 c028cbd2-c16b-5b4b-a496-9718f37d4682
1366 lines
36 KiB
C
Executable File
1366 lines
36 KiB
C
Executable File
/* m4memory.c (c)Copyright Sequiter Software Inc., 1988-1996. All rights reserved. */
|
|
|
|
#ifdef S4OS2
|
|
#ifdef __DLL__
|
|
#define INCL_DOSMEMMGR
|
|
#endif
|
|
#endif
|
|
#include "d4all.h"
|
|
|
|
#ifdef S4VB_DOS
|
|
#include "malloc.h"
|
|
#endif
|
|
|
|
#ifdef __TURBOC__
|
|
#pragma hdrstop
|
|
#endif
|
|
|
|
#ifdef S4OS2
|
|
#ifdef __DLL__
|
|
#include <bsememf.h>
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef S4SERVER
|
|
/* for 32 bit servers, allow more than 10000 memory allocations... */
|
|
#ifndef S4WIN32
|
|
#ifdef S4WINTEL
|
|
#ifndef S4OS2
|
|
#define MEM4MAX_POINTERS 10000
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#ifndef MEM4MAX_POINTERS
|
|
#define MEM4MAX_POINTERS 100000
|
|
#endif
|
|
#else
|
|
#define MEM4MAX_POINTERS 10000
|
|
#endif
|
|
|
|
#define mem4numTypes 10
|
|
|
|
#ifdef S4MEM_PRINT
|
|
#ifdef S4WINDOWS
|
|
#ifdef S4TESTING
|
|
#include "t4test.h"
|
|
#endif
|
|
#endif
|
|
int v4print = 0 ; /* if v4print == 0 then stdout, else stdprn, no output if -1 */
|
|
/* use globals to hold the current file name and line number */
|
|
const char *m4fileName = 0 ;
|
|
int m4lineNo = 0 ;
|
|
#ifdef S4WINDOWS
|
|
int S4FUNCTION code4memFileName( void )
|
|
{
|
|
return m4lineNo ;
|
|
}
|
|
|
|
const char *S4FUNCTION code4memFileNo( void )
|
|
{
|
|
return m4fileName ;
|
|
}
|
|
|
|
void S4FUNCTION code4memLineNoSet( int val )
|
|
{
|
|
m4lineNo = val ;
|
|
}
|
|
|
|
void S4FUNCTION code4memFileNameSet( const char *ptr )
|
|
{
|
|
m4fileName = ptr ;
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
typedef struct
|
|
{
|
|
LINK4 link ;
|
|
MEM4 types[mem4numTypes] ;
|
|
} MEMORY4GROUP ;
|
|
|
|
#ifdef S4WIN32
|
|
#ifdef S4SEMAPHORE
|
|
/* multi-thread support */
|
|
CRITICAL_SECTION critical4memory, critical4expression ;
|
|
#endif
|
|
#endif
|
|
|
|
#ifndef S4CBPP
|
|
static LIST4 avail = { 0, 0, 0 } ; /* A list of available MEM4 entries */
|
|
static LIST4 used = { 0, 0, 0 } ; /* A list of used MEM4 entries */
|
|
static LIST4 groups = { 0, 0, 0 } ; /* A list of Allocated MEM4 groups */
|
|
#else
|
|
/* initialization with class and union structures */
|
|
static LIST4 avail = { {0}, 0, {0} } ; /* A list of available MEM4 entries */
|
|
static LIST4 used = { {0}, {0}, {0} } ; /* A list of used MEM4 entries */
|
|
static LIST4 groups = { {0}, 0, {0} } ; /* A list of Allocated MEM4 groups */
|
|
#endif
|
|
#ifdef S4SEMAPHORE
|
|
#ifdef S4WIN32
|
|
static int memoryInitialized = 0 ;
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef S4SEMAPHORE
|
|
#ifdef S4WIN32
|
|
int mem4start( CODE4 *c4 )
|
|
{
|
|
if ( memoryInitialized == 0 )
|
|
return -1 ;
|
|
|
|
EnterCriticalSection( &critical4memory ) ;
|
|
|
|
return 0 ;
|
|
}
|
|
|
|
void mem4stop( CODE4 *c4 )
|
|
{
|
|
if ( memoryInitialized == 0 )
|
|
return ;
|
|
|
|
LeaveCriticalSection( &critical4memory ) ;
|
|
}
|
|
#else
|
|
static int mem4start( CODE4 *c4 )
|
|
{
|
|
APIRET rc ;
|
|
|
|
#ifdef E4ANALYZE
|
|
if ( c4 == 0 )
|
|
return error4( c4, e4info, "OS/2 Semaphore Failure" ) ;
|
|
#endif
|
|
|
|
rc = DosRequestMutexSem( c4->hmtxMem, -1 ) ;
|
|
if ( rc != 0 )
|
|
return error4( c4, e4info, "OS/2 Semaphore Failure" ) ;
|
|
return 0 ;
|
|
}
|
|
|
|
static void mem4stop( CODE4 *c4 )
|
|
{
|
|
#ifdef E4ANALYZE
|
|
if ( c4 == 0 )
|
|
{
|
|
error4( c4, e4info, "OS/2 Semaphore Failure" ) ;
|
|
return ;
|
|
}
|
|
#endif
|
|
|
|
DosReleaseMutexSem( c4->hmtxMem ) ;
|
|
}
|
|
#endif /* S4WIN32 */
|
|
#endif /* S4SEMAPHORE */
|
|
|
|
#ifdef E4MISC
|
|
|
|
static char **mem4testPointers ;
|
|
static int mem4numPointer = -1 ;
|
|
static int mem4numUsed = 0 ;
|
|
|
|
#ifdef S4DATA_ALIGN
|
|
#define mem4extraChars 12
|
|
#else
|
|
#define mem4extraChars 10
|
|
#endif
|
|
#define mem4extraTot (mem4extraChars*2 + sizeof(unsigned))
|
|
#define mem4checkChar 0x55
|
|
|
|
#define MEM4INC 500
|
|
|
|
/* Returns the pointer to be returned; is passed the pointer allocated by malloc ... */
|
|
static char *mem4fixPointer( char *startPtr, unsigned largeLen )
|
|
{
|
|
char *returnPtr ;
|
|
unsigned pos ;
|
|
|
|
memset( startPtr, mem4checkChar, mem4extraChars ) ;
|
|
returnPtr = startPtr + mem4extraChars ;
|
|
|
|
memcpy( returnPtr, (void *)&largeLen, sizeof(largeLen) ) ;
|
|
pos = largeLen - mem4extraChars ;
|
|
memset( startPtr+ pos, mem4checkChar, mem4extraChars ) ;
|
|
|
|
return returnPtr + sizeof(unsigned) ;
|
|
}
|
|
|
|
/* Returns the pointer allocated by malloc; */
|
|
/* passed by pointer returned by 'mem4fixPointer' */
|
|
static char *mem4checkPointer( char *returnPtr, int clear )
|
|
{
|
|
unsigned *largeLenPtr ;
|
|
char *mallocPtr, *testPtr ;
|
|
int i, j ;
|
|
|
|
largeLenPtr = (unsigned *)(returnPtr - sizeof(unsigned)) ;
|
|
mallocPtr = returnPtr - sizeof(unsigned) - mem4extraChars ;
|
|
|
|
for ( j = 0; j < 2; j++ )
|
|
{
|
|
if (j == 0)
|
|
testPtr = mallocPtr ;
|
|
else
|
|
testPtr = mallocPtr + *largeLenPtr - mem4extraChars ;
|
|
|
|
for ( i = 0 ; i < mem4extraChars ; i++ )
|
|
if ( testPtr[i] != mem4checkChar )
|
|
{
|
|
#ifdef S4MEM_PRINT
|
|
if ( v4print != -1 )
|
|
{
|
|
#ifdef S4WINDOWS
|
|
#ifdef S4TESTING
|
|
d4displayStr( mem4displayPtr, "corrupt memory: ", 1 ) ;
|
|
d4displayPtr( mem4displayPtr, mallocPtr- sizeof(unsigned) - mem4extraChars, 0 ) ;
|
|
#endif
|
|
#else
|
|
if ( v4print )
|
|
fprintf( stdprn, "\r\ncorrupt memory: %p", mallocPtr- sizeof(unsigned) - mem4extraChars ) ;
|
|
else
|
|
printf( "\r\ncorrupt memory: %p", mallocPtr- sizeof(unsigned) - mem4extraChars ) ;
|
|
#endif
|
|
}
|
|
#endif
|
|
error4( 0, e4result, E85901 ) ;
|
|
return 0 ;
|
|
}
|
|
}
|
|
if ( clear == 1 ) /* null the memory to potentially detect re-use, including clearing check chars */
|
|
memset( mallocPtr, 0, *largeLenPtr ) ;
|
|
return mallocPtr ;
|
|
}
|
|
|
|
static int mem4pushPointer( char *ptr )
|
|
{
|
|
#ifdef S4WINDOWS
|
|
HANDLE handle, *hPtr, *oldHPtr ;
|
|
hPtr = (HANDLE *)0 ;
|
|
#endif
|
|
|
|
if ( mem4numPointer < 0 )
|
|
{
|
|
#ifdef S4WINDOWS
|
|
#ifdef __DLL__
|
|
handle = GlobalAlloc( GMEM_MOVEABLE | GMEM_DDESHARE | GMEM_ZEROINIT, (DWORD) sizeof(char *) * MEM4INC + sizeof(HANDLE) ) ;
|
|
#else
|
|
handle = GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, (DWORD) sizeof(char *) * MEM4INC + sizeof(HANDLE) ) ;
|
|
#endif
|
|
|
|
if ( handle == (HANDLE) 0 )
|
|
return error4( 0, e4memory, E95901 ) ;
|
|
|
|
hPtr = (HANDLE *)GlobalLock( handle ) ;
|
|
*hPtr++ = handle ;
|
|
mem4testPointers = (char **)hPtr ;
|
|
#else
|
|
mem4testPointers = (char **)malloc( sizeof(char *) * MEM4INC ) ;
|
|
#endif
|
|
mem4numPointer = MEM4INC ;
|
|
}
|
|
if ( mem4numPointer == mem4numUsed )
|
|
{
|
|
mem4numPointer += MEM4INC ;
|
|
if ( mem4numPointer > MEM4MAX_POINTERS )
|
|
return error4( 0, e4result, E95901 ) ;
|
|
|
|
#ifdef S4WINDOWS
|
|
oldHPtr = (HANDLE *)(mem4testPointers) ;
|
|
oldHPtr-- ; /* get the actual handle */
|
|
|
|
#ifdef __DLL__
|
|
handle = GlobalReAlloc( *oldHPtr, (DWORD)sizeof(char *) * mem4numPointer + sizeof( HANDLE ), GMEM_MOVEABLE ) ;
|
|
#else
|
|
handle = GlobalReAlloc( *oldHPtr, (DWORD)sizeof(char *) * mem4numPointer + sizeof( HANDLE ), GMEM_MOVEABLE ) ;
|
|
#endif
|
|
|
|
if ( handle == (HANDLE) 0 )
|
|
return error4( 0, e4memory, E95901 ) ;
|
|
|
|
hPtr = (HANDLE *)GlobalLock( handle ) ;
|
|
*hPtr++ = handle ;
|
|
mem4testPointers = (char **)hPtr ;
|
|
#else
|
|
mem4testPointers = (char **)realloc( (void *)mem4testPointers, sizeof(char *)*mem4numPointer ) ;
|
|
#endif
|
|
}
|
|
|
|
if ( mem4testPointers == 0 )
|
|
return error4( 0, e4memory, E95901 ) ;
|
|
|
|
mem4testPointers[mem4numUsed++] = ptr ;
|
|
|
|
return 0 ;
|
|
}
|
|
|
|
static int mem4popPointer( char *ptr )
|
|
{
|
|
int i ;
|
|
|
|
if ( mem4testPointers == 0 ) /* failure in allocating tracking memory, so allow shutdown */
|
|
{
|
|
mem4numUsed-- ;
|
|
return 0 ;
|
|
}
|
|
|
|
for ( i = mem4numUsed - 1 ; i >= 0 ; i-- )
|
|
if ( mem4testPointers[i] == ptr )
|
|
{
|
|
/* This 'memmove' may create compile warning */
|
|
c4memmove( mem4testPointers+i, mem4testPointers+i+1, (size_t) (sizeof(char *) * (mem4numUsed-i-1))) ;
|
|
mem4numUsed-- ;
|
|
return 0 ;
|
|
}
|
|
|
|
return error4( 0, e4result, E95902 ) ;
|
|
}
|
|
|
|
int S4FUNCTION mem4checkMemory()
|
|
{
|
|
int i ;
|
|
char *ptr ;
|
|
|
|
if ( code4numCodeBase() == 0 )
|
|
return 0 ;
|
|
|
|
#ifdef S4SEMAPHORE
|
|
mem4start( 0 ) ;
|
|
#endif
|
|
|
|
for ( i = 0; i < mem4numUsed; i++ )
|
|
{
|
|
ptr = mem4checkPointer( mem4testPointers[i], 0 ) ;
|
|
if ( ptr == 0 )
|
|
return error4( 0, e4result, E95903 ) ;
|
|
}
|
|
|
|
#ifdef S4SEMAPHORE
|
|
mem4stop( 0 ) ;
|
|
#endif
|
|
|
|
return 0 ;
|
|
}
|
|
|
|
int S4FUNCTION mem4freeCheck( const int maxLeft )
|
|
{
|
|
#ifdef S4MEM_PRINT
|
|
int i ;
|
|
if ( v4print != -1 )
|
|
{
|
|
#ifdef S4WINDOWS
|
|
#ifdef S4TESTING
|
|
for ( i = 0; i < mem4numUsed; i++ )
|
|
{
|
|
d4displayStr( mem4displayPtr, "mem4freeCheck: ", 1 ) ;
|
|
d4displayPtr( mem4displayPtr, mem4testPointers[i], 0 ) ;
|
|
}
|
|
#endif
|
|
#else
|
|
if ( v4print )
|
|
for ( i = 0; i < mem4numUsed; i++ )
|
|
fprintf( stdprn, "\r\nmem4freeCheck: %p", mem4testPointers[i] ) ;
|
|
else
|
|
for ( i = 0; i < mem4numUsed; i++ )
|
|
printf( "\r\nmem4freeCheck: %p", mem4testPointers[i] ) ;
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
if ( mem4numUsed > maxLeft )
|
|
return error4( 0, e4result, 95904 ) ;
|
|
|
|
return ( mem4numUsed ) ;
|
|
}
|
|
#endif
|
|
|
|
void *S4FUNCTION mem4allocDefault( MEM4 *memoryType )
|
|
{
|
|
#ifdef E4PARM_HIGH
|
|
if ( memoryType == 0 )
|
|
{
|
|
error4( 0, e4parm_null, E95905 ) ;
|
|
return 0 ;
|
|
}
|
|
#endif
|
|
|
|
return mem4alloc2Default( memoryType, 0 ) ;
|
|
}
|
|
|
|
Y4CHUNK *mem4allocChunkDefault( MEM4 *typePtr )
|
|
{
|
|
Y4CHUNK *chunkPtr ;
|
|
int nAllocate, i ;
|
|
char *ptr ;
|
|
long allocSize ;
|
|
|
|
nAllocate = typePtr->unitExpand ;
|
|
if ( l4last( &typePtr->chunks ) == 0 )
|
|
nAllocate = typePtr->unitStart ;
|
|
|
|
for ( ;; )
|
|
{
|
|
allocSize = (long)sizeof( LINK4 ) + (long)nAllocate * typePtr->unitSize ;
|
|
if ( allocSize < UINT_MAX )
|
|
break ;
|
|
if ( nAllocate <= 1 )
|
|
return 0 ;
|
|
nAllocate = nAllocate / 2 ;
|
|
}
|
|
|
|
#ifdef S4DOS /* no memory sharing under DOS, so can use a CODE4 for limited memory */
|
|
chunkPtr = (Y4CHUNK *)u4allocFreeDefault( typePtr->codeBase, allocSize ) ;
|
|
#else
|
|
chunkPtr = (Y4CHUNK *)u4alloc( allocSize ) ;
|
|
#endif
|
|
if ( chunkPtr == 0 )
|
|
return 0 ;
|
|
ptr = (char *)&chunkPtr->data ;
|
|
for ( i = 0 ; i < nAllocate ; i++ )
|
|
l4add( &typePtr->pieces, (LINK4 *)( ptr + i * typePtr->unitSize ) ) ;
|
|
|
|
return chunkPtr ;
|
|
}
|
|
|
|
static void *mem4allocLow( MEM4 *memoryType )
|
|
{
|
|
LINK4 *nextPiece ;
|
|
Y4CHUNK *newChunk ;
|
|
#ifdef E4MISC
|
|
char *ptr ;
|
|
#endif
|
|
#ifdef S4OS2_SEMAPHORE
|
|
#ifdef __DLL__
|
|
ULONG flags ;
|
|
#endif
|
|
#endif
|
|
|
|
if ( memoryType == 0 )
|
|
return 0 ;
|
|
nextPiece = (LINK4 *)l4pop( &memoryType->pieces ) ;
|
|
|
|
if ( nextPiece != 0 )
|
|
{
|
|
#ifdef S4SEMAPHORE
|
|
#ifdef S4OS2
|
|
#ifdef __DLL__
|
|
/* get access to the memory */
|
|
flags = PAG_WRITE | PAG_READ ;
|
|
if ( DosGetSharedMem( nextPiece, flags ) != 0 )
|
|
return 0 ;
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#ifdef E4MISC
|
|
memoryType->nUsed++ ;
|
|
ptr = mem4fixPointer( (char *)nextPiece, memoryType->unitSize ) ;
|
|
|
|
if ( mem4pushPointer( ptr ) == e4memory )
|
|
{
|
|
memoryType->nUsed-- ;
|
|
l4add( &memoryType->pieces, nextPiece ) ;
|
|
return 0 ;
|
|
}
|
|
|
|
#ifdef S4MEM_PRINT
|
|
if ( v4print != -1 )
|
|
{
|
|
#ifdef S4WINDOWS
|
|
#ifdef S4TESTING
|
|
{
|
|
d4displayStr( mem4displayPtr, " Y4ALLOC: ", 1 ) ;
|
|
d4displayPtr( mem4displayPtr, ptr, 0 ) ;
|
|
d4displayStr( mem4displayPtr, " file: ", 0 ) ;
|
|
d4displayStr( mem4displayPtr, m4fileName, 0 ) ;
|
|
d4displayStr( mem4displayPtr, " line: ", 0 ) ;
|
|
d4displayNum( mem4displayPtr, m4lineNo, 0 ) ;
|
|
}
|
|
#endif
|
|
#else
|
|
if ( v4print )
|
|
fprintf( stdprn, "\r\n Y4ALLOC: %lx file: %s line: %12d", ptr, m4fileName, m4lineNo ) ;
|
|
else
|
|
printf( "\r\n Y4ALLOC: %lx file: %s line: %12d", ptr, m4fileName, m4lineNo ) ;
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
return (void *)ptr ;
|
|
#else
|
|
return nextPiece ;
|
|
#endif
|
|
}
|
|
|
|
if ( (newChunk = mem4allocChunkDefault( memoryType )) == 0 )
|
|
return 0 ;
|
|
l4add( &memoryType->chunks, &newChunk->link ) ;
|
|
|
|
memoryType->nUsed++ ;
|
|
#ifdef E4MISC
|
|
ptr = mem4fixPointer( (char *)l4pop(&memoryType->pieces),
|
|
memoryType->unitSize ) ;
|
|
#ifdef S4MEM_PRINT
|
|
if ( v4print != -1 )
|
|
{
|
|
#ifdef S4WINDOWS
|
|
#ifdef S4TESTING
|
|
{
|
|
d4displayStr( mem4displayPtr, " Y4ALLOC: ", 1 ) ;
|
|
d4displayPtr( mem4displayPtr, ptr, 0 ) ;
|
|
d4displayStr( mem4displayPtr, " file: ", 0 ) ;
|
|
d4displayStr( mem4displayPtr, m4fileName, 0 ) ;
|
|
d4displayStr( mem4displayPtr, " line: ", 0 ) ;
|
|
d4displayNum( mem4displayPtr, m4lineNo, 0 ) ;
|
|
}
|
|
#endif
|
|
#else
|
|
if ( v4print )
|
|
fprintf( stdprn, "\r\n Y4ALLOC: %lx file: %s line: %12d", ptr, m4fileName, m4lineNo ) ;
|
|
else
|
|
printf( "\r\n Y4ALLOC: %lx file: %s line: %12d", ptr, m4fileName, m4lineNo ) ;
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
mem4pushPointer( ptr ) ;
|
|
return (void *)ptr ;
|
|
#else
|
|
return l4pop( &memoryType->pieces ) ;
|
|
#endif
|
|
}
|
|
|
|
void *S4FUNCTION mem4alloc2Default( MEM4 *memoryType, CODE4 *c4 )
|
|
{
|
|
void *ptr ;
|
|
|
|
if ( code4numCodeBase() == 0 )
|
|
return 0 ;
|
|
|
|
if ( c4 )
|
|
if ( error4code( c4 ) < 0 )
|
|
return 0 ;
|
|
|
|
#ifdef S4SEMAPHORE
|
|
mem4start( c4 ) ;
|
|
#endif
|
|
|
|
ptr = mem4allocLow( memoryType ) ;
|
|
|
|
#ifdef S4SEMAPHORE
|
|
#ifdef S4WIN32
|
|
mem4stop( c4 ) ;
|
|
#else
|
|
mem4stop( memoryType->codeBase ) ;
|
|
#endif
|
|
#endif
|
|
|
|
if ( ptr == 0 )
|
|
{
|
|
if ( c4 )
|
|
error4set( c4, e4memory ) ;
|
|
return 0 ;
|
|
}
|
|
#ifdef E4MISC
|
|
memset( ptr, 0, memoryType->unitSize - mem4extraTot ) ;
|
|
#else
|
|
memset( ptr, 0, memoryType->unitSize ) ;
|
|
#endif
|
|
return ptr ;
|
|
}
|
|
|
|
MEM4 *S4FUNCTION mem4createDefault( CODE4 *c4, int start, const unsigned int uSize, int expand, const int isTemp )
|
|
{
|
|
MEM4 *onType ;
|
|
unsigned int unitSize ;
|
|
#ifdef S4SEMAPHORE
|
|
#ifdef S4OS2
|
|
#ifdef __DLL__
|
|
ULONG flags ;
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef E4PARM_HIGH
|
|
/* c4 == 0 is allowable */
|
|
if ( start < 1 || expand < 1 )
|
|
{
|
|
error4( c4, e4parm, E95906 ) ;
|
|
return 0 ;
|
|
}
|
|
#endif
|
|
|
|
if ( code4numCodeBase() == 0 )
|
|
return 0 ;
|
|
|
|
if ( uSize < sizeof( LINK4 ) ) /* ensure enough so that we can keep track of the memory */
|
|
unitSize = sizeof( LINK4 ) ;
|
|
else
|
|
unitSize = uSize ;
|
|
|
|
#ifdef E4MISC
|
|
unitSize += 2 * mem4extraChars + sizeof( unsigned ) ;
|
|
#endif
|
|
|
|
if ( c4 )
|
|
if ( error4code( c4 ) < 0 )
|
|
return 0 ;
|
|
|
|
#ifdef S4SEMAPHORE
|
|
mem4start( c4 ) ;
|
|
#endif
|
|
|
|
if ( !isTemp )
|
|
for( onType = 0 ;; )
|
|
{
|
|
onType = (MEM4 *)l4next( &used, onType ) ;
|
|
if ( onType == 0 )
|
|
break ;
|
|
|
|
#ifdef S4SEMAPHORE
|
|
#ifdef S4OS2
|
|
#ifdef __DLL__
|
|
/* get access to the memory */
|
|
flags = PAG_WRITE | PAG_READ ;
|
|
if ( DosGetSharedMem( onType, flags ) != 0 )
|
|
return 0 ;
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef S4DOS /* no memory sharing under DOS, so can use a CODE4 for limited memory */
|
|
if ( onType->codeBase == c4 || onType->codeBase == 0 )
|
|
#endif
|
|
if ( onType->unitSize == unitSize && onType->nRepeat > 0 )
|
|
{
|
|
/* Match */
|
|
if ( start > onType->unitStart )
|
|
onType->unitStart = start ;
|
|
if ( expand > onType->unitExpand)
|
|
onType->unitExpand = expand ;
|
|
onType->nRepeat++ ;
|
|
#ifdef S4SEMAPHORE
|
|
mem4stop( c4 ) ;
|
|
#endif
|
|
#ifdef S4DOS
|
|
if ( onType->codeBase == 0 ) /* set to avoid code4initUndo() errors */
|
|
onType->codeBase = c4 ;
|
|
#endif
|
|
return onType ;
|
|
}
|
|
}
|
|
|
|
/* Allocate memory for another MEM4 */
|
|
|
|
onType = (MEM4 *)l4last( &avail ) ;
|
|
if ( onType == 0 )
|
|
{
|
|
MEMORY4GROUP *group ;
|
|
int i ;
|
|
|
|
#ifdef S4MEM_PRINT
|
|
char *nullPtr = 0 ;
|
|
|
|
if ( v4print != -1 )
|
|
{
|
|
#ifdef S4WINDOWS
|
|
#ifdef S4TESTING
|
|
{
|
|
d4displayStr( mem4displayPtr, " MEM4: ", 1 ) ;
|
|
d4displayPtr( mem4displayPtr, nullPtr, 0 ) ;
|
|
d4displayStr( mem4displayPtr, " file: ", 0 ) ;
|
|
d4displayStr( mem4displayPtr, "ignoreNextLine", 0 ) ;
|
|
d4displayStr( mem4displayPtr, " line: ", 0 ) ;
|
|
d4displayNum( mem4displayPtr, 0, 0 ) ;
|
|
d4displayStr( mem4displayPtr, " num bytes: ", 0 ) ;
|
|
d4displayNum( mem4displayPtr, 0, 0 ) ;
|
|
}
|
|
#endif
|
|
#else
|
|
if ( v4print )
|
|
fprintf( stdprn, "\r\n MEM4: %lx file: ignoreNextLine line: %12d num bytes: %12d", nullPtr, 0, 0 ) ;
|
|
else
|
|
printf("\r\n MEM4: %lx file: ignoreNextLine line: %12d num bytes: %12d", nullPtr, 0, 0 ) ;
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
group = (MEMORY4GROUP *)u4allocFreeDefault( c4, (long)sizeof( MEMORY4GROUP ) ) ;
|
|
if ( group == 0 )
|
|
{
|
|
if ( c4 )
|
|
error4set( c4, e4memory ) ;
|
|
#ifdef S4SEMAPHORE
|
|
mem4stop( c4 ) ;
|
|
#endif
|
|
return 0 ;
|
|
}
|
|
|
|
for ( i = 0 ; i < mem4numTypes ; i++ )
|
|
l4add( &avail, group->types + i ) ;
|
|
onType = (MEM4 *)l4last( &avail ) ;
|
|
l4add( &groups, group ) ;
|
|
}
|
|
|
|
l4remove( &avail, onType ) ;
|
|
memset( (void *)onType, 0, sizeof( MEM4 ) ) ;
|
|
l4add( &used, onType ) ;
|
|
|
|
onType->unitStart = start ;
|
|
onType->unitSize = unitSize ;
|
|
onType->unitExpand= expand ;
|
|
onType->nRepeat = 1 ;
|
|
onType->nUsed = 0 ;
|
|
if ( isTemp )
|
|
onType->nRepeat = -1 ;
|
|
|
|
#ifdef S4SEMAPHORE
|
|
mem4stop( c4 ) ;
|
|
#endif
|
|
|
|
#ifdef S4MEM_PRINT
|
|
if ( v4print != -1 )
|
|
{
|
|
#ifdef S4WINDOWS
|
|
#ifdef S4TESTING
|
|
{
|
|
d4displayStr( mem4displayPtr, " MEM4: ", 1 ) ;
|
|
d4displayPtr( mem4displayPtr, onType, 0 ) ;
|
|
d4displayStr( mem4displayPtr, " file: ", 0 ) ;
|
|
d4displayStr( mem4displayPtr, m4fileName, 0 ) ;
|
|
d4displayStr( mem4displayPtr, " line: ", 0 ) ;
|
|
d4displayNum( mem4displayPtr, m4lineNo, 0 ) ;
|
|
}
|
|
#endif
|
|
#else
|
|
if ( v4print )
|
|
fprintf( stdprn, "\r\n MEM4: %lx file: %s line: %12d", onType, m4fileName, m4lineNo ) ;
|
|
else
|
|
printf( "\r\n MEM4: %lx file: %s line: %12d", onType, m4fileName, m4lineNo ) ;
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
#ifdef S4DOS /* no memory sharing under DOS, so can use a CODE4 for limited memory */
|
|
onType->codeBase = c4 ;
|
|
#endif
|
|
return onType ;
|
|
}
|
|
|
|
void *S4FUNCTION mem4createAllocDefault( CODE4 *c4, MEM4 **typePtrPtr, int start, const unsigned int unitSize, int expand, const int isTemp)
|
|
{
|
|
if ( *typePtrPtr == 0 )
|
|
{
|
|
*typePtrPtr = mem4createDefault( c4, start, unitSize, expand, isTemp ) ;
|
|
if ( *typePtrPtr == 0 )
|
|
return 0 ;
|
|
}
|
|
|
|
return mem4alloc2Default( *typePtrPtr, c4 ) ;
|
|
}
|
|
|
|
int S4FUNCTION mem4freeDefault( MEM4 *memoryType, void *freePtr )
|
|
{
|
|
#ifdef E4MISC
|
|
int rc ;
|
|
LINK4 *holdPtr ;
|
|
#endif
|
|
|
|
if ( freePtr == 0 ) /* as documented */
|
|
return 0 ;
|
|
|
|
if ( memoryType == 0 )
|
|
return error4( 0, e4parm_null, E95907 ) ;
|
|
|
|
if ( code4numCodeBase() == 0 )
|
|
return 0 ;
|
|
|
|
#ifdef S4SEMAPHORE
|
|
mem4start( 0 ) ;
|
|
#endif
|
|
|
|
memoryType->nUsed-- ;
|
|
#ifdef E4MISC
|
|
if ( memoryType->nUsed < 0 )
|
|
{
|
|
#ifdef S4SEMAPHORE
|
|
mem4stop( 0 ) ;
|
|
#endif
|
|
return error4( 0, e4result, E95907 ) ;
|
|
}
|
|
|
|
rc = mem4popPointer( (char *)freePtr ) ;
|
|
holdPtr = (LINK4 *)mem4checkPointer( (char *)freePtr, 0 ) ;
|
|
if ( holdPtr != 0 )
|
|
{
|
|
l4add( &memoryType->pieces, holdPtr ) ;
|
|
#ifdef S4MEM_PRINT
|
|
if ( v4print != -1 )
|
|
{
|
|
#ifdef S4WINDOWS
|
|
#ifdef S4TESTING
|
|
{
|
|
d4displayStr( mem4displayPtr, " Y4FREE: ", 1 ) ;
|
|
d4displayPtr( mem4displayPtr, freePtr, 0 ) ;
|
|
d4displayStr( mem4displayPtr, " file: ", 0 ) ;
|
|
d4displayStr( mem4displayPtr, m4fileName, 0 ) ;
|
|
d4displayStr( mem4displayPtr, " line: ", 0 ) ;
|
|
d4displayNum( mem4displayPtr, m4lineNo, 0 ) ;
|
|
}
|
|
#endif
|
|
#else
|
|
if ( v4print )
|
|
fprintf(stdprn, "\r\n Y4FREE: %lx file: %s line: %12d", freePtr, m4fileName, m4lineNo ) ;
|
|
else
|
|
printf( "\r\n Y4FREE: %lx file: %s line: %12d", freePtr, m4fileName, m4lineNo ) ;
|
|
#endif
|
|
}
|
|
#endif
|
|
}
|
|
|
|
memset( ((char *)freePtr), 0, memoryType->unitSize - 2 * mem4extraChars - sizeof( unsigned ) ) ;
|
|
#ifdef S4SEMAPHORE
|
|
mem4stop( 0 ) ;
|
|
#endif
|
|
return rc ;
|
|
#else
|
|
l4add( &memoryType->pieces, (LINK4 *)freePtr ) ;
|
|
#ifdef S4SEMAPHORE
|
|
mem4stop( 0 ) ;
|
|
#endif
|
|
return 0 ;
|
|
#endif
|
|
}
|
|
|
|
void S4FUNCTION mem4release( MEM4 *memoryType )
|
|
{
|
|
void *ptr ;
|
|
|
|
if ( memoryType == 0 )
|
|
return ;
|
|
|
|
if ( code4numCodeBase() == 0 )
|
|
return ;
|
|
|
|
#ifdef S4SEMAPHORE
|
|
mem4start( 0 ) ;
|
|
#endif
|
|
|
|
memoryType->nRepeat-- ;
|
|
if ( memoryType->nRepeat <= 0 )
|
|
{
|
|
for(;;)
|
|
{
|
|
ptr = l4pop( &memoryType->chunks) ;
|
|
if ( ptr == 0 )
|
|
break ;
|
|
u4freeDefault( ptr ) ;
|
|
}
|
|
|
|
l4remove( &used, memoryType ) ;
|
|
l4add( &avail, memoryType ) ;
|
|
|
|
#ifdef S4MEM_PRINT
|
|
if ( v4print != -1 )
|
|
{
|
|
#ifdef S4WINDOWS
|
|
#ifdef S4TESTING
|
|
{
|
|
d4displayStr( mem4displayPtr, " Y4RELEASE: ", 1 ) ;
|
|
d4displayPtr( mem4displayPtr, memoryType, 0 ) ;
|
|
}
|
|
#endif
|
|
#else
|
|
if ( v4print )
|
|
fprintf( stdprn, "\r\n Y4RELEASE: %lx", memoryType ) ;
|
|
else
|
|
printf( "\r\n Y4RELEASE: %lx", memoryType ) ;
|
|
#endif
|
|
}
|
|
#endif
|
|
}
|
|
|
|
#ifdef S4SEMAPHORE
|
|
mem4stop( 0 ) ;
|
|
#endif
|
|
}
|
|
|
|
#ifdef S4TESTING
|
|
int s4allocOff = 0 ;
|
|
#endif
|
|
|
|
#ifdef S4MAX
|
|
static long mem4maxMemory = 16384 ;
|
|
static long mem4allocated = 0L ;
|
|
|
|
long u4allocated( void )
|
|
{
|
|
return mem4allocated ;
|
|
}
|
|
|
|
long u4max( void )
|
|
{
|
|
return mem4maxMemory ;
|
|
}
|
|
#endif
|
|
|
|
void *S4FUNCTION u4allocDefault( long n )
|
|
{
|
|
size_t s ;
|
|
char *ptr ;
|
|
#ifdef S4SEMAPHORE
|
|
#ifdef S4OS2
|
|
#ifdef __DLL__
|
|
ULONG flags;
|
|
APIRET rc;
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#ifdef S4WINDOWS
|
|
HANDLE handle, *hPtr ;
|
|
#endif
|
|
|
|
#ifdef S4TESTING
|
|
if ( s4allocOff == 1 ) /* for testing, emulate out of memory conditions */
|
|
return 0 ;
|
|
#endif
|
|
|
|
#ifdef E4PARM_HIGH
|
|
if ( n == 0L )
|
|
{
|
|
error4( 0, e4parm, E85903 ) ;
|
|
return 0 ;
|
|
}
|
|
#ifdef E4MISC
|
|
n += mem4extraChars*2 + sizeof(unsigned) ;
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef S4MAX
|
|
n += sizeof( long ) ; /* room for length */
|
|
if ( mem4allocated + n > mem4maxMemory )
|
|
return 0 ;
|
|
#endif
|
|
|
|
s = (size_t) n ;
|
|
if ( n > (long) s )
|
|
return 0 ;
|
|
|
|
#ifdef S4WINDOWS
|
|
#ifdef __DLL__
|
|
handle = GlobalAlloc( GMEM_MOVEABLE | GMEM_DDESHARE | GMEM_ZEROINIT, (DWORD) s+ sizeof(HANDLE) ) ;
|
|
#else
|
|
handle = GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, (DWORD) s+ sizeof(HANDLE) ) ;
|
|
#endif
|
|
|
|
if ( handle == (HANDLE)0 )
|
|
return 0 ;
|
|
|
|
hPtr = (HANDLE *)GlobalLock( handle ) ;
|
|
*hPtr++ = handle ;
|
|
ptr = (char *)hPtr ;
|
|
#else
|
|
#ifdef __DLL__
|
|
#ifdef S4OS2_SEMAPHORE
|
|
flags = PAG_WRITE | PAG_READ | OBJ_GETTABLE ;
|
|
rc = DosAllocSharedMem( (void *)&ptr, 0, s, flags ) ;
|
|
|
|
if (rc != 0)
|
|
return 0 ;
|
|
flags = PAG_WRITE | PAG_READ ;
|
|
rc = DosGetSharedMem( ptr, flags ) ;
|
|
if ( rc != 0 )
|
|
return 0 ;
|
|
#else
|
|
ptr = (char *)malloc( s ) ;
|
|
|
|
if ( ptr == 0 )
|
|
return 0 ;
|
|
|
|
#ifndef S4PASCAL_WIN
|
|
memset( ptr, 0, s ) ;
|
|
#endif
|
|
#endif
|
|
#else
|
|
ptr = (char *)malloc( s ) ;
|
|
|
|
if ( ptr == 0 )
|
|
return 0 ;
|
|
|
|
/* Borland malloc of 64K (or close to) will */
|
|
#ifdef __TURBOC__ /* result in corruption of segment memory due */
|
|
if ( (ptr+s-1 <= ptr) && (s > 1 )) /* to wrap-around problems */
|
|
{
|
|
free( ptr ) ;
|
|
return 0 ;
|
|
}
|
|
#endif
|
|
|
|
#ifndef S4PASCAL_WIN
|
|
memset( ptr, 0, s ) ;
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef S4MEM_PRINT
|
|
if ( v4print != -1 )
|
|
{
|
|
#ifdef S4WINDOWS
|
|
#ifdef S4TESTING
|
|
{
|
|
d4displayStr( mem4displayPtr, " U4ALLOC: ", 1 ) ;
|
|
d4displayPtr( mem4displayPtr, ptr, 0 ) ;
|
|
d4displayStr( mem4displayPtr, " file: ", 0 ) ;
|
|
d4displayStr( mem4displayPtr, m4fileName, 0 ) ;
|
|
d4displayStr( mem4displayPtr, " line: ", 0 ) ;
|
|
d4displayNum( mem4displayPtr, m4lineNo, 0 ) ;
|
|
d4displayStr( mem4displayPtr, " num bytes: ", 0 ) ;
|
|
d4displayNum( mem4displayPtr, n, 0 ) ;
|
|
}
|
|
#endif
|
|
#else
|
|
if ( v4print )
|
|
fprintf( stdprn, "\r\n U4ALLOC: %lx file: %s line: %12d num bytes: %12ld", ptr, m4fileName, m4lineNo, n ) ;
|
|
else
|
|
printf("\r\n U4ALLOC: %lx file: %s line: %12d num bytes: %12ld", ptr, m4fileName, m4lineNo, n ) ;
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
#ifdef E4MISC
|
|
#ifdef S4SEMAPHORE
|
|
mem4start( 0 ) ;
|
|
#endif
|
|
ptr = mem4fixPointer( ptr, s ) ;
|
|
mem4pushPointer( ptr ) ;
|
|
memset( ptr, 0, s-mem4extraChars*2 - sizeof(unsigned) ) ;
|
|
#ifdef S4SEMAPHORE
|
|
mem4stop( 0 ) ;
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef S4MAX
|
|
#ifdef S4SEMAPHORE
|
|
mem4start( 0 ) ;
|
|
#endif
|
|
mem4allocated += n ;
|
|
#ifdef S4SEMAPHORE
|
|
mem4stop( 0 ) ;
|
|
#endif
|
|
*((long *)ptr) = n ;
|
|
ptr += sizeof( long ) ;
|
|
#endif
|
|
|
|
return (void *)ptr ;
|
|
}
|
|
|
|
void S4FUNCTION u4freeFixedDefault( FIXED4MEM fixedMem )
|
|
{
|
|
#ifdef S4USE_LOW_MEMORY
|
|
if ( ( GetWinFlags() & WF_ENHANCED ) == WF_ENHANCED )
|
|
GlobalPageUnlock( (HGLOBAL)s4protected( fixedMem ) ) ;
|
|
GlobalDosFree( (HGLOBAL)s4protected( fixedMem ) ) ;
|
|
#else
|
|
u4freeDefault( fixedMem ) ;
|
|
#endif
|
|
}
|
|
|
|
/* u4alloc_fixed() allocates fixed memory blocks in the lower 1 MEG of ram.
|
|
It is used for allocating memory that is to be used with DOS interrupts.
|
|
*/
|
|
FIXED4MEM S4FUNCTION u4allocFixedDefault( CODE4 *c4, long n )
|
|
{
|
|
#ifdef S4USE_LOW_MEMORY
|
|
size_t s ;
|
|
FIXED4MEM fixedMem ;
|
|
|
|
memset( &fixedMem, 0, sizeof( FIXED4MEM ) ) ;
|
|
|
|
#ifdef E4PARM_LOW
|
|
if ( c4 == 0 )
|
|
{
|
|
error4( 0, e4parm_null, E95908 ) ;
|
|
return fixedMem ;
|
|
}
|
|
|
|
if ( n == 0L )
|
|
{
|
|
error4( c4, e4parm, E85903 ) ;
|
|
return fixedMem ;
|
|
}
|
|
n += mem4extraChars*2 + sizeof(unsigned) ;
|
|
#endif
|
|
|
|
s = (size_t)n ;
|
|
if ( n > (long)s )
|
|
return fixedMem ;
|
|
|
|
#ifdef __DLL__
|
|
fixedMem.block = GlobalDosAlloc( (DWORD)s + sizeof(HANDLE) ) ;
|
|
#else
|
|
fixedMem.block = GlobalDosAlloc( (DWORD)s + sizeof(HANDLE) ) ;
|
|
#endif
|
|
|
|
if ( fixedMem.block == 0 )
|
|
return fixedMem ;
|
|
|
|
if ( ( GetWinFlags() & WF_ENHANCED ) == WF_ENHANCED )
|
|
GlobalPageLock( (HGLOBAL)s4protected( fixedMem ) ) ;
|
|
|
|
memset( (void *)s4protected( fixedMem ), 0, (size_t)n ) ;
|
|
return fixedMem ;
|
|
#else
|
|
return u4allocFreeDefault( c4, n ) ;
|
|
#endif
|
|
}
|
|
|
|
void *S4FUNCTION u4allocErDefault( CODE4 *c4, long n )
|
|
{
|
|
void *ptr = (void *)u4allocFreeDefault( c4, n ) ;
|
|
if ( ptr == 0 && c4 )
|
|
error4( c4, e4memory, E95909 ) ;
|
|
|
|
return ptr ;
|
|
}
|
|
|
|
int S4FUNCTION u4freeDefault( void *ptr )
|
|
{
|
|
int rc ;
|
|
#ifdef S4WINDOWS
|
|
HANDLE hand ;
|
|
#endif
|
|
|
|
#ifdef S4MAX
|
|
long amount ;
|
|
#endif
|
|
|
|
rc = 0 ;
|
|
|
|
if ( code4numCodeBase() == 0 )
|
|
return 0 ;
|
|
|
|
if ( ptr == 0 )
|
|
return 0 ;
|
|
|
|
#ifdef S4MAX
|
|
ptr = ((char *)ptr) - sizeof( long ) ;
|
|
amount = *((long *)ptr) ;
|
|
#ifdef S4SEMAPHORE
|
|
mem4start( 0 ) ;
|
|
#endif
|
|
mem4allocated -= amount ;
|
|
#ifdef S4SEMAPHORE
|
|
mem4stop( 0 ) ;
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef S4WINDOWS
|
|
#ifdef E4MISC
|
|
rc = mem4popPointer( (char *)ptr ) ;
|
|
ptr = mem4checkPointer( (char *)ptr, 1 ) ;
|
|
if ( (char *)ptr == 0 ) /* error during mem check */
|
|
return -1 ;
|
|
hand = ((HANDLE *)(char *)ptr)[-1] ;
|
|
#else
|
|
hand = ((HANDLE *)ptr)[-1] ;
|
|
#endif
|
|
|
|
#ifdef S4MEM_PRINT
|
|
if ( v4print != -1 )
|
|
{
|
|
#ifdef S4WINDOWS
|
|
#ifdef S4TESTING
|
|
d4displayStr( mem4displayPtr, " U4FREE: ", 1 ) ;
|
|
d4displayPtr( mem4displayPtr, ptr, 0 ) ;
|
|
d4displayStr( mem4displayPtr, " file: ", 0 ) ;
|
|
d4displayStr( mem4displayPtr, m4fileName, 0 ) ;
|
|
d4displayStr( mem4displayPtr, " line: ", 0 ) ;
|
|
d4displayNum( mem4displayPtr, m4lineNo, 0 ) ;
|
|
#endif
|
|
#endif
|
|
}
|
|
#endif
|
|
GlobalUnlock( hand ) ;
|
|
hand = GlobalFree( hand ) ;
|
|
|
|
if ( hand != (HANDLE) 0 )
|
|
return error4( 0, e4memory, E95910 ) ;
|
|
#else
|
|
#ifdef E4MISC
|
|
#ifdef S4SEMAPHORE
|
|
mem4start( 0 ) ;
|
|
#endif
|
|
rc = mem4popPointer( (char *)ptr ) ;
|
|
ptr = mem4checkPointer( (char *)ptr, 1 ) ;
|
|
#ifdef S4SEMAPHORE
|
|
mem4stop( 0 ) ;
|
|
#endif
|
|
|
|
#ifdef S4MEM_PRINT
|
|
if ( v4print != -1 )
|
|
{
|
|
#ifdef S4WINDOWS
|
|
#ifdef S4TESTING
|
|
{
|
|
d4displayStr( mem4displayPtr, " U4FREE: ", 1 ) ;
|
|
d4displayPtr( mem4displayPtr, ptr, 0 ) ;
|
|
d4displayStr( mem4displayPtr, " file: ", 0 ) ;
|
|
d4displayStr( mem4displayPtr, m4fileName, 0 ) ;
|
|
d4displayStr( mem4displayPtr, " line: ", 0 ) ;
|
|
d4displayNum( mem4displayPtr, m4lineNo, 0 ) ;
|
|
}
|
|
#endif
|
|
#else
|
|
if ( v4print )
|
|
fprintf( stdprn, "\r\n U4FREE: %lx file: %s line: %12d", ptr, m4fileName, m4lineNo ) ;
|
|
else
|
|
printf( "\r\n U4FREE: %lx file: %s line: %12d", ptr, m4fileName, m4lineNo );
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
free( ptr ) ;
|
|
#else
|
|
#ifdef S4MEM_PRINT
|
|
if ( v4print != -1 )
|
|
{
|
|
#ifdef S4WINDOWS
|
|
#ifdef S4TESTING
|
|
{
|
|
d4displayStr( mem4displayPtr, " U4FREE: ", 1 ) ;
|
|
d4displayPtr( mem4displayPtr, ptr, 0 ) ;
|
|
d4displayStr( mem4displayPtr, " file: ", 0 ) ;
|
|
d4displayStr( mem4displayPtr, m4fileName, 0 ) ;
|
|
d4displayStr( mem4displayPtr, " line: ", 0 ) ;
|
|
d4displayNum( mem4displayPtr, m4lineNo, 0 ) ;
|
|
}
|
|
#endif
|
|
#else
|
|
if ( v4print )
|
|
fprintf( stdprn, "\r\n U4FREE: %lx file: %s line: %12d", ptr, m4fileName, m4lineNo ) ;
|
|
else
|
|
printf( "\r\n U4FREE: %lx file: %s line: %12d", ptr, m4fileName, m4lineNo );
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
free( ptr ) ;
|
|
#endif
|
|
#endif
|
|
|
|
return rc ;
|
|
}
|
|
|
|
int mem4reset( void )
|
|
{
|
|
MEM4 *onType ;
|
|
LINK4 *onChunk, *onGroup ;
|
|
#ifdef S4WINDOWS
|
|
#ifdef E4MISC
|
|
HANDLE hand ;
|
|
#endif
|
|
#endif
|
|
#ifdef S4LOCK_CHECK
|
|
return error4( 0, e4result, E85904 ) ;
|
|
#endif
|
|
|
|
for( onType = 0 ;; )
|
|
{
|
|
onType = (MEM4 *)l4next(&used,onType) ;
|
|
if ( onType == 0 )
|
|
break ;
|
|
do
|
|
{
|
|
onChunk = (LINK4 *)l4pop( &onType->chunks) ;
|
|
u4freeDefault( onChunk ) ; /* free of 0 still succeeds */
|
|
} while ( onChunk ) ;
|
|
}
|
|
|
|
for( ;; )
|
|
{
|
|
onGroup = (LINK4 *)l4pop( &groups ) ;
|
|
if ( onGroup == 0 )
|
|
break ;
|
|
u4freeDefault( onGroup ) ;
|
|
}
|
|
|
|
#ifdef E4MISC
|
|
if ( mem4numPointer > 0 )
|
|
{
|
|
#ifdef S4WINDOWS
|
|
hand = ((HANDLE *)mem4testPointers)[-1] ;
|
|
|
|
GlobalUnlock( hand ) ;
|
|
hand = GlobalFree( hand ) ;
|
|
|
|
if ( hand != (HANDLE)0 )
|
|
return error4( 0, e4memory, E95911 ) ;
|
|
#else
|
|
#ifdef S4MEM_PRINT
|
|
if ( v4print != -1 )
|
|
{
|
|
#ifdef S4WINDOWS
|
|
#ifdef S4TESTING
|
|
{
|
|
d4displayStr( mem4displayPtr, " MEM4RESET: ", 1 ) ;
|
|
d4displayPtr( mem4displayPtr, mem4testPointers, 0 ) ;
|
|
#endif
|
|
#else
|
|
if ( v4print )
|
|
fprintf( stdprn, "\r\n MEM4RESET: %lx", mem4testPointers ) ;
|
|
else
|
|
printf( "\r\n MEM4RESET: %lx", mem4testPointers );
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
free( (void *)mem4testPointers ) ;
|
|
#endif
|
|
|
|
mem4testPointers = 0 ;
|
|
mem4numPointer = -1 ;
|
|
mem4numUsed = 0 ;
|
|
}
|
|
#endif
|
|
|
|
mem4init() ;
|
|
|
|
#ifdef S4SEMAPHORE
|
|
#ifdef S4WIN32
|
|
DeleteCriticalSection( &critical4memory ) ;
|
|
DeleteCriticalSection( &critical4expression ) ;
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef S4SEMAPHORE
|
|
#ifdef S4WIN32
|
|
memoryInitialized = 0 ;
|
|
#endif
|
|
#endif
|
|
|
|
return 0 ;
|
|
}
|
|
|
|
void mem4init( void )
|
|
{
|
|
if ( code4numCodeBase() != 0 )
|
|
return ;
|
|
|
|
#ifdef S4SEMAPHORE
|
|
#ifdef S4WIN32
|
|
memoryInitialized = 1 ;
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef S4SEMAPHORE
|
|
#ifdef S4WIN32
|
|
InitializeCriticalSection( &critical4memory ) ;
|
|
InitializeCriticalSection( &critical4expression ) ;
|
|
#endif
|
|
mem4start( 0 ) ;
|
|
#endif
|
|
memset( (void *)&avail, 0, sizeof( avail ) ) ;
|
|
memset( (void *)&used, 0, sizeof( used ) ) ;
|
|
memset( (void *)&groups, 0, sizeof( groups ) ) ;
|
|
#ifdef S4SEMAPHORE
|
|
mem4stop( 0 ) ;
|
|
#endif
|
|
}
|
|
|