home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0010 - 0019 / ibm0010-0019 / ibm0010.tar / ibm0010 / CODE4-1.ZIP / SOURCE.ZIP / H4.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-10-14  |  9.3 KB  |  393 lines

  1. /* h4.c  Memory Handler
  2.    (c)Copyright Sequiter Software Inc., 1987, 1988, 1989.  All rights reserved.
  3. */
  4.  
  5. #include "d4base.h"
  6. #include "h4memory.h"
  7. #include "u4error.h"
  8.  
  9. #ifdef WINDOWS_L
  10.    #define  WINDOWS
  11. #endif
  12. #ifdef WINDOWS_G
  13.    #define  WINDOWS
  14. #endif
  15. #ifdef WINDOWS
  16.    #include "windows.h"
  17. #else
  18.    extern void *malloc(unsigned int) ;
  19. #endif
  20.  
  21. #ifndef UNIX
  22. #ifndef WINDOWS
  23.    #include <stdlib.h>
  24. #endif
  25. #endif
  26. #include <string.h>
  27.  
  28. int  h4add( ptr_ptr, mem_ref, add_ref, add_before ) 
  29. char ** ptr_ptr ;
  30. int  mem_ref, add_ref ;
  31. int  add_before ;
  32. {
  33.    MEMORY *memory ;
  34.    UNIT   *mem_ptr, *add_ptr, *next_ptr ;
  35.  
  36.    if ( add_ref == mem_ref || add_ref < 0 )  return add_ref;
  37.  
  38.    if ( add_before && mem_ref >= 0 )
  39.    {
  40.       h4add( ptr_ptr, mem_ref, add_ref, 0 ) ;   
  41.       h4remove( ptr_ptr, mem_ref ) ;
  42.       h4add( ptr_ptr, add_ref, mem_ref, 0 ) ;   
  43.  
  44.       return  add_ref ;
  45.    }
  46.  
  47.    memory = (MEMORY *) (*ptr_ptr -sizeof(MEMORY)) ;
  48.  
  49.    add_ptr = (UNIT *) (*ptr_ptr + memory->len_unit* add_ref) ;
  50.    add_ptr->prev =  mem_ref ;
  51.    if ( mem_ref < 0 )
  52.    {
  53.       add_ptr->next =  -1 ;
  54.       return  add_ref ;
  55.    }
  56.  
  57.    mem_ptr  = (UNIT *) (*ptr_ptr + memory->len_unit* mem_ref) ;
  58.    next_ptr = (UNIT *) (*ptr_ptr + memory->len_unit* mem_ptr->next) ;
  59.  
  60.    add_ptr->next =  mem_ptr->next ;
  61.    mem_ptr->next =  add_ref ;
  62.  
  63.    if ( add_ptr->next < 0 )  return  add_ref ;
  64.    next_ptr->prev =  add_ref ;
  65.  
  66.    return  add_ref ;
  67. }
  68.  
  69.  
  70. int  h4remove( ptr_ptr, mem_ref ) 
  71. char ** ptr_ptr ;
  72. int mem_ref ;
  73. {
  74.    MEMORY *memory ;
  75.    UNIT   *mem_ptr, *previous_ptr, *next_ptr ;
  76.    int     return_unit ;
  77.  
  78.    if ( mem_ref < 0 )  return -1 ;
  79.    memory = (MEMORY *) (*ptr_ptr -sizeof(MEMORY)) ;
  80.  
  81.    mem_ptr = (UNIT *) (*ptr_ptr + memory->len_unit* mem_ref) ;
  82.    if ( mem_ptr->next >= 0 )
  83.    {
  84.       return_unit    =  mem_ptr->next ;
  85.       next_ptr       = (UNIT *) (*ptr_ptr + memory->len_unit* mem_ptr->next) ;
  86.       next_ptr->prev =  mem_ptr->prev ;
  87.    }
  88.    else
  89.       return_unit    =  -1 ;
  90.  
  91.    if ( mem_ptr->prev >= 0 )
  92.    {
  93.       return_unit        =  mem_ptr->prev ;
  94.       previous_ptr       = (UNIT *) (*ptr_ptr + memory->len_unit*mem_ptr->prev);
  95.       previous_ptr->next =  mem_ptr->next ;
  96.    }
  97.    mem_ptr->prev =  -1 ;
  98.    mem_ptr->next =  -1 ;
  99.  
  100.    return( return_unit ) ;
  101. }
  102.  
  103.  
  104. /* h4alloc.c
  105.  
  106.    Memory allocation routine.
  107.    Calls u4error if there is not enough memory.
  108.    Zeros the memory with NULL's
  109. */
  110.  
  111. char * h4alloc(num)
  112. unsigned int num ;
  113. {
  114.    char * ptr ;
  115.  
  116.    #ifdef WINDOWS
  117.       ptr =  h4alloc_try(num) ;
  118.    #else
  119.       ptr =  malloc(num) ;
  120.    #endif
  121.  
  122.    if (ptr==  ((char *)0) )
  123.    {
  124.       u4error( E_MEMORY, (char *) 0) ;
  125.       return( (char *) 0 ) ;
  126.    }
  127.    else
  128.       memset(ptr, 0, (size_t) num) ;
  129.  
  130.    return( ptr) ;
  131. }
  132.  
  133. char * h4alloc_try(num)
  134. unsigned int num ;
  135. {
  136.    #ifdef WINDOWS
  137.       HANDLE  handle, *handle_ptr ;
  138.  
  139.       handle_ptr =  (HANDLE *) 0 ;
  140.  
  141.       #ifdef WINDOWS_G
  142.          handle =  GlobalAlloc( GMEM_FIXED, (DWORD) num+ sizeof(HANDLE) ) ;
  143.      if ( handle != (HANDLE) 0 )
  144.      {
  145.         handle_ptr =  (HANDLE *) GlobalLock( handle ) ;
  146.         *handle_ptr++ =  handle ;
  147.      }
  148.       #else
  149.          handle =  LocalAlloc( LMEM_FIXED, (WORD) num+ sizeof(HANDLE) ) ;
  150.      if ( handle != (HANDLE) 0 )
  151.      {
  152.         handle_ptr =  (HANDLE *) LocalLock( handle ) ;
  153.         *handle_ptr++ =  handle ;
  154.      }
  155.       #endif
  156.  
  157.       return( (char *) handle_ptr ) ;
  158.    #else
  159.       char * ptr ;
  160.       ptr =  malloc(num) ;
  161.  
  162.       return( ptr) ;
  163.    #endif
  164. }
  165.  
  166. void  h4free_memory( ptr )
  167. void *ptr ;
  168. {
  169.    #ifdef WINDOWS
  170.       #ifdef WINDOWS_G
  171.          HANDLE  hand ;
  172.  
  173.      hand =  ((HANDLE *) ptr)[-1] ;
  174.  
  175.       /* rc   =  GlobalUnlock( hand ) ;
  176.      if ( rc )    u4error( E_INTERNAL, "h4free_memory", (char *) 0 ) ;
  177.       */
  178.  
  179.      hand =  GlobalFree( hand ) ;
  180.      if ( hand != (HANDLE) 0 )    
  181.               u4error( E_INTERNAL, "h4free_memory", (char *) 0 ) ;
  182.       #else
  183.          HANDLE  hand ;
  184.  
  185.      hand =  ((HANDLE *) ptr)[-1] ;
  186.  
  187.       /* rc   =  LocalUnlock( hand ) ;
  188.      if ( ! rc )   u4error( E_INTERNAL, "h4free_memory", (char *) 0 ) ;
  189.       */
  190.  
  191.      hand =  LocalFree( hand ) ;
  192.      if ( hand != (HANDLE) 0 )    
  193.               u4error( E_INTERNAL, "h4free_memory", (char *) 0 ) ;
  194.       #endif
  195.    #else
  196.       free(ptr) ;
  197.    #endif
  198. }
  199.  
  200.  
  201.  
  202. /*  h4get.c
  203.  
  204.     Allocates a block of memory from the predefined memory array.
  205.     Adds it to the end of the linked list.
  206. */
  207.  
  208. int h4get( ptr_ptr, previous_ref)
  209. char ** ptr_ptr ;
  210. int    previous_ref ;
  211. {
  212.    char   *new_ptr ;
  213.    int      i, unit_ref ;
  214.    long   new_size ;
  215.    MEMORY *memory ;
  216.    UNIT   *unit_ptr, *previous_ptr, *next_ptr ;
  217.  
  218.    memory= (MEMORY *) (*ptr_ptr -sizeof(MEMORY)) ;
  219.  
  220.    if (memory->first_free >= memory->num_unit)
  221.    {
  222.       /*  Must allocate some additional memory for the new unit */
  223.  
  224.       new_size = (unsigned int) memory->len_unit*
  225.        ((unsigned long)memory->num_unit+memory->add_unit)+sizeof(MEMORY);
  226.       if ( new_size > 0xFFE0L )
  227.       {
  228.          u4error( E_ALLOCATE, "h4create()", (char *) 0 ) ;
  229.      return -1 ;
  230.       }
  231.       new_ptr  = h4alloc((unsigned int) new_size) ;
  232.       if ( new_ptr == (char *) 0 )  return -1 ;
  233.  
  234.       memcpy( new_ptr, (char *) memory, (size_t) 
  235.            (memory->len_unit*(unsigned long) memory->num_unit)+ sizeof(MEMORY)) ;
  236.       h4free_memory((char *) memory) ;
  237.  
  238.       /* update  memory and  *ptr_ptr  to the new memory block */
  239.       memory      = (MEMORYPTR) new_ptr ;
  240.       new_ptr     += sizeof(MEMORY) ;
  241.       *ptr_ptr      = new_ptr ;
  242.  
  243.       /*  Create some pointers to keep track of the newly memory units */
  244.       unit_ptr      = (UNIT *) (*ptr_ptr + memory->len_unit* memory->num_unit) ;
  245.  
  246.       for (i= memory->num_unit+1; i<= memory->num_unit+ memory->add_unit; i++)
  247.       {
  248.      unit_ptr->next = i ;
  249.      unit_ptr    = (UNIT *) ((char *)unit_ptr +    memory->len_unit) ;
  250.       }
  251.  
  252.       /* There is new number of memory units in the memory block */
  253.       memory->num_unit += memory->add_unit ;
  254.    }
  255.  
  256.    /*  Unallocate from the chain of unallocated units */
  257.    unit_ptr          = (UNIT *) (*ptr_ptr + memory->len_unit* memory->first_free) ;
  258.    unit_ref          =  memory->first_free ;
  259.    memory->first_free =  unit_ptr->next  ;
  260.  
  261.    /*  Add to the new double linked list */
  262.    if (previous_ref >= 0)
  263.    {
  264.       unit_ptr->prev     =  previous_ref ;
  265.       previous_ptr     = (UNIT *) (*ptr_ptr + memory->len_unit* previous_ref) ;
  266.       unit_ptr->next     =  previous_ptr->next ;
  267.       previous_ptr->next = unit_ref ;
  268.  
  269.       if ( unit_ptr->next >= 0 )
  270.       {
  271.      next_ptr     = (UNIT *) (*ptr_ptr + memory->len_unit* previous_ptr->next) ;
  272.      next_ptr->prev  = unit_ref ;
  273.       }
  274.    }
  275.    else
  276.    {
  277.       unit_ptr->next  =  -1 ;
  278.       unit_ptr->prev  =  -1 ;
  279.    }
  280.    memset( (char *)unit_ptr+sizeof(UNIT), 0, (size_t) memory->len_unit-sizeof(UNIT) ) ;
  281.  
  282.    return( unit_ref ) ;
  283. }
  284.  
  285. /* h4create.c */
  286.  
  287. int  h4create ( ptr_ptr, num, len, add)
  288. char ** ptr_ptr ;
  289. int len, num, add ;
  290. {
  291.    int    i ;
  292.    unsigned long  total ;
  293.    MEMORYPTR   mem_stru ;
  294.    union 
  295.    {
  296.       int   *int_ptr  ;
  297.       char  *char_ptr ;
  298.    }  ptr ;
  299.  
  300.    if (len<= 0) len = 1 ;
  301.    if (num<= 0) num = 1 ;
  302.    if (add<=0)    add = 1 ;
  303.  
  304.    total =  (unsigned long) len * num + sizeof(MEMORY) ;
  305.    if (total > 0xFFE0L )
  306.       u4error( E_ALLOCATE, "h4create()", (char *) 0 ) ;
  307.    ptr.char_ptr =  h4alloc( (unsigned int) total ) ;
  308.    if ( ptr.char_ptr == (char *) 0 )  return -1 ;
  309.  
  310.    mem_stru = (MEMORYPTR) ptr.char_ptr ;
  311.    ptr.char_ptr += sizeof(MEMORY) ;
  312.    *ptr_ptr = ptr.char_ptr ;
  313.  
  314.    mem_stru->first_free= 0 ;
  315.    mem_stru->len_unit  = len ;
  316.    mem_stru->num_unit  = num ;
  317.    mem_stru->add_unit  = add ;
  318.  
  319.    for (i=1; i<=num; i++)
  320.    {
  321.       *ptr.int_ptr  =  i ;
  322.       ptr.char_ptr +=  len ;
  323.    }
  324.  
  325.    return 0 ;
  326. }
  327.  
  328. /*
  329.     h4free.c
  330.  
  331.     Frees a memory unit.
  332.     Maintains the double linked list.
  333.  
  334.     Returns
  335.        Returns the a reference to the previous memory unit.
  336.        If the previous memory unit does not exist, return a reference
  337.        to the next memory unit.  If a next memory unit does not exist,
  338.        return -1.
  339.  
  340.        On error return -2.
  341. */
  342.  
  343. h4free( ptr_ptr, unit_ref)
  344. char ** ptr_ptr ;
  345. int    unit_ref ;
  346. {
  347.    MEMORY *memory ;
  348.    UNIT   *unit_ptr, *next_ptr, *previous_ptr ;
  349.    int       return_unit ;
  350.  
  351.    memory = (MEMORY *) ( *ptr_ptr - sizeof(MEMORY) ) ;
  352.    if (unit_ref>= memory->num_unit || unit_ref<0)
  353.    {
  354.       u4error( E_INTERNAL, "H4FREE", (char *) 0) ;
  355.       return(-2) ;
  356.    }
  357.  
  358.    unit_ptr     = (UNIT *) (*ptr_ptr +  memory->len_unit* unit_ref) ;
  359.  
  360.    /*  Maintain the double linked list */
  361.    if ( unit_ptr->next >= 0)
  362.    {
  363.       next_ptr        = (UNIT *) (*ptr_ptr +  memory->len_unit* unit_ptr->next) ;
  364.       next_ptr->prev=  unit_ptr->prev ;
  365.    }
  366.    if ( unit_ptr->prev >= 0)
  367.    {
  368.       previous_ptr    = (UNIT *) (*ptr_ptr +    memory->len_unit* unit_ptr->prev);
  369.       previous_ptr->next= unit_ptr->next ;
  370.  
  371.       return_unit    = unit_ptr->prev ;
  372.    }
  373.    else
  374.       return_unit    = unit_ptr->next ;
  375.  
  376.  
  377.    /*  Fix up the pointer to the released memory */
  378.  
  379.    unit_ptr->next     =  memory->first_free ;
  380.    memory->first_free =  unit_ref ;
  381.  
  382.    return( return_unit ) ;
  383. }
  384.  
  385.  
  386. void  h4free_chain( ptr_ref_ptr, mem_ref )
  387. char **ptr_ref_ptr ;
  388. int    mem_ref ;
  389. {
  390.    while ( mem_ref >= 0 )
  391.       mem_ref =  h4free( ptr_ref_ptr, mem_ref ) ;
  392. }
  393.