home *** CD-ROM | disk | FTP | other *** search
-
- /* h4.c Memory Handler
- (c)Copyright Sequiter Software Inc., 1987-1990. All rights reserved.
- */
-
- #include "d4all.h"
- #include "h4memory.h"
- #include "u4error.h"
- #include "p4misc.h"
-
- #ifdef WINDOWS_L
- #define WINDOWS
- #endif
-
- #ifdef WINDOWS_G
- #define WINDOWS
- #endif
-
- #ifdef WINDOWS
- #include "windows.h"
- #endif
-
- #ifdef NO_ALLOC
- #include <dos.h>
- #endif
-
- #include <stdlib.h>
- #include <string.h>
-
- int h4add( char **ptr_ptr, int mem_ref, int add_ref, int add_before )
- {
- MEMORY *memory ;
- UNIT *mem_ptr, *add_ptr, *next_ptr ;
-
- if ( add_ref == mem_ref || add_ref < 0 ) return add_ref;
-
- if ( add_before && mem_ref >= 0 )
- {
- h4add( ptr_ptr, mem_ref, add_ref, 0 ) ;
- h4remove( ptr_ptr, mem_ref ) ;
- h4add( ptr_ptr, add_ref, mem_ref, 0 ) ;
-
- return add_ref ;
- }
-
- memory = (MEMORY *) (*ptr_ptr -sizeof(MEMORY)) ;
-
- add_ptr = (UNIT *) (*ptr_ptr + memory->len_unit* add_ref) ;
- add_ptr->prev = mem_ref ;
- if ( mem_ref < 0 )
- {
- add_ptr->next = -1 ;
- return add_ref ;
- }
-
- mem_ptr = (UNIT *) (*ptr_ptr + memory->len_unit* mem_ref) ;
- next_ptr = (UNIT *) (*ptr_ptr + memory->len_unit* mem_ptr->next) ;
-
- add_ptr->next = mem_ptr->next ;
- mem_ptr->next = add_ref ;
-
- if ( add_ptr->next < 0 ) return add_ref ;
- next_ptr->prev = add_ref ;
-
- return add_ref ;
- }
-
-
- int h4remove( char **ptr_ptr, int mem_ref )
- {
- MEMORY *memory ;
- UNIT *mem_ptr, *previous_ptr, *next_ptr ;
- int return_unit ;
-
- if ( mem_ref < 0 ) return -1 ;
- memory = (MEMORY *) (*ptr_ptr -sizeof(MEMORY)) ;
-
- mem_ptr = (UNIT *) (*ptr_ptr + memory->len_unit* mem_ref) ;
- if ( mem_ptr->next >= 0 )
- {
- return_unit = mem_ptr->next ;
- next_ptr = (UNIT *) (*ptr_ptr + memory->len_unit* mem_ptr->next) ;
- next_ptr->prev = mem_ptr->prev ;
- }
- else
- return_unit = -1 ;
-
- if ( mem_ptr->prev >= 0 )
- {
- return_unit = mem_ptr->prev ;
- previous_ptr = (UNIT *) (*ptr_ptr + memory->len_unit*mem_ptr->prev);
- previous_ptr->next = mem_ptr->next ;
- }
- mem_ptr->prev = -1 ;
- mem_ptr->next = -1 ;
-
- return( return_unit ) ;
- }
-
-
- /* h4alloc.c
-
- Memory allocation routine.
- Calls u4error if there is not enough memory.
- Zeros the memory with NULL's
- */
-
- #ifdef H4TEST
- void * h4malloc_test(unsigned int) ;
- #endif
-
- char * h4alloc( int num )
- {
- char * ptr ;
-
- #ifdef WINDOWS
- ptr = (char *) h4alloc_try(num) ;
- #else
- #ifdef H4TEST
- ptr = (char *) h4malloc_test((unsigned) num) ;
- #else
- ptr = (char *) h4alloc_try( num ) ;
- #endif
- #endif
-
- if (ptr== ((char *)0) )
- {
- u4error( E_MEMORY, (char *) 0) ;
- return( (char *) 0 ) ;
- }
- else
- memset(ptr, 0, (size_t) num) ;
-
- return( ptr) ;
- }
-
- char * h4alloc_try( int num )
- {
- #ifdef WINDOWS
- HANDLE handle, *handle_ptr ;
-
- handle_ptr = (HANDLE *) 0 ;
-
- #ifdef WINDOWS_G
- handle = GlobalAlloc( GMEM_FIXED, (DWORD) num+ sizeof(HANDLE) ) ;
- if ( handle != (HANDLE) 0 )
- {
- handle_ptr = (HANDLE *) GlobalLock( handle ) ;
- *handle_ptr++ = handle ;
- }
- #else
- handle = LocalAlloc( LMEM_FIXED, (WORD) num+ sizeof(HANDLE) ) ;
- if ( handle != (HANDLE) 0 )
- {
- handle_ptr = (HANDLE *) LocalLock( handle ) ;
- *handle_ptr++ = handle ;
- }
- #endif
-
- return( (char *) handle_ptr ) ;
- #else
- #ifdef H4TEST
- #ifdef NO_ALLOC
- Forced Compile Error: H4TEST Cannot be used with NO_ALLOC
- #else
- return( h4malloc_test((unsigned) num) ) ;
- #endif
- #else
- #ifdef NO_ALLOC
- unsigned int num_par ;
- static union memory_ptr_st
- {
- char *far_ptr ;
- struct ptr_st { unsigned int off ; unsigned int seg ; } p ;
- } memory_ptr ;
-
- if ( sizeof(char *) != sizeof(char far *) )
- {
- u4error( 0, "Large Memory Model Only",(char *) 0 ) ;
- exit(1) ;
- }
-
- memory_ptr.far_ptr = 0 ;
- num_par = ( ((unsigned int) num) -1)/16 + 1 ;
-
- _AH = 0x48 ;
- _BX = num_par ;
- geninterrupt(0x21) ;
- if ( _FLAGS & 1 ) return( 0 ) ;
-
- memory_ptr.p.seg = _AX ;
- return( memory_ptr.far_ptr ) ;
- #else
- return( (char *) malloc((size_t) num) ) ;
- #endif
- #endif
- #endif
- }
-
- void h4free_memory( void *ptr )
- {
- #ifdef WINDOWS
- #ifdef WINDOWS_G
- HANDLE hand ;
-
- hand = ((HANDLE *) ptr)[-1] ;
-
- /* rc = GlobalUnlock( hand ) ;
- if ( rc ) u4error( E_INTERNAL, "h4free_memory", (char *) 0 ) ;
- */
-
- hand = GlobalFree( hand ) ;
- if ( hand != (HANDLE) 0 )
- u4error( E_INTERNAL, "h4free_memory", (char *) 0 ) ;
- #else
- HANDLE hand ;
-
- hand = ((HANDLE *) ptr)[-1] ;
-
- /* rc = LocalUnlock( hand ) ;
- if ( ! rc ) u4error( E_INTERNAL, "h4free_memory", (char *) 0 ) ;
- */
-
- hand = LocalFree( hand ) ;
- if ( hand != (HANDLE) 0 )
- u4error( E_INTERNAL, "h4free_memory", (char *) 0 ) ;
- #endif
- #else
- #ifdef H4TEST
- #ifdef NO_ALLOC
- Forced Compile Error: H4TEST Cannot be used with NO_ALLOC
- #else
- h4free_test(ptr) ;
- #endif
- #else
- #ifdef NO_ALLOC
- unsigned int save_es ;
-
- save_es = _ES ;
- _AH = 0x49 ;
- _ES = FP_SEG(ptr) ;
- geninterrupt( 0x21 ) ;
- _ES = save_es ;
-
- if ( _FLAGS & 1 )
- u4error( E_INTERNAL, "Freeing Memory", (char *) 0 ) ;
- #else
- free(ptr) ;
- #endif
- #endif
- #endif
- }
-
-
- /* h4get.c
-
- Allocates a block of memory from the predefined memory array.
- Adds it to the end of the linked list.
- */
-
- int h4get( char **ptr_ptr, int previous_ref)
- {
- char *new_ptr ;
- int i, unit_ref ;
- long new_size ;
- MEMORY *memory ;
- UNIT *unit_ptr, *previous_ptr, *next_ptr ;
-
- memory= (MEMORY *) (*ptr_ptr -sizeof(MEMORY)) ;
-
- if (memory->first_free >= memory->num_unit)
- {
- /* Must allocate some additional memory for the new unit */
-
- new_size = (unsigned int) memory->len_unit*
- ((unsigned long)memory->num_unit+memory->add_unit)+sizeof(MEMORY);
- if ( new_size > 0xFFE0L )
- {
- u4error( E_ALLOCATE, "h4create()", (char *) 0 ) ;
- return -1 ;
- }
- new_ptr = h4alloc((unsigned int) new_size) ;
- if ( new_ptr == (char *) 0 ) return -1 ;
-
- memcpy( new_ptr, (char *) memory, (size_t)
- (memory->len_unit*(unsigned long) memory->num_unit)+ sizeof(MEMORY)) ;
- h4free_memory((char *) memory) ;
-
- /* update memory and *ptr_ptr to the new memory block */
- memory = (MEMORYPTR) new_ptr ;
- new_ptr += sizeof(MEMORY) ;
- *ptr_ptr = new_ptr ;
-
- /* Create some pointers to keep track of the newly memory units */
- unit_ptr = (UNIT *) (*ptr_ptr + memory->len_unit* memory->num_unit) ;
-
- for (i= memory->num_unit+1; i<= memory->num_unit+ memory->add_unit; i++)
- {
- unit_ptr->next = i ;
- unit_ptr = (UNIT *) ((char *)unit_ptr + memory->len_unit) ;
- }
-
- /* There is new number of memory units in the memory block */
- memory->num_unit += memory->add_unit ;
- }
-
- /* Unallocate from the chain of unallocated units */
- unit_ptr = (UNIT *) (*ptr_ptr + memory->len_unit* memory->first_free) ;
- unit_ref = memory->first_free ;
- memory->first_free = unit_ptr->next ;
-
- /* Add to the new double linked list */
- if (previous_ref >= 0)
- {
- unit_ptr->prev = previous_ref ;
- previous_ptr = (UNIT *) (*ptr_ptr + memory->len_unit* previous_ref) ;
- unit_ptr->next = previous_ptr->next ;
- previous_ptr->next = unit_ref ;
-
- if ( unit_ptr->next >= 0 )
- {
- next_ptr = (UNIT *) (*ptr_ptr + memory->len_unit* previous_ptr->next) ;
- next_ptr->prev = unit_ref ;
- }
- }
- else
- {
- unit_ptr->next = -1 ;
- unit_ptr->prev = -1 ;
- }
- memset( (char *)unit_ptr+sizeof(UNIT), 0, (size_t) memory->len_unit-sizeof(UNIT) ) ;
-
- return( unit_ref ) ;
- }
-
- /* h4create.c */
-
- int h4create( char **ptr_ptr, int num, int len, int add )
- {
- int i ;
- unsigned long total ;
- MEMORYPTR mem_stru ;
- union
- {
- int *int_ptr ;
- char *char_ptr ;
- } ptr ;
-
- if (len<= 0) len = 1 ;
- if (num<= 0) num = 1 ;
- if (add<=0) add = 1 ;
-
- total = (unsigned long) len * num + sizeof(MEMORY) ;
- if (total > 0xFFE0L )
- u4error( E_ALLOCATE, "h4create()", (char *) 0 ) ;
- ptr.char_ptr = h4alloc( (unsigned int) total ) ;
- if ( ptr.char_ptr == (char *) 0 ) return -1 ;
-
- mem_stru = (MEMORYPTR) ptr.char_ptr ;
- ptr.char_ptr += sizeof(MEMORY) ;
- *ptr_ptr = ptr.char_ptr ;
-
- mem_stru->first_free= 0 ;
- mem_stru->len_unit = len ;
- mem_stru->num_unit = num ;
- mem_stru->add_unit = add ;
-
- for (i=1; i<=num; i++)
- {
- *ptr.int_ptr = i ;
- ptr.char_ptr += len ;
- }
-
- return 0 ;
- }
-
- /*
- h4free.c
-
- Frees a memory unit.
- Maintains the double linked list.
-
- Returns
- Returns the a reference to the previous memory unit.
- If the previous memory unit does not exist, return a reference
- to the next memory unit. If a next memory unit does not exist,
- return -1.
-
- On error return -2.
- */
-
- h4free( char **ptr_ptr, int unit_ref )
- {
- MEMORY *memory ;
- UNIT *unit_ptr, *next_ptr, *previous_ptr ;
- int return_unit ;
-
- memory = (MEMORY *) ( *ptr_ptr - sizeof(MEMORY) ) ;
- if (unit_ref>= memory->num_unit || unit_ref<0)
- {
- u4error( E_INTERNAL, "H4FREE", (char *) 0) ;
- return(-2) ;
- }
-
- unit_ptr = (UNIT *) (*ptr_ptr + memory->len_unit* unit_ref) ;
-
- /* Maintain the double linked list */
- if ( unit_ptr->next >= 0)
- {
- next_ptr = (UNIT *) (*ptr_ptr + memory->len_unit* unit_ptr->next) ;
- next_ptr->prev= unit_ptr->prev ;
- }
- if ( unit_ptr->prev >= 0)
- {
- previous_ptr = (UNIT *) (*ptr_ptr + memory->len_unit* unit_ptr->prev);
- previous_ptr->next= unit_ptr->next ;
-
- return_unit = unit_ptr->prev ;
- }
- else
- return_unit = unit_ptr->next ;
-
-
- /* Fix up the pointer to the released memory */
-
- unit_ptr->next = memory->first_free ;
- memory->first_free = unit_ref ;
-
- return( return_unit ) ;
- }
-
-
- void h4free_chain( char **ptr_ref_ptr, int mem_ref )
- {
- while ( mem_ref >= 0 )
- mem_ref = h4free( ptr_ref_ptr, mem_ref ) ;
- }
-
-
- #ifdef H4TEST
- /* This test code ensures that only allocated pointers are freed.
- In addition, it is possible to check that all pointers have
- been freed. This is a useful test for Code Base after it
- has been uninitialized by calling 'd4init_undo', ...
- */
-
- static void **h4test_pointers ;
- static int h4num_pointer = -1 ;
- static int h4num_used = 0 ;
-
- void * h4malloc_test( unsigned int num_bytes )
- {
- void *ptr ;
-
- if ( h4num_pointer < 0 )
- {
- h4test_pointers = (void **) malloc( sizeof(void *) * 100 ) ;
- h4num_pointer = 100 ;
- }
- if ( h4num_pointer == h4num_used )
- {
- h4num_pointer += 100 ;
- if ( h4num_pointer > 10000 )
- u4error( E_INTERNAL, "h4malloc_test()", "Too many pointers", (char *) 0 ) ;
-
- h4test_pointers = (void **) realloc( h4test_pointers, sizeof(void *) *h4num_pointer ) ;
- }
-
- if ( h4test_pointers == (void **) 0 )
- u4error( E_INTERNAL, "h4malloc_test()", "Out of Memory", (char *) 0 ) ;
-
- ptr = malloc( num_bytes ) ;
- if ( ptr != (void *) 0 )
- h4test_pointers[h4num_used++] = ptr ;
-
- return( ptr ) ;
- }
-
- void h4free_test( void *ptr )
- {
- int i ;
-
- for ( i=h4num_used-1; i>=0; i-- )
- if ( h4test_pointers[i] == ptr )
- {
- free( ptr ) ;
- /* This 'memmove' may create compile warning */
- memmove( h4test_pointers+i, h4test_pointers+i+1, (size_t) (sizeof(void *) * h4num_used-i-1)) ;
- h4num_used-- ;
- return ;
- }
-
- u4error( E_INTERNAL, "h4free_test()", "Free value not found", (char *) 0 ) ;
- }
-
- int h4free_check( int max_left )
- {
- if ( h4num_used > max_left )
- u4error( E_INTERNAL, "h4free_test()", "Free value not found", (char *) 0 ) ;
-
- return ( h4num_used ) ;
- }
- #endif
-