a0f5e0898b
which included commits to RCS files with non-trunk default branches. git-svn-id: svn://10.65.10.50/trunk@976 c028cbd2-c16b-5b4b-a496-9718f37d4682
824 lines
17 KiB
C
Executable File
824 lines
17 KiB
C
Executable File
/* m4memory.c (c)Copyright Sequiter Software Inc., 1990-1994. All rights reserved. */
|
|
|
|
#ifdef S4OS2
|
|
#ifdef __DLL__
|
|
#define INCL_DOSMEMMGR
|
|
#endif
|
|
#endif
|
|
#include "d4all.h"
|
|
|
|
#ifdef S4VB_DOS
|
|
#include "malloc.h"
|
|
#endif
|
|
|
|
#ifndef S4UNIX
|
|
#ifdef __TURBOC__
|
|
#pragma hdrstop
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef S4OS2
|
|
#ifdef __DLL__
|
|
#include <bsememf.h>
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef S4MEM_PRINT
|
|
int v4print = 0 ; /* if v4print == 0 then stdout, else stdprn */
|
|
#endif
|
|
|
|
#define mem4num_types 10
|
|
|
|
typedef struct
|
|
{
|
|
LINK4 link ;
|
|
MEM4 types[mem4num_types] ;
|
|
} MEMORY4GROUP ;
|
|
|
|
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 */
|
|
|
|
#ifdef S4OS2
|
|
#ifdef S4OS2SEM
|
|
int mem4start( CODE4 *c4 )
|
|
{
|
|
APIRET rc ;
|
|
|
|
#ifdef S4DEBUG
|
|
if ( c4 == 0 )
|
|
return e4( c4, e4info, "OS/2 Semaphore Failure" ) ;
|
|
#endif
|
|
|
|
rc = DosRequestMutexSem( c4->hmtx_mem, -1 ) ;
|
|
if ( rc != 0 )
|
|
return e4( c4, e4info, "OS/2 Semaphore Failure" ) ;
|
|
return 0 ;
|
|
}
|
|
|
|
void mem4stop( CODE4 *c4 )
|
|
{
|
|
#ifdef S4DEBUG
|
|
if ( c4 == 0 )
|
|
{
|
|
e4( c4, e4info, "OS/2 Semaphore Failure" ) ;
|
|
return ;
|
|
}
|
|
#endif
|
|
|
|
DosReleaseMutexSem( c4->hmtx_mem ) ;
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef S4DEBUG
|
|
|
|
static char **mem4test_pointers ;
|
|
static int mem4num_pointer = -1 ;
|
|
static int mem4num_used = 0 ;
|
|
|
|
#ifdef S4UNIX
|
|
#define mem4extra_chars 12
|
|
#else
|
|
#define mem4extra_chars 10
|
|
#endif
|
|
#define mem4extra_tot (mem4extra_chars*2 + sizeof(unsigned))
|
|
#define mem4check_char 0x55
|
|
|
|
/* Returns the pointer to be returned; is passed the pointer allocated by malloc ... */
|
|
static char *mem4fix_pointer( char *start_ptr, unsigned large_len )
|
|
{
|
|
char *return_ptr ;
|
|
unsigned pos ;
|
|
|
|
memset( start_ptr, mem4check_char, mem4extra_chars ) ;
|
|
return_ptr = start_ptr + mem4extra_chars ;
|
|
|
|
memcpy( return_ptr, (void *)&large_len, sizeof(large_len) ) ;
|
|
pos = large_len - mem4extra_chars ;
|
|
memset( start_ptr+ pos, mem4check_char, mem4extra_chars ) ;
|
|
|
|
return return_ptr + sizeof(unsigned) ;
|
|
}
|
|
|
|
/* Returns the pointer allocated by malloc; */
|
|
/* passed by pointer returned by 'mem4fix_pointer' */
|
|
static char *mem4check_pointer( char *return_ptr, int clear )
|
|
{
|
|
unsigned *large_len_ptr ;
|
|
char *malloc_ptr, *test_ptr ;
|
|
int i, j ;
|
|
|
|
large_len_ptr = (unsigned *)(return_ptr - sizeof(unsigned)) ;
|
|
malloc_ptr = return_ptr - sizeof(unsigned) - mem4extra_chars ;
|
|
|
|
for ( j = 0; j < 2; j++ )
|
|
{
|
|
if (j == 0)
|
|
test_ptr = malloc_ptr ;
|
|
else
|
|
test_ptr = malloc_ptr + *large_len_ptr - mem4extra_chars ;
|
|
|
|
for ( i = 0 ; i < mem4extra_chars ; i++ )
|
|
if ( test_ptr[i] != mem4check_char )
|
|
e4severe( e4result, E4_RESULT_CMP ) ;
|
|
}
|
|
if ( clear == 1 ) /* null the memory to potentially detect re-use, including clearing check chars */
|
|
memset( malloc_ptr, 0, *large_len_ptr ) ;
|
|
return malloc_ptr ;
|
|
}
|
|
|
|
static void mem4push_pointer( char *ptr )
|
|
{
|
|
#ifdef S4WINDOWS
|
|
HANDLE handle, *h_ptr, *old_h_ptr ;
|
|
h_ptr = (HANDLE *)0 ;
|
|
#endif
|
|
|
|
if ( mem4num_pointer < 0 )
|
|
{
|
|
#ifdef S4WINDOWS
|
|
#ifdef __DLL__
|
|
handle = GlobalAlloc( GMEM_MOVEABLE | GMEM_DDESHARE | GMEM_ZEROINIT, (DWORD) sizeof(char *) * 100 + sizeof(HANDLE) ) ;
|
|
#else
|
|
handle = GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, (DWORD) sizeof(char *) * 100 + sizeof(HANDLE) ) ;
|
|
#endif
|
|
|
|
if ( handle == (HANDLE) 0 )
|
|
e4severe( e4memory, E4_MEMORY_YPU ) ;
|
|
|
|
h_ptr = (HANDLE *)GlobalLock( handle ) ;
|
|
*h_ptr++ = handle ;
|
|
mem4test_pointers = (char **)h_ptr ;
|
|
#else
|
|
mem4test_pointers = (char **)malloc( sizeof(char *) * 100 ) ;
|
|
#endif
|
|
mem4num_pointer = 100 ;
|
|
}
|
|
if ( mem4num_pointer == mem4num_used )
|
|
{
|
|
mem4num_pointer += 100 ;
|
|
if ( mem4num_pointer > 10000 )
|
|
e4severe( e4result, E4_MEMORY_YPU ) ;
|
|
|
|
#ifdef S4WINDOWS
|
|
old_h_ptr = (HANDLE *)(mem4test_pointers) ;
|
|
old_h_ptr-- ; /* get the actual handle */
|
|
|
|
#ifdef __DLL__
|
|
handle = GlobalReAlloc( *old_h_ptr, (DWORD)sizeof(char *) * mem4num_pointer + sizeof( HANDLE ), GMEM_MOVEABLE ) ;
|
|
#else
|
|
handle = GlobalReAlloc( *old_h_ptr, (DWORD)sizeof(char *) * mem4num_pointer + sizeof( HANDLE ), GMEM_MOVEABLE ) ;
|
|
#endif
|
|
|
|
if ( handle == (HANDLE) 0 )
|
|
e4severe( e4memory, E4_MEMORY_YPU ) ;
|
|
|
|
h_ptr = (HANDLE *)GlobalLock( handle ) ;
|
|
*h_ptr++ = handle ;
|
|
mem4test_pointers = (char **)h_ptr ;
|
|
#else
|
|
mem4test_pointers = (char **)realloc( (void *)mem4test_pointers, sizeof(char *)*mem4num_pointer ) ;
|
|
#endif
|
|
}
|
|
|
|
if ( mem4test_pointers == 0 )
|
|
e4severe( e4memory, E4_MEMORY_YPU ) ;
|
|
|
|
mem4test_pointers[mem4num_used++] = ptr ;
|
|
}
|
|
|
|
static void mem4pop_pointer( char *ptr )
|
|
{
|
|
int i ;
|
|
|
|
for ( i = mem4num_used - 1 ; i >= 0 ; i-- )
|
|
if ( mem4test_pointers[i] == ptr )
|
|
{
|
|
/* This 'memmove' may create compile warning */
|
|
memmove( mem4test_pointers+i, mem4test_pointers+i+1, (size_t) (sizeof(char *) * (mem4num_used-i-1))) ;
|
|
mem4num_used-- ;
|
|
return ;
|
|
}
|
|
e4severe( e4result, E4_MEMORY_YPO ) ;
|
|
}
|
|
|
|
void S4FUNCTION mem4check_memory()
|
|
{
|
|
int i ;
|
|
|
|
for ( i = 0; i < mem4num_used; i++ )
|
|
mem4check_pointer( mem4test_pointers[i], 0 ) ;
|
|
}
|
|
|
|
int S4FUNCTION mem4free_check( int max_left )
|
|
{
|
|
#ifdef S4MEM_PRINT
|
|
int i ;
|
|
if ( v4print )
|
|
for ( i = 0; i < mem4num_used; i++ )
|
|
fprintf( stdprn, "\r\nmem4free_check: %p", mem4test_pointers[i] ) ;
|
|
else
|
|
for ( i = 0; i < mem4num_used; i++ )
|
|
printf( "\r\nmem4free_check: %p", mem4test_pointers[i] ) ;
|
|
#endif
|
|
|
|
if ( mem4num_used > max_left )
|
|
e4severe( e4result, E4_RESULT_FRE ) ;
|
|
|
|
return ( mem4num_used ) ;
|
|
}
|
|
#endif
|
|
|
|
|
|
void *S4FUNCTION mem4alloc( MEM4 *memory_type )
|
|
{
|
|
#ifdef S4DEBUG
|
|
if ( memory_type == 0 )
|
|
e4severe( e4parm, E4_MEM4ALLOC ) ;
|
|
#endif
|
|
|
|
return mem4alloc2( memory_type, 0 ) ;
|
|
}
|
|
|
|
Y4CHUNK *S4FUNCTION mem4alloc_chunk( MEM4 *type_ptr )
|
|
{
|
|
Y4CHUNK *chunk_ptr ;
|
|
int n_allocate, i ;
|
|
char *ptr ;
|
|
|
|
n_allocate = type_ptr->unit_expand ;
|
|
if ( l4last( &type_ptr->chunks ) == 0 )
|
|
n_allocate = type_ptr->unit_start ;
|
|
|
|
chunk_ptr = (Y4CHUNK *)u4alloc_free( type_ptr->code_base, sizeof( LINK4 ) + (long)n_allocate*type_ptr->unit_size ) ;
|
|
if ( chunk_ptr == 0 )
|
|
return 0 ;
|
|
ptr = (char *)&chunk_ptr->data ;
|
|
for ( i = 0 ; i < n_allocate ; i++ )
|
|
l4add( &type_ptr->pieces, (LINK4 *)( ptr + i * type_ptr->unit_size ) ) ;
|
|
|
|
return chunk_ptr ;
|
|
}
|
|
|
|
static void *mem4alloc_low( MEM4 *memory_type )
|
|
{
|
|
LINK4 *next_piece ;
|
|
Y4CHUNK *new_chunk ;
|
|
#ifdef S4DEBUG
|
|
char *ptr ;
|
|
#endif
|
|
#ifdef S4OS2SEM
|
|
#ifdef S4OS2
|
|
#ifdef __DLL__
|
|
ULONG flags ;
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
if ( memory_type == 0 )
|
|
return 0 ;
|
|
next_piece = (LINK4 *)l4pop( &memory_type->pieces ) ;
|
|
|
|
if ( next_piece != 0 )
|
|
{
|
|
#ifdef S4OS2
|
|
#ifdef S4OS2SEM
|
|
#ifdef __DLL__
|
|
/* get access to the memory */
|
|
flags = PAG_WRITE | PAG_READ ;
|
|
if ( DosGetSharedMem( next_piece, flags ) != 0 )
|
|
return 0 ;
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#ifdef S4DEBUG
|
|
memory_type->n_used++ ;
|
|
ptr = mem4fix_pointer( (char *)next_piece, memory_type->unit_size ) ;
|
|
|
|
#ifdef S4MEM_PRINT
|
|
if ( v4print )
|
|
fprintf( stdprn, "\r\n Y4ALLOC: %p", ptr );
|
|
else
|
|
printf( "\r\n Y4ALLOC: %p", ptr);
|
|
#endif
|
|
|
|
mem4push_pointer( ptr ) ;
|
|
return (void *)ptr ;
|
|
#else
|
|
return next_piece ;
|
|
#endif
|
|
}
|
|
|
|
if ( (new_chunk = mem4alloc_chunk( memory_type )) == 0 )
|
|
return 0 ;
|
|
l4add( &memory_type->chunks, &new_chunk->link ) ;
|
|
|
|
memory_type->n_used++ ;
|
|
#ifdef S4DEBUG
|
|
ptr = mem4fix_pointer( (char *)l4pop(&memory_type->pieces),
|
|
memory_type->unit_size ) ;
|
|
#ifdef S4MEM_PRINT
|
|
if ( v4print )
|
|
fprintf(stdprn, "\r\n Y4ALLOC: %p", ptr);
|
|
else
|
|
printf( "\r\n Y4ALLOC: %p", ptr);
|
|
#endif
|
|
|
|
mem4push_pointer( ptr ) ;
|
|
return (void *)ptr ;
|
|
#else
|
|
return l4pop( &memory_type->pieces ) ;
|
|
#endif
|
|
}
|
|
|
|
void *S4FUNCTION mem4alloc2( MEM4 *memory_type, CODE4 *c4 )
|
|
{
|
|
void *ptr ;
|
|
|
|
if ( c4 )
|
|
if ( c4->error_code < 0 )
|
|
return 0 ;
|
|
|
|
#ifdef S4OS2SEM
|
|
#ifdef S4OS2
|
|
if ( mem4start( memory_type->code_base ) != 0 )
|
|
return 0 ;
|
|
#endif
|
|
#endif
|
|
|
|
ptr = mem4alloc_low( memory_type ) ;
|
|
|
|
#ifdef S4OS2SEM
|
|
#ifdef S4OS2
|
|
mem4stop( memory_type->code_base ) ;
|
|
#endif
|
|
#endif
|
|
|
|
if ( ptr == 0 )
|
|
{
|
|
if ( c4 )
|
|
e4set( c4, e4memory ) ;
|
|
return 0 ;
|
|
}
|
|
#ifdef S4DEBUG
|
|
memset( ptr, 0, memory_type->unit_size - mem4extra_tot ) ;
|
|
#else
|
|
memset( ptr, 0, memory_type->unit_size ) ;
|
|
#endif
|
|
return ptr ;
|
|
}
|
|
|
|
MEM4 *S4FUNCTION mem4create( CODE4 *c4, int start, unsigned unit_size, int expand, int is_temp )
|
|
{
|
|
MEM4 *on_type ;
|
|
#ifdef S4OS2SEM
|
|
#ifdef S4OS2
|
|
#ifdef __DLL__
|
|
ULONG flags ;
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef S4DEBUG
|
|
if ( start < 0 || expand < 0 )
|
|
e4severe( e4parm, E4_MEM4CREATE ) ;
|
|
unit_size += 2 * mem4extra_chars + sizeof( unsigned ) ;
|
|
#ifdef S4OS2
|
|
if ( c4 == 0 )
|
|
e4severe( e4info, "OS/2 mem4create() requires valid CodeBase pointer" ) ;
|
|
#endif
|
|
#endif
|
|
|
|
if ( c4 )
|
|
if ( c4->error_code < 0 )
|
|
return 0 ;
|
|
|
|
#ifdef S4OS2SEM
|
|
#ifdef S4OS2
|
|
if ( mem4start( c4 ) != 0 )
|
|
return 0 ;
|
|
#endif
|
|
#endif
|
|
|
|
if ( !is_temp )
|
|
for( on_type = 0 ; ; )
|
|
{
|
|
on_type = (MEM4 *)l4next( &used, on_type ) ;
|
|
if ( on_type == 0 )
|
|
break ;
|
|
|
|
#ifdef S4OS2
|
|
#ifdef S4OS2SEM
|
|
#ifdef __DLL__
|
|
/* get access to the memory */
|
|
flags = PAG_WRITE | PAG_READ ;
|
|
if ( DosGetSharedMem( on_type, flags ) != 0 )
|
|
return 0 ;
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
if ( on_type->unit_size == unit_size && on_type->n_repeat > 0 )
|
|
{
|
|
/* Match */
|
|
if ( start > on_type->unit_start )
|
|
on_type->unit_start = start ;
|
|
if ( expand > on_type->unit_expand)
|
|
on_type->unit_expand = expand ;
|
|
on_type->n_repeat++ ;
|
|
#ifdef S4OS2
|
|
#ifdef S4OS2SEM
|
|
mem4stop( c4 ) ;
|
|
#endif
|
|
#endif
|
|
return on_type ;
|
|
}
|
|
}
|
|
|
|
/* Allocate memory for another MEM4 */
|
|
|
|
on_type = (MEM4 *)l4last( &avail ) ;
|
|
if ( on_type == 0 )
|
|
{
|
|
MEMORY4GROUP *group ;
|
|
int i ;
|
|
|
|
group = (MEMORY4GROUP *)u4alloc_free( c4, sizeof( MEMORY4GROUP ) ) ;
|
|
if ( group == 0 )
|
|
{
|
|
if ( c4 )
|
|
e4set( c4, e4memory ) ;
|
|
#ifdef S4OS2SEM
|
|
#ifdef S4OS2
|
|
mem4stop( c4 ) ;
|
|
#endif
|
|
#endif
|
|
return 0 ;
|
|
}
|
|
|
|
for ( i = 0 ; i < mem4num_types ; i++ )
|
|
l4add( &avail, group->types + i ) ;
|
|
on_type = (MEM4 *)l4last( &avail ) ;
|
|
l4add( &groups, group ) ;
|
|
}
|
|
|
|
l4remove( &avail, on_type ) ;
|
|
memset( (void *)on_type, 0, sizeof( MEM4 ) ) ;
|
|
l4add( &used, on_type ) ;
|
|
|
|
#ifdef S4OS2SEM
|
|
#ifdef S4OS2
|
|
mem4stop( c4 ) ;
|
|
#endif
|
|
#endif
|
|
|
|
on_type->unit_start = start ;
|
|
on_type->unit_size = unit_size ;
|
|
on_type->unit_expand= expand ;
|
|
on_type->n_repeat = 1 ;
|
|
on_type->n_used = 0 ;
|
|
if ( is_temp )
|
|
on_type->n_repeat = -1 ;
|
|
|
|
#ifdef S4MEM_PRINT
|
|
if ( v4print )
|
|
fprintf( stdprn, "\r\n MEM4: %p", on_type ) ;
|
|
else
|
|
printf( "\r\n MEM4: %p", on_type ) ;
|
|
#endif
|
|
|
|
on_type->code_base = c4 ;
|
|
return on_type ;
|
|
}
|
|
|
|
void *S4FUNCTION mem4create_alloc( CODE4 *c4, MEM4 **type_ptr_ptr, int start, unsigned unit_size, int expand, int is_temp)
|
|
{
|
|
if ( *type_ptr_ptr == 0 )
|
|
{
|
|
*type_ptr_ptr = mem4create( c4, start, unit_size, expand, is_temp ) ;
|
|
if ( *type_ptr_ptr == 0 )
|
|
return 0 ;
|
|
}
|
|
|
|
return mem4alloc2( *type_ptr_ptr, c4 ) ;
|
|
}
|
|
|
|
void S4FUNCTION mem4free( MEM4 *memory_type, void *free_ptr )
|
|
{
|
|
if ( memory_type == 0 || free_ptr == 0 )
|
|
return ;
|
|
|
|
memory_type->n_used-- ;
|
|
#ifdef S4DEBUG
|
|
if ( memory_type->n_used < 0 )
|
|
e4severe( e4result, E4_MEM4FREE ) ;
|
|
|
|
#ifdef S4MEM_PRINT
|
|
if ( v4print )
|
|
fprintf(stdprn, "\r\n Y4FREE: %p", free_ptr ) ;
|
|
else
|
|
printf( "\r\n Y4FREE: %p", free_ptr ) ;
|
|
#endif
|
|
|
|
mem4pop_pointer( (char *)free_ptr ) ;
|
|
l4add( &memory_type->pieces, (LINK4 *)mem4check_pointer( (char *)free_ptr, 0 ) ) ;
|
|
/* memset( (void *)&free_ptr, 0, sizeof(free_ptr) ) ; */
|
|
#else
|
|
l4add( &memory_type->pieces, (LINK4 *)free_ptr ) ;
|
|
#endif
|
|
}
|
|
|
|
void S4FUNCTION mem4release( MEM4 *memory_type )
|
|
{
|
|
void *ptr ;
|
|
|
|
if ( memory_type == 0 )
|
|
return ;
|
|
|
|
memory_type->n_repeat-- ;
|
|
if ( memory_type->n_repeat <= 0 )
|
|
{
|
|
for(;;)
|
|
{
|
|
ptr = l4pop( &memory_type->chunks) ;
|
|
if ( ptr == 0 )
|
|
break ;
|
|
u4free( ptr ) ;
|
|
}
|
|
|
|
l4remove( &used, memory_type ) ;
|
|
l4add( &avail, memory_type ) ;
|
|
|
|
#ifdef S4MEM_PRINT
|
|
if ( v4print )
|
|
fprintf( stdprn, "\r\n Y4RELEASE: %p", memory_type ) ;
|
|
else
|
|
printf( "\r\n Y4RELEASE: %p", memory_type ) ;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
#ifdef S4OLD_CODE
|
|
MEM4 *S4FUNCTION mem4type( int start, unsigned unit_size, int expand, int is_temp)
|
|
{
|
|
return mem4create( 0, start, unit_size, expand, is_temp ) ;
|
|
}
|
|
#endif
|
|
|
|
#ifdef S4MAX
|
|
long mem4max_memory = 0x4000 ;
|
|
long mem4allocated = 0L ;
|
|
#ifndef S4DEBUG
|
|
S4DEBUG should be set with S4MAX (force compile error.)
|
|
#endif
|
|
#endif
|
|
|
|
void *S4FUNCTION u4alloc( long n )
|
|
{
|
|
size_t s ;
|
|
char *ptr ;
|
|
#ifdef S4OS2SEM
|
|
#ifdef __DLL__
|
|
#ifdef S4OS2
|
|
ULONG flags;
|
|
APIRET rc;
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef S4DEBUG
|
|
if ( n == 0L )
|
|
e4severe( e4parm, E4_PARM_ZER ) ;
|
|
n += mem4extra_chars*2 + sizeof(unsigned) ;
|
|
#endif
|
|
|
|
#ifdef S4MAX
|
|
/* Assumes 'mem4max_memory' is less than the actual maximum */
|
|
if ( mem4allocated + n > mem4max_memory )
|
|
return 0 ;
|
|
mem4allocated += n ;
|
|
#endif
|
|
|
|
s = (size_t) n ;
|
|
if ( n > (long) s )
|
|
return 0 ;
|
|
|
|
#ifdef S4WINDOWS
|
|
{
|
|
HANDLE handle, *h_ptr ;
|
|
h_ptr = (HANDLE *)0 ;
|
|
|
|
#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 ;
|
|
|
|
h_ptr = (HANDLE *)GlobalLock( handle ) ;
|
|
*h_ptr++ = handle ;
|
|
ptr = (char *)h_ptr ;
|
|
}
|
|
#else
|
|
#ifdef __DLL__
|
|
#ifdef S4OS2SEM
|
|
#ifndef S4OS2
|
|
error invalid switch configuration
|
|
#endif
|
|
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
|
|
#ifndef S4DEBUG
|
|
memset( ptr, 0, s ) ;
|
|
#endif
|
|
#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
|
|
#ifndef S4DEBUG
|
|
memset( ptr, 0, s ) ;
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef S4DEBUG
|
|
ptr = mem4fix_pointer( ptr, s ) ;
|
|
mem4push_pointer( ptr ) ;
|
|
memset( ptr, 0, s-mem4extra_chars*2 - sizeof(unsigned) ) ;
|
|
#endif
|
|
|
|
#ifdef S4MEM_PRINT
|
|
if ( v4print )
|
|
fprintf( stdprn, "\r\nU4ALLOC: %p # bytes alloc: %ld", ptr, n );
|
|
else
|
|
printf("\r\nU4ALLOC: %p # bytes alloc: %ld", ptr, n);
|
|
#endif
|
|
|
|
return (void *)ptr ;
|
|
}
|
|
|
|
void *S4FUNCTION u4alloc_er( CODE4 S4PTR *c4, long n )
|
|
{
|
|
void *ptr = u4alloc_free( c4, n ) ;
|
|
if ( ptr == 0 && c4 )
|
|
e4( c4, e4memory, 0 ) ;
|
|
|
|
return ptr ;
|
|
}
|
|
|
|
void S4FUNCTION u4free( void *ptr )
|
|
{
|
|
#ifdef S4WINDOWS
|
|
HANDLE hand ;
|
|
#endif
|
|
|
|
#ifdef S4MAX
|
|
unsigned *amount ;
|
|
#endif
|
|
|
|
if ( ptr == 0 )
|
|
return ;
|
|
|
|
#ifdef S4MAX
|
|
amount = (unsigned *)ptr ;
|
|
mem4allocated -= amount[-1] ;
|
|
#endif
|
|
|
|
#ifdef S4WINDOWS
|
|
#ifdef S4DEBUG
|
|
mem4pop_pointer( (char *)ptr ) ;
|
|
hand = ((HANDLE *)mem4check_pointer( (char *)ptr, 1 ))[-1] ;
|
|
#else
|
|
hand = ((HANDLE *)ptr)[-1] ;
|
|
#endif
|
|
|
|
GlobalUnlock( hand ) ;
|
|
hand = GlobalFree( hand ) ;
|
|
|
|
if ( hand != (HANDLE) 0 )
|
|
e4severe( e4memory, E4_MEMORY_ERR ) ;
|
|
#else
|
|
#ifdef S4DEBUG
|
|
mem4pop_pointer( (char *)ptr ) ;
|
|
|
|
#ifdef S4MEM_PRINT
|
|
if ( v4print )
|
|
fprintf( stdprn, "\r\nU4FREE: %p", ptr ) ;
|
|
else
|
|
printf( "\r\nU4FREE: %p", ptr );
|
|
#endif
|
|
|
|
free(mem4check_pointer( (char *)ptr, 1 ) ) ;
|
|
#else
|
|
#ifdef S4MEM_PRINT
|
|
if ( v4print )
|
|
fprintf( stdprn, "\r\nU4FREE: %p", ptr ) ;
|
|
else
|
|
printf( "\r\nU4FREE: %p", ptr );
|
|
#endif
|
|
|
|
free( ptr ) ;
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
void S4FUNCTION mem4reset()
|
|
{
|
|
MEM4 *on_type ;
|
|
LINK4 *on_chunk, *on_group ;
|
|
#ifdef S4WINDOWS
|
|
HANDLE hand ;
|
|
#endif
|
|
#ifdef S4LOCK_CHECK
|
|
e4severe( e4result, E4_RESULT_S4L ) ;
|
|
#endif
|
|
|
|
for( on_type = 0 ;; )
|
|
{
|
|
on_type = (MEM4 *)l4next(&used,on_type) ;
|
|
if ( on_type == 0 )
|
|
break ;
|
|
do
|
|
{
|
|
on_chunk = (LINK4 *)l4pop( &on_type->chunks) ;
|
|
u4free( on_chunk ) ; /* free of 0 still succeeds */
|
|
} while ( on_chunk ) ;
|
|
}
|
|
|
|
for( ;; )
|
|
{
|
|
on_group = (LINK4 *)l4pop( &groups ) ;
|
|
if ( on_group == 0 )
|
|
break ;
|
|
u4free( on_group ) ;
|
|
}
|
|
|
|
#ifdef S4DEBUG
|
|
if ( mem4num_pointer > 0 )
|
|
{
|
|
#ifdef S4WINDOWS
|
|
hand = ((HANDLE *)mem4test_pointers)[-1] ;
|
|
|
|
GlobalUnlock( hand ) ;
|
|
hand = GlobalFree( hand ) ;
|
|
|
|
if ( hand != (HANDLE)0 )
|
|
e4severe( e4memory, E4_MEMORY_ERR ) ;
|
|
#else
|
|
#ifdef S4MEM_PRINT
|
|
if ( v4print )
|
|
fprintf( stdprn, "\r\nMEM4RESET: %p", mem4test_pointers ) ;
|
|
else
|
|
printf( "\r\nMEM4RESET: %p", mem4test_pointers );
|
|
#endif
|
|
|
|
free( (void *)mem4test_pointers ) ;
|
|
#endif
|
|
|
|
mem4test_pointers = 0 ;
|
|
mem4num_pointer = -1 ;
|
|
mem4num_used = 0 ;
|
|
}
|
|
#endif
|
|
|
|
mem4init() ;
|
|
}
|
|
|
|
void S4FUNCTION mem4init()
|
|
{
|
|
memset( (void *)&avail, 0, sizeof( avail ) ) ;
|
|
memset( (void *)&used, 0, sizeof( used ) ) ;
|
|
memset( (void *)&groups, 0, sizeof( groups ) ) ;
|
|
}
|