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 ) ) ;
 | |
| }
 |