home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 328_01 / heapdbg.c < prev    next >
C/C++ Source or Header  |  1991-02-28  |  8KB  |  518 lines

  1. /* HEAPDBG.C
  2.  *
  3.  *    a smaller version of the wheap.c program.
  4.  *  This version only allocates memory from DOS 'far' ram. Expanded memory 
  5.  *    and disk virtual memory are ignored. The variable wheap_ramlimit is ignored
  6.  *
  7.  *    The reason for this is that wheap.c allocates a 64-k disk IO buffer,
  8.  *    which can make use of the TurboC debugger or codeview impossible 
  9.  *  (too much ram)
  10.  *
  11.  *  USE:    
  12.  *    the calling routine follows this sequence (details ommitted):
  13.  *        WHEAP *heap_ptr, char far *data_ptr;
  14.  *
  15.  *             heap_ptr = wheap_alloc ();              ... acquire heap storage
  16.  *             data_ptr = wheap_access( heap_ptr,...); ... move to RAM
  17.  *                  ... do something using data_ptr
  18.  *            wheap_deaccess ( heap_ptr, ...); ... release back to heap
  19.  *            wheap_free     ( heap_ptr );     ... free from heap.
  20.  *
  21.  *    method: WHEAP block is a double linked list,
  22.  *            most recent near heap_top
  23.  *        items added/removed at any time.
  24.  *
  25.  */
  26.  
  27.  
  28.  
  29. #include <stdlib.h>
  30. #ifndef __TURBOC__
  31.     /* Microsoft C */
  32.     #include <malloc.h>
  33. #else
  34.     /* Turbo C */
  35.     #include <alloc.h>
  36. #endif
  37.  
  38.  
  39. #include <string.h>
  40.  
  41.  
  42.  
  43.  
  44.  
  45. #define WHEAP_GLOBALS
  46.  
  47. #include "wtwg.h"
  48.  
  49.  
  50. #ifdef __OVERLAY__
  51.     /* TURBO C VROOM - may not use near calls */
  52.     #define NEAR_CALL
  53. #else 
  54.     /* for large model, slightly faster */
  55.     #define NEAR_CALL near
  56. #endif
  57.  
  58.  
  59.  
  60. /* Limitation on how much dos far ram can be used as heap.
  61.  */
  62.        unsigned long wheap_ramlimit = (256L*1024L);
  63.  
  64.  
  65. static WHEAP         *current_access = NULL;
  66.  
  67.  
  68.  
  69.  
  70. #ifdef __TURBOC__
  71.     /* TURBOC is able to generate forward address refs.
  72.      * so heap_top can be initialized properly
  73.      * but in Microsoft, need to do this in wheap_init
  74.      * because microsoft C can't handle the forward address reference.
  75.      */
  76. static WHEAP  NEAR_CALL heap_bottom;
  77.  
  78.  
  79. static WHEAP  NEAR_CALL heap_top =
  80.     {
  81.     NULL,           /* linked list -- _next, _prev */
  82.     &heap_bottom,
  83.  
  84.     WHEAP_MAX,    /* num bytes -in xms systems, # reqrd for dskbase */
  85.     WHP_DSK,    /* flag */
  86.  
  87.     255,        /* priority */
  88.  
  89.     NULL,        /* disk access buffer ptr (xms or ram) */
  90.  
  91.     NULL,        /* double list - dskhi, then dsklo */
  92.     &heap_bottom,
  93.  
  94.     0,
  95.  
  96.     0,
  97.     0,
  98.  
  99.     0,
  100.     0        /* filler     */
  101.  
  102.     };
  103.  
  104. static WHEAP  NEAR_CALL heap_bottom =
  105.     {
  106.     &heap_top,
  107.     NULL,
  108.  
  109.     0,
  110.     WHP_DSK,
  111.  
  112.     255,
  113.  
  114.     NULL,
  115.  
  116.     &heap_top,
  117.     NULL,
  118.  
  119.     0,        /* lowest disk marker is start of file */
  120.  
  121.     0,
  122.     0,
  123.  
  124.     0,
  125.     0
  126.  
  127.     };
  128.  
  129. #else
  130.     /* Microsoft C version - can't initialize the double linked list
  131.      * properly, so must do it at run-time.
  132.      */
  133.  
  134. static WHEAP  NEAR_CALL heap_top =
  135.     {
  136.     NULL,           /* linked list -- _next, _prev */
  137.     NULL,           /* WILL BE INITIALIZED AT RUN TIME */
  138.  
  139.     WHEAP_MAX,      /* num bytes -in xms systems, # reqrd for dskbase */
  140.     WHP_DSK,        /* flag */
  141.  
  142.     255,            /* priority */
  143.  
  144.     NULL,           /* disk access buffer ptr (xms or ram) */
  145.  
  146.     NULL, 
  147.     NULL,           /* MICROSOFT - initialize at runtime */
  148.  
  149.     0,
  150.  
  151.     0,
  152.     0,
  153.  
  154.     0,
  155.     0               /* filler     */
  156.  
  157.     };
  158.  
  159. static WHEAP  NEAR_CALL heap_bottom =
  160.     {
  161.     &heap_top,
  162.     NULL,
  163.  
  164.     0,
  165.     WHP_DSK,
  166.  
  167.     255,
  168.  
  169.     NULL,
  170.  
  171.     &heap_top,
  172.     NULL,
  173.  
  174.     0,
  175.  
  176.     0,
  177.     0,
  178.  
  179.     0,
  180.     0
  181.  
  182.     };
  183.  
  184.  
  185. #endif  /* Microsoft verswion */
  186.  
  187.  
  188.  
  189.  
  190.  
  191.     /*------ XMS subroutines -------*/
  192.     /*  removed from small version */
  193.  
  194.     /*------ DSK subroutines -------*/
  195.     /*  removed from small version */
  196.  
  197.  
  198.  
  199.     /*------ RAM subroutines -------*/
  200.  
  201. static int  NEAR_CALL ram_alloc    ( WHEAP *hptr );
  202.  
  203.  
  204.     /*------ memory management routines --------------*/
  205.  
  206. static void NEAR_CALL unchain_heap ( WHEAP *hptr );
  207.  
  208.  
  209.  
  210.  
  211.  
  212.     /*---------Disk and Expanded routines - removed -------------*/
  213.  
  214.  
  215.  
  216.  
  217.  
  218.     /*------ RAM subroutines -------*/
  219.  
  220. static int  NEAR_CALL ram_alloc ( WHEAP *hptr )
  221.     {
  222.     void far *ptr;
  223.     int       retcode;
  224.     size_t    nbytes;
  225.  
  226.     nbytes = hptr-> whp_nb;
  227.  
  228.     ptr = wfarmalloc ( nbytes, NULL );
  229.  
  230.     if ( ptr )
  231.         {
  232.         hptr-> whp_ram  = ptr;
  233.         retcode = 0;
  234.         }
  235.     else
  236.          {
  237.         retcode = 1;
  238.         }
  239.  
  240.     return (retcode);    /* ram_alloc */
  241.     }
  242.  
  243.  
  244.  
  245.  
  246.  
  247.  
  248.  
  249.  
  250.  
  251.     /*----------- integrated (whole heap) routines -------------*/
  252.  
  253.  
  254.  
  255.     /* note that wheap-init is called before other windows routines,
  256.      * so it must not call window routines outside this module...
  257.      */
  258. void     wheap_init ( void )
  259.     {
  260.  
  261.     #ifndef __TURBOC__
  262.         /* Microsoft C is unable to initialize the double linked
  263.          * list properly at compile-time,
  264.          * so it has to be done at run-time
  265.          */
  266.         heap_top.whp_prev = &heap_bottom;
  267.         heap_top.whp_dsklo = &heap_bottom;
  268.  
  269.     #endif  /* Microsoft */
  270.  
  271.     /* initialize expanded memory */
  272.     /* removed from smaller version */
  273.     
  274.     
  275.     
  276.     /* initilize disk file for I/O, acquire 64k buffer */
  277.     /* removed from smaller version */
  278.  
  279.  
  280.     return;        /* wheap_init */
  281.     }
  282.  
  283.  
  284. WHEAP    *wheap_alloc ( size_t nbytes,  unsigned char priority, char *errmsg)
  285.     {
  286.     WHEAP *hptr;
  287.     int   need;
  288.     int   low_priority =1;
  289.  
  290.     /* 80 byte errmsg, 31 bytes used, 39 left for caller
  291.      */
  292.     #define MSG_OFFSET 30
  293.     #define MSG_REMAIN 50
  294.  
  295.  
  296.     char msgbuff[81];
  297.     strcpy ( msgbuff, "Out of heap memory, call from  " );
  298.  
  299.     hptr = wmalloc ( sizeof (WHEAP), "WHEAP" );
  300.  
  301.     memset ( hptr, 0, sizeof (WHEAP) );
  302.  
  303.  
  304.     if ( nbytes > WHEAP_MAX || nbytes == 0 )
  305.         {
  306.         werror ('W', "heap request too large");
  307.         }
  308.  
  309.     /* double linked list
  310.      */
  311.     hptr-> whp_nb       = nbytes;
  312.     hptr-> whp_priority = priority;
  313.  
  314.     hptr-> whp_next        = &heap_top;
  315.     hptr-> whp_prev     = heap_top.whp_prev;
  316.  
  317.     (heap_top.whp_prev)->whp_next    = hptr;
  318.     (heap_top.whp_prev)              = hptr;
  319.  
  320.  
  321.  
  322.  
  323.     need =  ram_alloc ( hptr );
  324.     hptr->  whp_flag = WHP_RAM;
  325.  
  326.  
  327.  
  328.     if ( need && errmsg )
  329.         {
  330.         memcpy(msgbuff+MSG_OFFSET, errmsg, MSG_REMAIN);
  331.         msgbuff[sizeof(msgbuff)-1] = 0;
  332.  
  333.         werror ( 'W', msgbuff );
  334.         }
  335.  
  336.  
  337.     return ( hptr );    /* wheap_alloc */
  338.     }
  339.  
  340.  
  341.  
  342.  
  343. void far     *wheap_access   ( WHEAP *hptr,  int readwrite )
  344.     {
  345.  
  346.     void far *ptr;
  347.  
  348.     if ( current_access )
  349.         {
  350.         wheap_deaccess ( current_access, 0 );
  351.         }
  352.  
  353.  
  354.  
  355.     ptr = hptr -> whp_ram;
  356.  
  357.     current_access = hptr;
  358.  
  359.  
  360.     return ( ptr );    /* wheap_access */
  361.     }
  362.  
  363.  
  364.  
  365. void          wheap_deaccess ( WHEAP *hptr,  int readwrite )
  366.     {
  367.  
  368.  
  369.     current_access = NULL;
  370.  
  371.     return;        /* wheap_deaccess */
  372.     }
  373.  
  374.  
  375. /* unchain_heap() - remove WHEAP object from linked list
  376.  *    and free memory used to store WHEAP item.
  377.  *
  378.  */
  379. static void  NEAR_CALL unchain_heap ( WHEAP *hptr )
  380.     {
  381.     WHEAP   *pr, *nx;
  382.  
  383.     pr = hptr-> whp_prev;
  384.     nx = hptr-> whp_next;
  385.  
  386.     pr-> whp_next = nx;
  387.     nx-> whp_prev = pr;
  388.  
  389.  
  390.     free ( hptr );
  391.  
  392.     return;        /* unchain_heap */
  393.     }
  394.  
  395.  
  396.  
  397.  
  398.  
  399. void         wheap_free  ( WHEAP *hptr )
  400.     {
  401.  
  402.  
  403.     if ( current_access )
  404.         {
  405.         wheap_deaccess ( current_access, 0 );
  406.         }
  407.  
  408.  
  409.  
  410.         farfree ( hptr-> whp_ram );
  411.  
  412.  
  413.     unchain_heap ( hptr );
  414.  
  415.     return;        /* wheap_free */
  416.     }
  417.  
  418.  
  419.  
  420. unsigned long     wheap_avail    ( void )
  421.     {
  422.  
  423.     return ( wheap_ramlimit );   /* wheap_avail */
  424.     }
  425.  
  426.  
  427.  
  428. unsigned long     wheap_availxms ( void )
  429.     {
  430.  
  431.     return (0);                /* wheap_availxms */
  432.     }
  433.  
  434.  
  435.  
  436.  
  437. void         wheap_swap2dsk ( WHEAP *hptr )
  438.     {
  439.  
  440.     return;        /* wheap_swap2dsk */
  441.     }
  442.  
  443.  
  444. /* swap all WHEAP blocks of given priority to disk
  445.  */
  446. void         wheap_swapall2dsk ( int priority )
  447.     {
  448.     return;        /* wheap_swapall2dsk */
  449.     }
  450.  
  451.  
  452.  
  453.  
  454.  
  455.  
  456. void far     *wheap_unlink ( WHEAP *hptr )
  457.     {
  458.     void far *ptr;
  459.  
  460.     size_t    numbytes;
  461.  
  462.  
  463.     wheap_access ( hptr, 1 );
  464.  
  465.     numbytes = hptr-> whp_nb;
  466.  
  467.     ptr = hptr->whp_ram;
  468.  
  469.  
  470.     /* now take item hptr out of the heap lists
  471.      */
  472.     unchain_heap ( hptr );
  473.  
  474.  
  475.     return (ptr);    /* wheap_unlink */
  476.     }
  477.  
  478.  
  479.  
  480.  
  481.  
  482.  
  483. void         wheap_freeall ( void )
  484.     {
  485.     WHEAP *hptr, *pending;
  486.  
  487.  
  488.  
  489.     /* point to first allocated one
  490.      */
  491.     hptr = heap_bottom.whp_next;
  492.  
  493.  
  494.  
  495.     /* run up chain, removing elelments one at a time
  496.      */
  497.     while ( &heap_top != hptr )
  498.         {
  499.  
  500.         pending  = hptr-> whp_next;
  501.  
  502.         wheap_free ( hptr );
  503.  
  504.         hptr = pending;
  505.  
  506.         }    /* end while */
  507.  
  508.  
  509.     return;        /* wheap_freeall */
  510.     }
  511.  
  512.  
  513.  
  514.  
  515.     /*------------------- end of HEAPDBG.C -------------------- */
  516.  
  517.  
  518.