home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / dbmalloc.zip / realloc.c~ < prev    next >
Text File  |  1993-01-04  |  11KB  |  491 lines

  1. /*
  2.  * (c) Copyright 1990, 1991, 1992 Conor P. Cahill (cpcahil@virtech.vti.com)
  3.  *
  4.  * This software may be distributed freely as long as the following conditions
  5.  * are met:
  6.  *         * the distribution, or any derivative thereof, may not be
  7.  *          included as part of a commercial product
  8.  *        * full source code is provided including this copyright
  9.  *        * there is no charge for the software itself (there may be
  10.  *          a minimal charge for the copying or distribution effort)
  11.  *        * this copyright notice is not modified or removed from any
  12.  *          source file
  13.  */
  14.  
  15. #ifndef lint
  16. static
  17. char rcs_hdr[] = "$Id: realloc.c,v 1.26 1992/09/03 22:24:33 cpcahil Exp $";
  18. #endif
  19.  
  20. #include <stdio.h>
  21.  
  22. #include "mallocin.h"
  23.  
  24. DATATYPE *
  25. realloc(cptr,size)
  26.     DATATYPE        * cptr;
  27.     SIZETYPE          size;
  28. {
  29.     return( debug_realloc(NULL,-1,cptr,size) );
  30. }
  31.  
  32. DATATYPE *
  33. debug_realloc(file,line,cptr,size)
  34.     CONST char        * file;
  35.     int              line;
  36.     DATATYPE        * cptr;
  37.     SIZETYPE          size;
  38. {
  39.     static IDTYPE          call_counter;
  40.  
  41.     /*
  42.      * increment the call counter
  43.      */
  44.     call_counter++;
  45.  
  46.     return( DBFrealloc("realloc",M_T_REALLOC,call_counter,
  47.               file,line,cptr,size) );
  48.  
  49. }
  50.  
  51. /*
  52.  * Function:    DBFrealloc()
  53.  *
  54.  * Purpose:    to re-allocate a data area.
  55.  *
  56.  * Arguments:    cptr    - pointer to area to reallocate
  57.  *        size    - size to change area to
  58.  *
  59.  * Returns:    pointer to new area (may be same area)
  60.  *
  61.  * Narrative:    verify pointer is within malloc region
  62.  *        obtain mlist pointer from cptr
  63.  *        verify magic number is correct
  64.  *        verify inuse flag is set
  65.  *        verify connection to adjoining segments is correct
  66.  *        save requested size
  67.  *        round-up size to appropriate boundry
  68.  *        IF size is bigger than what is in this segment
  69.  *            try to join next segment to this segment
  70.  *        IF size is less than what is is this segment
  71.  *            determine leftover amount of space
  72.  *        ELSE
  73.  *            allocate new segment of size bites
  74.  *            IF allocation failed
  75.  *                return NULL
  76.  *            copy previous data to new segment
  77.  *            free previous segment
  78.  *            return new pointer
  79.  *        split of extra space in this segment (if any)
  80.  *        clear bytes beyound what they had before
  81.  *        return pointer to data 
  82.  */
  83.  
  84. DATATYPE *
  85. DBFrealloc(func,type,call_counter,file,line,cptr,size)
  86.     CONST char        * func;
  87.     int              type;
  88.     IDTYPE              call_counter;
  89.     CONST char        * file;
  90.     int              line;
  91.     DATATYPE        * cptr;
  92.     SIZETYPE          size;
  93. {
  94.     SIZETYPE          i;
  95.     char            * new_cptr;
  96.     int              marked;
  97.     SIZETYPE          need;
  98.     struct mlist        * optr;
  99.     struct mlist        * ptr;
  100.     SIZETYPE          r_size;
  101.     SIZETYPE          start;
  102.  
  103.     MALLOC_INIT();
  104.  
  105.     /*
  106.      * IF malloc chain checking is on, go do it.
  107.      */
  108.     if( malloc_opts & MOPT_CKCHAIN )
  109.     {
  110.         VOIDCAST DBFmalloc_chain_check(func,file,line,1);
  111.     }
  112.  
  113.     /*
  114.      * if the user wants to be warned about zero length mallocs, do so
  115.      */
  116.     if( ((malloc_opts & MOPT_ZERO) != 0) && (size == 0) )
  117.     {
  118.         malloc_errno = M_CODE_ZERO_ALLOC;
  119.         malloc_warning(func,file,line,(struct mlist *)NULL);
  120.     }
  121.  
  122.     /*
  123.      * if this is an ansi-c compiler and we want to use the realloc(0) 
  124.      * paradigm, or if this is a call from xtrealloc, then if the 
  125.      * pointer is a null, act as if this is a call to malloc.
  126.      */
  127. #if defined(ANSI_NULLS) || (__STDC__ && ! defined(NO_ANSI_NULLS))
  128.     if( cptr == NULL )
  129. #else
  130.     if( (cptr == NULL) && (type == M_T_XTREALLOC) )
  131. #endif
  132.     {
  133.         /*
  134.          * allocate the new chunk
  135.          */
  136.         new_cptr = DBFmalloc(func,type,call_counter,file,line,size);
  137.  
  138.         return(new_cptr);
  139.     }
  140.  
  141.     /*
  142.      * verify that cptr is within the malloc region...
  143.      */
  144.     if(    (cptr < malloc_data_start)
  145.         || (cptr > malloc_data_end) 
  146.         || ((((long)cptr) & malloc_round) != 0 ) )
  147.     {
  148.         malloc_errno = M_CODE_BAD_PTR;
  149.         malloc_warning(func,file,line,(struct mlist *)NULL);
  150.         return (NULL);
  151.     }
  152.  
  153.     /* 
  154.      * convert pointer to mlist struct pointer.  To do this we must 
  155.      * move the pointer backwards the correct number of bytes...
  156.      */
  157.     
  158.     ptr = (struct mlist *) (((char *)cptr) - M_SIZE);
  159.     
  160.     if( (ptr->flag&M_MAGIC_BITS) != M_MAGIC )
  161.     {
  162.         malloc_errno = M_CODE_BAD_MAGIC;
  163.         malloc_warning(func,file,line,(struct mlist *)NULL);
  164.         return(NULL);
  165.     }
  166.  
  167.     if( ! (ptr->flag & M_INUSE) )
  168.     {
  169.         malloc_errno = M_CODE_NOT_INUSE ;
  170.         malloc_warning(func,file,line,ptr);
  171.         return(NULL);
  172.     }
  173.  
  174.      if( (ptr->prev && (ptr->prev->next != ptr) ) ||
  175.         (ptr->next && (ptr->next->prev != ptr) ) ||
  176.         ((ptr->next == NULL) && (ptr->prev == NULL)) )
  177.     {
  178.         malloc_errno = M_CODE_BAD_CONNECT;
  179.         malloc_warning(func,file,line,ptr);
  180.         return(NULL);
  181.     }
  182.  
  183.     /*
  184.      * save the marked status
  185.      */
  186.     marked = ptr->flag & M_MARKED;
  187.  
  188.     /*
  189.      * save the requested size;
  190.      */
  191.     r_size = size;
  192.  
  193.     /*
  194.      * make sure we have the full boundary that is needed
  195.      */
  196.     size += malloc_boundsize;
  197.  
  198.     M_ROUNDUP(size);
  199.  
  200.     if( (size > ptr->s.size) && ((malloc_opts & MOPT_REUSE) != 0) )
  201.     {
  202.         malloc_join(ptr,ptr->next,INUSEOK,DOFILL);
  203.     }
  204.  
  205.     /*
  206.      * if we still don't have enough room, and we are at the end of the
  207.      * malloc chain and we are up against the current sbrk, we can just
  208.       * sbrk more room for our data area.
  209.       */    
  210.     if(    (size > ptr->s.size)
  211.         && (ptr == malloc_end) 
  212.         && ((ptr->data+ptr->s.size) == sbrk(0) ) )
  213.     {
  214.         need = size - ptr->s.size;
  215.  
  216.         /*
  217.          * if the need is less than the minimum block size,
  218.          *     get the minimum block size
  219.           */
  220.         if( need < M_BLOCKSIZE )
  221.         {
  222.             need = M_BLOCKSIZE;
  223.         }
  224.         /*
  225.          * else if the need is not an even multiple of the block size,
  226.          *     round it up to an even multiple
  227.          */
  228.         else if( need & (M_BLOCKSIZE-1) )
  229.         {
  230.             need &= ~(M_BLOCKSIZE-1);
  231.             need += M_BLOCKSIZE;
  232.         }
  233.  
  234.         /*
  235.          * get the space from the os
  236.           */
  237.         cptr = sbrk(need);
  238.  
  239.         /*
  240.          * if we failed to get the space, tell the user about it
  241.          */
  242.         if( cptr == (char *) -1 )
  243.         {
  244.             malloc_errno = M_CODE_NOMORE_MEM;
  245.             malloc_fatal(func,file,line, (struct mlist *)NULL);
  246.             return(NULL);
  247.         }
  248.  
  249.         /*
  250.          * adjust our segment size (extra space will be split off later
  251.          */
  252.         start = ptr->s.size;
  253.         ptr->s.size += need;
  254.  
  255.         /*
  256.          * we have to act like this was a join of a new segment so
  257.          * we need to call the fill routine to get it to fill the
  258.          * new data area.
  259.          */
  260.         FILLDATA(ptr,FILL_JOIN,start,(struct mlist *)NULL);
  261.  
  262.         /*
  263.          * mark our end point
  264.          */
  265.         malloc_data_end = sbrk((int)0);
  266.     
  267.     }
  268.     
  269.         
  270.     /*
  271.      * if the size is still too small and the previous segment is free
  272.      * and it would be big enough it if was joined to the current segment
  273.      */
  274.     if(    ((malloc_opts & MOPT_CKCHAIN) != 0)
  275.         && (size > ptr->s.size)
  276.         && ((ptr->prev->flag & M_INUSE) == 0)
  277.         && (size < (ptr->s.size + ptr->prev->s.size + M_SIZE) ) )
  278.     {
  279.         /*
  280.          * save the old pointer
  281.          */
  282.         optr = ptr;
  283.  
  284.         /*
  285.          * move out pointer to the proper area.
  286.          */
  287.         ptr = ptr->prev;
  288.     
  289.         /*
  290.           * force this pointer to be inuse
  291.          */
  292.         ptr->flag |= M_INUSE;
  293.         ptr->r_size = ptr->next->r_size;
  294.         
  295.         /*
  296.           * join the two segments
  297.          */
  298.         malloc_join(ptr, ptr->next, ANY_INUSEOK, DONTFILL);
  299.  
  300.         /*
  301.          * remove ptr from the free list
  302.          */
  303.         malloc_freeseg(M_FREE_REMOVE,ptr);
  304.  
  305.         /*
  306.          * copy data from the current space to the new space.  Note
  307.           * that the data areas for this copy will likely overlap.
  308.          */
  309.         DataMC(ptr->data,optr->data,ptr->r_size);
  310.  
  311.         /*
  312.          * note that we don't fill in the areas here.  It will be
  313.          * filled later
  314.          */
  315.  
  316.     }
  317.     if( size > ptr->s.size )
  318.     {
  319.         /*
  320.          * else we can't combine it, so lets allocate a new chunk,
  321.          * copy the data and free the old chunk...
  322.          */
  323.         new_cptr = DBFmalloc(func,type,call_counter,file,line,size);
  324.  
  325.         if( new_cptr == (char *) 0)
  326.         {
  327.             return(new_cptr);
  328.         }
  329.  
  330.         if( r_size < ptr->r_size )
  331.         {
  332.             i = r_size;
  333.         }
  334.         else
  335.         {
  336.             i = ptr->r_size;
  337.         }
  338.         in_malloc_code++;
  339.         VOIDCAST memcpy(new_cptr,ptr->data,i);
  340.         in_malloc_code--;
  341.  
  342.         /*
  343.          * if the old segment was marked, unmark it and mark the new
  344.          * segment.
  345.          */
  346.         if( marked )
  347.         {
  348.             ptr->flag &= ~M_MARKED;
  349.             malloc_mark(new_cptr);
  350.         }
  351.  
  352.         /*
  353.          * free the old segment since it is no longer needed.
  354.          */
  355.         DBFfree("realloc:free",F_T_REALLOC,call_counter,file,line,cptr);
  356.  
  357.         
  358.         return(new_cptr);
  359.  
  360.     } /* if( size... */
  361.  
  362.     /*
  363.      * save amount of real data in new segment (this will be used in the
  364.      * memset later) and then save requested size of this segment.
  365.      */
  366.     if( ptr->r_size < r_size )
  367.     {
  368.         i = ptr->r_size;
  369.     }
  370.     else
  371.     {
  372.         i = r_size;
  373.     }
  374.  
  375.     ptr->r_size = r_size;
  376.  
  377.     /*
  378.      * split off extra free space at end of this segment, if possible...
  379.      */
  380.  
  381.     malloc_split(ptr);
  382.  
  383.     /*
  384.      * save the id info.
  385.      */    
  386.     ptr->file      = file;
  387.     ptr->line      = line;
  388.     ptr->id        = call_counter;
  389.     ptr->hist_id   = malloc_hist_id++;
  390.     ptr->stack     = StackCurrent();
  391.     ptr->freestack = NULL;
  392.     SETTYPE(ptr,type);
  393.  
  394.     /*
  395.      * fill data and/or boundary areas
  396.      */
  397.     FILLDATA(ptr,FILL_REALLOC,i, (struct mlist *) NULL);
  398.     
  399.     return(ptr->data);
  400.  
  401. } /* DBFrealloc(... */
  402.  
  403.  
  404. /*
  405.  * $Log: realloc.c,v $
  406.  * Revision 1.26  1992/09/03  22:24:33  cpcahil
  407.  * final changes for PL14
  408.  *
  409.  * Revision 1.25  1992/08/22  16:27:13  cpcahil
  410.  * final changes for pl14
  411.  *
  412.  * Revision 1.24  1992/07/03  00:03:25  cpcahil
  413.  * more fixes for pl13, several suggestons from Rich Salz.
  414.  *
  415.  * Revision 1.23  1992/05/14  23:02:27  cpcahil
  416.  * added support for ANSI NULL behavior even with non-ansi compilers (if
  417.  * chosen at compile time).
  418.  *
  419.  * Revision 1.22  1992/05/08  02:30:35  cpcahil
  420.  * minor cleanups from minix/atari port
  421.  *
  422.  * Revision 1.21  1992/05/06  05:37:44  cpcahil
  423.  * added overriding of fill characters and boundary size
  424.  *
  425.  * Revision 1.20  1992/05/06  04:53:29  cpcahil
  426.  * performance enhancments
  427.  *
  428.  * Revision 1.19  1992/04/22  18:17:32  cpcahil
  429.  * added support for Xt Alloc functions, linted code
  430.  *
  431.  * Revision 1.18  1992/04/13  03:06:33  cpcahil
  432.  * Added Stack support, marking of non-leaks, auto-config, auto-testing
  433.  *
  434.  * Revision 1.17  1992/03/01  12:42:38  cpcahil
  435.  * added support for managing freed areas and fixed doublword bndr problems
  436.  *
  437.  * Revision 1.16  1992/01/30  12:23:06  cpcahil
  438.  * renamed mallocint.h -> mallocin.h
  439.  *
  440.  * Revision 1.15  1992/01/10  17:28:03  cpcahil
  441.  * Added support for overriding void datatype
  442.  *
  443.  * Revision 1.14  1991/12/06  08:54:19  cpcahil
  444.  * cleanup of __STDC__ usage and addition of CHANGES file
  445.  *
  446.  * Revision 1.13  91/12/04  09:23:44  cpcahil
  447.  * several performance enhancements including addition of free list
  448.  * 
  449.  * Revision 1.12  91/12/02  19:10:14  cpcahil
  450.  * changes for patch release 5
  451.  * 
  452.  * Revision 1.11  91/11/25  14:42:05  cpcahil
  453.  * Final changes in preparation for patch 4 release
  454.  * 
  455.  * Revision 1.10  91/11/24  00:49:32  cpcahil
  456.  * first cut at patch 4
  457.  * 
  458.  * Revision 1.9  91/11/20  11:54:11  cpcahil
  459.  * interim checkin
  460.  * 
  461.  * Revision 1.8  90/08/29  21:22:52  cpcahil
  462.  * miscellaneous lint fixes
  463.  * 
  464.  * Revision 1.7  90/05/11  00:13:10  cpcahil
  465.  * added copyright statment
  466.  * 
  467.  * Revision 1.6  90/02/25  11:01:20  cpcahil
  468.  * added support for malloc chain checking.
  469.  * 
  470.  * Revision 1.5  90/02/24  21:50:31  cpcahil
  471.  * lots of lint fixes
  472.  * 
  473.  * Revision 1.4  90/02/24  17:29:39  cpcahil
  474.  * changed $Header to $Id so full path wouldnt be included as part of rcs 
  475.  * id string
  476.  * 
  477.  * Revision 1.3  90/02/24  17:20:00  cpcahil
  478.  * attempt to get rid of full path in rcs header.
  479.  * 
  480.  * Revision 1.2  90/02/24  15:14:20  cpcahil
  481.  * 1. added function header 
  482.  * 2. changed calls to malloc_warning to conform to new usage
  483.  * 3. added setting of malloc_errno
  484.  *  4. broke up bad pointer determination so that errno's would be more
  485.  *    descriptive
  486.  * 
  487.  * Revision 1.1  90/02/22  23:17:43  cpcahil
  488.  * Initial revision
  489.  * 
  490.  */
  491.