home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mmpm21tk.zip / TK / FSSHT / HHPHEAP.C < prev    next >
C/C++ Source or Header  |  1993-03-07  |  28KB  |  838 lines

  1. /*static char *SCCSID = "@(#)hhpheap.c  13.2 92/04/30";*/
  2. #pragma title ("HHPHEAP.C - Dynamic Memory Management")
  3.  
  4. /************************ START OF SPECIFICATIONS ***************************/
  5. /*                                                                          */
  6. /* SOURCE FILE NAME:  HHPHEAP.C                                             */
  7. /*                                                                          */
  8. /* DESCRIPTIVE NAME: HHP Memory Management                                  */
  9. /*                                                                          */
  10. /* COPYRIGHT:                                                               */
  11. /*                   Copyright (c) IBM Corporation 1991, 1992               */
  12. /*                          All Rights Reserved                             */
  13. /*                                                                          */
  14. /* STATUS: OS/2 MM Release 1.00                                             */
  15. /*                                                                          */
  16. /* FUNCTION: Memory Management                                              */
  17. /*                                                                          */
  18. /* NOTES:                                                                   */
  19. /*    RESTRICTIONS: Runs in 32 bit protect mode (OS/2 2.0)                  */
  20. /*                                                                          */
  21. /*    This is a Heap Manager that can manage heaps larger than 64K.  It     */
  22. /*    can grow and shrink dynamically.  It is intended to hide some of the  */
  23. /*    memory management differences between 16-bit and 32-bit.              */
  24. /*                                                                          */
  25. /* ENTRY POINTS:                                                            */
  26. /*                                                                          */
  27. /*   ROUTINES: HhpCreateHeap                                                */
  28. /*             HhpAllocMem                                                  */
  29. /*             HhpFreeMem                                                   */
  30. /*             HhpDestroyHeap                                               */
  31. /*             HhpAccessHeap                                                */
  32. /*             HhpReleaseHeap                                               */
  33. /*             HhpAllocBuffer                                               */
  34. /*             HhpFreeBuffer                                                */
  35. /*             HhpAccessBuffer                                              */
  36. /*             HhpGetPID                                                    */
  37. /*                                                                          */
  38. /* EXTERNAL REFERENCES:                                                     */
  39. /*                                                                          */
  40. /* REVISIONS:                                                               */
  41. /*   04/30/92   DMD       Change PID_MAX to 50 from 20                      */
  42. /*                                                                          */
  43. /*************************** END OF SPECIFICATIONS **************************/
  44.  
  45. /*
  46.  *  Include files
  47.  */
  48.  
  49. #define INCL_BASE           // include BASE OS/2 defines
  50. #define INCL_NOPMAPI        // leave out the PM stuff
  51. #include <os2.h>            // all-inclusive OS/2 include file
  52. #include <string.h>         //dwk
  53. #include <stdlib.h>         //dwk
  54.  
  55. #include <hhpheap.h>        // External function prototypes
  56.  
  57.  
  58. /*
  59.  *  DLL global data
  60.  */
  61.  
  62. #define PID_MAX    50
  63.  
  64. #define SEG_NONSHARED       0x0000    //dwk
  65. #define SEG_GIVEABLE        0x0001    //dwk
  66. #define SEG_GETTABLE        0x0002    //dwk
  67.  
  68. /*
  69.  *  Local Symbols
  70.  */
  71.  
  72. #define HEAP_MAGIC     0x55
  73.  
  74. typedef struct _PIDINFO {       /* pidi */  //dwk
  75.     PID     pid;                            //dwk
  76.     TID     tid;                            //dwk
  77.     PID     pidParent;                      //dwk
  78. } PIDINFO;                                  //dwk
  79.  
  80. typedef struct _HBLOCK {                   /* should be dword multiple */
  81.    struct _HBLOCK FAR * pNext;             /* Next Heap Descriptor */
  82.    struct _HBLOCK FAR * pPrev;             /* Prev Heap Descriptor */
  83.    ULONG   lBlockSize;                     /* Block Size */
  84.    UCHAR   fAlloc;                         /* Block Alloced */
  85.    UCHAR   magic;                          /* Used for Magic Number */
  86. #ifdef MMDEBUG
  87.    CHAR    szFile[15];
  88.    USHORT  uLine;
  89. #endif
  90. } BLOCK;
  91. typedef BLOCK FAR  * PBLOCK;
  92.  
  93.  
  94. typedef struct _HHEAP {
  95.    struct _HHEAP FAR * pNext;              /* Next Heap */
  96.    PPID     ppidList;                      /* Pointer to pid List */
  97.    PBLOCK   pBlock;                        /* Heap Block List */
  98.    USHORT   uAllocCnt;                     /* Allocated Block Cnt */
  99.    ULONG    lSize;                         /* Segment Size */
  100.    USHORT   fFlags;                        /* Flags */
  101.    BLOCK    Block;                         /* first Block */
  102. } HEAP;
  103. typedef HEAP FAR * PHEAP;
  104.  
  105. /**********************************************************************\
  106.  *  Local functions                                                   *
  107. \**********************************************************************/
  108.  
  109. BOOL   LocateFreeMem (PHEAP pFirstHeap,
  110.                       PHEAP FAR * ppHeap,
  111.                       PBLOCK FAR * ppBlock,
  112.                       ULONG cbLen);
  113. USHORT CollapseFreeBlock (PBLOCK pBlock);
  114. USHORT CollapseFreeHeap (PHEAP pFirstHeap, PHEAP pHeap);
  115.  
  116. #ifndef INCL_32
  117. /* Reallocation of a segment is used to grow a heap in 16-bit OS/2 */
  118. BOOL   ReallocHeap (PHEAP pFirstHeap,
  119.                     PHEAP FAR * ppHeap,
  120.                     PBLOCK FAR * ppBlock,
  121.                     ULONG lSize);
  122. #endif
  123.  
  124. USHORT AddPid (PHEAP pFirstHeap, PID pid, PHEAP pNewHeap);
  125. PHEAP NewHeap (PHEAP pFirstHeap, ULONG lInitSize, USHORT fFlags);
  126.  
  127. /**********************************************************************\
  128.  * HhpCreateHeap
  129.  *
  130.  * Create the First Heap
  131.  *
  132.  * History:
  133. \**********************************************************************/
  134. HHUGEHEAP APIENTRY HhpCreateHeap (ULONG lInitSize, USHORT fFlags)
  135. {
  136.    return ((HHUGEHEAP)NewHeap (NULL, lInitSize, fFlags));
  137. }
  138.  
  139.  
  140. /**********************************************************************\
  141.  * NewHeap
  142.  *
  143.  * Create a New Heap (one segment)
  144.  *
  145.  * History:
  146. \**********************************************************************/
  147. PHEAP NewHeap (PHEAP pFirstHeap, ULONG lInitSize, USHORT fFlags)
  148. {
  149.    PHEAP  pHeap;
  150.    PHEAP  pLastHeap;
  151.  
  152.    /******************************************************************/
  153.    /* Allocate a Segment or block of memory into which to build heap */
  154.    /******************************************************************/
  155.  
  156.    pHeap = (PHEAP) HhpAllocBuffer (lInitSize, fFlags);   /* Alloc Memory for Heap */
  157.    if (!pHeap) return (NULL);
  158.  
  159.    /*
  160.     * Zero the heap here.  This is more efficient than zeroing when
  161.     * each piece is allocated.
  162.     */
  163.  
  164. //   memset( pHeap, '\0', (ULONG)lInitSize );
  165.  
  166.    /*****************************************************************/
  167.    /* Setup Heap Structures                                         */
  168.    /*****************************************************************/
  169.    pHeap->pNext = 0;                            /* Last in List */
  170.    pHeap->pBlock = &pHeap->Block;               /* Point to first block */
  171.    pHeap->uAllocCnt = 0;                        /* Number of Allocated Blocks */
  172.    pHeap->lSize = lInitSize;                    /* Size of Segment */
  173.    pHeap->fFlags = fFlags;                      /* Heap Flags */
  174.    pHeap->ppidList = NULL;                      /* No Pid List */
  175.  
  176.    pHeap->pBlock->pNext = NULL;                 /* Only one block */
  177.    pHeap->pBlock->pPrev = NULL;                 /* No back pointer */
  178.    pHeap->pBlock->lBlockSize = (lInitSize - (ULONG) sizeof(HEAP));  /* Init Block Size */
  179.    pHeap->pBlock->fAlloc = FALSE;               /* Free */
  180.    pHeap->pBlock->magic = HEAP_MAGIC;           /* Initialize reserved word */
  181.  
  182.    /******************************************************************/
  183.    /* Chain Heaps                                                    */
  184.    /******************************************************************/
  185.    if (pFirstHeap) {
  186.       for (pLastHeap=pFirstHeap; pLastHeap->pNext; pLastHeap=pLastHeap->pNext);
  187.       pLastHeap->pNext = pHeap;
  188.    }
  189.  
  190.    /******************************************************************/
  191.    /* Create PID List or Give new Heap to all who Accessed Heap      */
  192.    /******************************************************************/
  193.  
  194.    if (!pFirstHeap && pHeap->fFlags & HH_SHARED)
  195.       {
  196.       pHeap->ppidList = HhpIAllocMem ((HHUGEHEAP)pHeap, sizeof(PID)*PID_MAX);
  197.  
  198.       /*
  199.        * Don't Give to anyone.
  200.        */
  201.  
  202.       if (AddPid( pHeap, HhpGetPID(), NULL ))
  203.          return (NULL);
  204.       }
  205.    else if (pHeap->fFlags & HH_SHARED)
  206.       {
  207.  
  208.       /*
  209.        * Give This Heap to Others.
  210.        */
  211.  
  212.       if (AddPid( pFirstHeap, HhpGetPID(), pHeap ))
  213.          return (NULL);
  214.       }
  215.  
  216.    return (pHeap);                              /* return heap pointer */
  217.  
  218. }
  219.  
  220. /**********************************************************************\
  221.  * HhpIAllocMem
  222.  *
  223.  * Allocate some memory
  224.  *
  225.  * History:
  226. \**********************************************************************/
  227.  
  228. PVOID APIENTRY HhpIAllocMem (HHUGEHEAP hheap, ULONG cbLen)
  229. {
  230.    PBLOCK pBlock;
  231.    PHEAP  pHeap;
  232.    PBLOCK pBlockNew;
  233.    PBLOCK pBlockNext;
  234.    BOOL   fAlloc;
  235.    ULONG  lNewBlockSize;
  236.    PHEAP  pFirstHeap = (PHEAP)hheap;
  237.    PCHAR  pData = NULL;
  238.  
  239.    if (!hheap) return (NULL);                   /* Bad handle */
  240.  
  241.    fAlloc = LocateFreeMem (pFirstHeap, &pHeap, &pBlock, cbLen); /* Locate a free Block */
  242.  
  243.    if (fAlloc)
  244.       {
  245.  
  246.       /* Allocate the first cbLen bytes of Block */
  247.  
  248.       if (pBlock->lBlockSize - cbLen <= sizeof(BLOCK))
  249.          {
  250.          cbLen = pBlock->lBlockSize;          /* Round up the Request Size */
  251.          }
  252.  
  253.       lNewBlockSize = pBlock->lBlockSize - cbLen;  /* New block size */
  254.       pBlockNew = (PBLOCK)((PCHAR)pBlock + sizeof(BLOCK) + cbLen); /* New Block */
  255.  
  256.       pBlock->lBlockSize = cbLen;            /* Data space of the block */
  257.       pBlock->fAlloc = TRUE;                 /* Allocated Block */
  258.       pHeap->uAllocCnt++;                    /* Alloc'ed block count */
  259.       pBlock->magic = HEAP_MAGIC;            /* Should already be there */
  260.  
  261.       if (lNewBlockSize)
  262.          {
  263.  
  264.          /*
  265.           * Create a Free Block for Fragment.
  266.           * Point to next block.
  267.           */
  268.  
  269.          pBlockNext = pBlock->pNext;
  270.          pBlock->pNext = pBlockNew;
  271.          pBlockNew->pNext = pBlockNext;
  272.          if (pBlockNext) pBlockNext->pPrev = pBlockNew;
  273.          pBlockNew->pPrev = pBlock;
  274.  
  275.          pBlockNew->lBlockSize = lNewBlockSize - (ULONG) sizeof(BLOCK);
  276.          pBlockNew->fAlloc = FALSE;
  277.          pBlockNew->magic = HEAP_MAGIC;
  278.          }
  279.  
  280.       /*
  281.        * Note:  No need to zero memory.  It is now done on heap creation and
  282.        * freemem.
  283.        * WRONG...  Backed out...
  284.        * Zero now, fix actual bug later... It seems block control information
  285.        * is not being zeroed on a free.
  286.        */
  287.  
  288.       pData = (PCHAR)pBlock + (USHORT)sizeof(BLOCK);     /* Get Pointer */
  289.       memset( pData, '\0', (ULONG)cbLen );
  290.       }
  291.  
  292.    return (pData);                                    /* return pointer */
  293. }
  294.  
  295. /**********************************************************************\
  296.  * LocateFreeMem
  297.  *
  298.  * Locate a Free Block of Memory
  299.  *
  300.  * History:
  301. \**********************************************************************/
  302. BOOL LocateFreeMem (PHEAP pFirstHeap,
  303.                     PHEAP FAR * ppHeap,
  304.                     PBLOCK FAR * ppBlock,
  305.                     ULONG cbLen)
  306. {
  307.    PBLOCK pBlock;                            /* block pointer */
  308.    PHEAP  pHeap;                             /* heap pointer */
  309.    ULONG  lSize;                             /* New Heap Size */
  310.  
  311.    /*****************************************************************/
  312.    /* Locate an existing Block by searching list.  Since this is a  */
  313.    /* huge heap, performance can be improved by saving the last     */
  314.    /* searched node (speed) or a best-fit algorithm (overall size)  */
  315.    /*****************************************************************/
  316.  
  317.    for (pHeap = pFirstHeap; pHeap; pHeap = pHeap->pNext) {
  318.       for (pBlock = pHeap->pBlock; pBlock; pBlock = pBlock->pNext) {
  319.            /* Is there an existing free block that is big enough */
  320.            if (!pBlock->fAlloc && pBlock->lBlockSize >= cbLen) {
  321.               *ppHeap = pHeap;
  322.               *ppBlock = pBlock;
  323.               return (TRUE);
  324.            }
  325.       }
  326.    }
  327.  
  328.    /*******************************************************************/
  329.    /* Try Reallocing an Existing Heap to make room                    */
  330.    /*******************************************************************/
  331.    lSize = ((ULONG)cbLen+(ULONG)sizeof(HEAP)+
  332.             (ULONG)sizeof(BLOCK)+0xfffL) & 0xfffff000L; /* Round to 4K */
  333.  
  334. #ifndef INCL_32
  335.    if (ReallocHeap (pFirstHeap, ppHeap, ppBlock, lSize)) {
  336.       return (TRUE);
  337.    }
  338. #endif
  339.  
  340.    /********************************************************************/
  341.    /* Create a New Heap                                                */
  342.    /********************************************************************/
  343.    *ppHeap = NewHeap (pFirstHeap, lSize, pFirstHeap->fFlags);
  344.    if (!*ppHeap) return (FALSE);                        /* No More Mem */
  345.  
  346.    *ppBlock = (*ppHeap)->pBlock;                        /* First Block Free */
  347.  
  348.    return (TRUE);
  349.  
  350. }
  351.  
  352. /*********************************************************************\
  353.  * HhpFreeMem
  354.  *
  355.  * Free Memory
  356.  *
  357.  * History:
  358. \**********************************************************************/
  359. BOOL APIENTRY HhpFreeMem (HHUGEHEAP hheap, PVOID pData)
  360. {
  361.    PHEAP  pHeap;
  362.    PBLOCK pBlock;
  363.    PHEAP pFirstHeap = (PHEAP)hheap;
  364.  
  365.    /*****************************************************************/
  366.    /* Validate the heap handle and the data pointer                 */
  367.    /*****************************************************************/
  368.  
  369.    if (!hheap) return (TRUE);                         /* Bad handle */
  370.  
  371.    pBlock = (PBLOCK)((PCHAR)pData - sizeof(BLOCK));   /* get Block Pointer */
  372.    if (pBlock->magic != HEAP_MAGIC) return (TRUE);    /* Can't Free anything */
  373.    if (!pBlock->fAlloc) return (TRUE);
  374.  
  375.    /* Determine if the data is in the specified heap */
  376.  
  377.    for (pHeap = pFirstHeap; pHeap; pHeap = pHeap->pNext) {
  378.       if ((PCHAR)pData >= (PCHAR)pHeap->pBlock &&
  379.           (PCHAR)pData < ((PCHAR)pHeap + pHeap->lSize)) break;
  380.    }
  381.  
  382.    /********************************************************************/
  383.    /* Free the Block                                                   */
  384.    /********************************************************************/
  385.  
  386.    if (pHeap)
  387.       {
  388.       memset( pData, '\0', pBlock->lBlockSize );
  389.  
  390.       pBlock->fAlloc = FALSE;                   /* Free Block */
  391.       pHeap->uAllocCnt--;                       /* Decrement Alloc Block Cnt */
  392.       CollapseFreeBlock (pBlock);               /* Collect Garbage */
  393.  
  394.    /*******************************************/
  395.    /*  Brad Noe 3/7/93                        */
  396.    /*                                         */
  397.    /*  Commented out because it seems to cause*/
  398.    /*  problems in multi-process case         */
  399.    /*  Need to investigate and fix            */
  400.    /*******************************************/
  401. //    CollapseFreeHeap  (pFirstHeap, pHeap);    /* Collect Garbage */
  402.       }
  403.  
  404.    return (FALSE);
  405.  
  406. }
  407.  
  408. /************************************************************************\
  409.  * CollapseFreeBlock
  410.  *
  411.  *
  412.  * History:
  413. \************************************************************************/
  414. USHORT CollapseFreeBlock (PBLOCK pBlock)
  415. {
  416.    register PBLOCK pPrevBlock;
  417.    register PBLOCK pNextBlock;
  418.  
  419.    if (pBlock->fAlloc) return (FALSE);          /* This block is allocated */
  420.  
  421.    pPrevBlock = pBlock->pPrev;
  422.    pNextBlock = pBlock->pNext;
  423.  
  424.    if (pNextBlock && !pNextBlock->fAlloc) {     /* Next Block */
  425.       pBlock->pNext = pNextBlock->pNext;
  426.       if (pNextBlock->pNext) pNextBlock->pNext->pPrev = pBlock;
  427.       pBlock->lBlockSize += sizeof(BLOCK) + pNextBlock->lBlockSize;
  428.    }
  429.  
  430.    if (pPrevBlock && !pPrevBlock->fAlloc) {    /* Prev Block */
  431.       pPrevBlock->pNext = pBlock->pNext;
  432.       if (pBlock->pNext) pBlock->pNext->pPrev = pPrevBlock;
  433.       pPrevBlock->lBlockSize += sizeof(BLOCK) + pBlock->lBlockSize;
  434.    }
  435.  
  436.    return (FALSE);
  437.  
  438. }
  439.  
  440. /************************************************************************\
  441.  * CollapseFreeHeap
  442.  *
  443.  *
  444.  * History:
  445. \************************************************************************/
  446. USHORT CollapseFreeHeap (PHEAP pFirstHeap, PHEAP pHeap)
  447. {
  448.    register PHEAP pTempHeap;
  449.  
  450.    if (pFirstHeap == pHeap) return (FALSE);     /* Never Free First Heap */
  451.  
  452.    if (pHeap->uAllocCnt) return (FALSE);        /* Allocated Blocks */
  453.  
  454.    for (pTempHeap = pFirstHeap; pTempHeap->pNext != pHeap;
  455.         pTempHeap = pTempHeap->pNext);          /* Locate Previous Heap */
  456.  
  457.    pTempHeap->pNext = pHeap->pNext;             /* Take out of List */
  458.  
  459.    HhpFreeBuffer ((PBYTE)pHeap);            /* Free Segment */
  460.  
  461.    return (FALSE);
  462.  
  463. }
  464.  
  465. /**********************************************************************\
  466.  * HhpDestroyHeap
  467.  *
  468.  *
  469. \**********************************************************************/
  470. BOOL APIENTRY HhpDestroyHeap (HHUGEHEAP hheap)
  471. {
  472.    PHEAP pHeap;
  473.    PHEAP pFirstHeap = (PHEAP) hheap;
  474.    PSZ   pszTemp;
  475.  
  476. #ifdef MMDEBUG
  477.        if (!DosScanEnv(MM_HEAP_DEBUG_VAR, &pszTemp))
  478.          HhpDumpHeap(hheap);
  479. #endif
  480.  
  481.    while (pFirstHeap) {                   /* Free All Segments Of Heap */
  482.       pHeap = pFirstHeap;
  483.       pFirstHeap = pFirstHeap->pNext;
  484.       HhpFreeBuffer ((PBYTE)pHeap);
  485.    }
  486.  
  487.    return (FALSE);
  488.  
  489. }
  490.  
  491. /***********************************************************************\
  492.  * HhpAllocBuffer  (Call DosAllocSeg or DosAllocMem)
  493.  *
  494.  * History:
  495. \***********************************************************************/
  496. PBYTE APIENTRY HhpAllocBuffer (ULONG lSize, USHORT fFlags)
  497. {
  498.    USHORT rc;
  499.    USHORT fMem;
  500.  
  501. #ifndef INCL_32
  502.    SEL sel;
  503.  
  504.    if (fFlags & HH_SHARED) {
  505.       fMem = SEG_GIVEABLE | SEG_GETTABLE;
  506.    } else {
  507.       fMem = SEG_NONSHARED;
  508.    }
  509.  
  510.    if (lSize > 0xffffL) return (NULL);              /* Limit to 64K-1 */
  511.  
  512.    rc = DosAllocSeg ((USHORT)lSize, &sel, fMem);    /* Allocate Heap Seg */
  513.    if (rc) return (NULL);
  514.    return (MAKEP(sel, 0));
  515.  
  516. #else
  517.  
  518.    PBYTE pBuffer;
  519.  
  520.    /*
  521.     * Allocate private or shared memory.
  522.     */
  523.  
  524.    if (fFlags & HH_SHARED)
  525.       {
  526.       fMem = fALLOCSHR & ~PAG_EXECUTE;
  527.  
  528.       rc = (USHORT) DosAllocSharedMem( (PPVOID)&pBuffer,
  529.                                        NULL,
  530.                                        (ULONG)lSize,
  531.                                        (ULONG)fMem );
  532.       }
  533.    else
  534.       {
  535.       fMem = fALLOC & ~PAG_EXECUTE;
  536.  
  537.       rc = (USHORT) DosAllocMem( (PPVOID)&pBuffer,
  538.                                  (ULONG)lSize,
  539.                                  (ULONG)fMem );
  540.       }
  541.  
  542.    if (rc) return (NULL);
  543.    return (pBuffer);
  544.  
  545. #endif
  546.  
  547. }
  548.  
  549. /***********************************************************************\
  550.  * HhpFreeBuffer    (Call DosFreeSeg or DosFreeMem)
  551.  *
  552.  *
  553.  * History
  554. \***********************************************************************/
  555. USHORT APIENTRY HhpFreeBuffer (PBYTE pBuffer)
  556. {
  557. #ifndef INCL_32
  558.    return (DosFreeSeg (SELECTOROF(pBuffer)));
  559. #else
  560.    return ((USHORT) DosFreeMem ((PVOID)pBuffer));
  561. #endif
  562. }
  563.  
  564. /**********************************************************************\
  565.  * HhpAccessBuffer
  566.  *
  567.  *
  568.  *
  569. \**********************************************************************/
  570. USHORT APIENTRY HhpAccessBuffer (PBYTE pBuffer)
  571. {
  572. #ifndef INCL_32
  573.     if (DosGetSeg (SELECTOROF(pBuffer))) return (TRUE);
  574. #else
  575.     if (DosGetSharedMem (pBuffer, fPERM)) return (TRUE);
  576. #endif
  577.     return (FALSE);
  578. }
  579.  
  580. /**********************************************************************\
  581.  * HhpAccessHeap        (Access a shared Heap)
  582.  *
  583.  *
  584.  * History:
  585. \**********************************************************************/
  586.  
  587. USHORT APIENTRY HhpAccessHeap( HHUGEHEAP hheap, PID pid )
  588. {
  589.    PHEAP pFirstHeap = (PHEAP) hheap;
  590.    PHEAP pHeap;
  591.  
  592.    if (!hheap) return (TRUE);
  593.  
  594.    /*********************************************************************/
  595.    /* Get Access to All Existing Segments/Pages in the Heap             */
  596.    /*********************************************************************/
  597.  
  598.    for (pHeap = pFirstHeap; pHeap; pHeap = pHeap->pNext) { /* Access All Segments Of Heap */
  599.       if (HhpAccessBuffer ((PVOID)pHeap)) return (TRUE);
  600.    }
  601.  
  602.    /********************************************************************/
  603.    /* Put New Pid Into Pid List                                        */
  604.    /********************************************************************/
  605.  
  606.    if (pFirstHeap->fFlags & HH_SHARED)
  607.       {
  608.       if (AddPid( pFirstHeap, pid, NULL ))
  609.          return (TRUE);
  610.       }
  611.  
  612.    return (FALSE);
  613.  
  614. }
  615.  
  616. /**********************************************************************\
  617.  * HhpReleaseHeap
  618.  *
  619.  * History:
  620. \**********************************************************************/
  621. USHORT APIENTRY HhpReleaseHeap (HHUGEHEAP hheap, PID pid)
  622. {
  623.    PHEAP pHeap = (PHEAP) hheap;
  624.    USHORT i;
  625.  
  626.    if (!(pHeap->fFlags & HH_SHARED)) return (FALSE);
  627.  
  628.    if (!pHeap->ppidList) return (FALSE);
  629.  
  630.    /* Remove Pid from List */
  631.    for (i=0; i<PID_MAX && pHeap->ppidList[i] != pid; i++);   /* Locate Slot */
  632.  
  633.    if (i < PID_MAX)
  634.       pHeap->ppidList[i] = (ULONG)NULL;
  635.  
  636.    return ((USHORT)NULL);
  637.  
  638. }
  639.  
  640. /*************************************************************************\
  641.  * AddPid
  642.  *
  643.  *
  644. \*************************************************************************/
  645. USHORT AddPid (PHEAP pFirstHeap, PID pid, PHEAP pNewHeap)
  646. {
  647.    USHORT i;
  648.  
  649.    /* Save the Pid in the PidList of the First Heap only */
  650.  
  651.    for (i=0; i<PID_MAX && pFirstHeap->ppidList[i] != pid; i++); /* Existing */
  652.    if (i == PID_MAX) {
  653.       for (i=0; i<PID_MAX && pFirstHeap->ppidList[i] != 0; i++);/* Locate Slot */
  654.       if (i == PID_MAX) return (TRUE);                     /* No Access */
  655.       pFirstHeap->ppidList[i] = pid;                       /* store pid */
  656.    }
  657.  
  658.    /* Give the New Memory Block to all who have accessed this heap */
  659.  
  660.    if (pNewHeap && pNewHeap != pFirstHeap) {      /* Give Seg to All Pids */
  661.       for (i=0; i<PID_MAX; i++) {
  662.          if (pFirstHeap->ppidList[i] != 0) {
  663. #ifndef INCL_32
  664.             SEL selNew;
  665.             DosGiveSeg (SELECTOROF(pNewHeap), pFirstHeap->ppidList[i], &selNew);
  666. #else
  667.             DosGiveSharedMem (pNewHeap, pFirstHeap->ppidList[i], fGIVESHR);
  668. #endif
  669.          }
  670.       }
  671.    }
  672.  
  673.    return (FALSE);
  674.  
  675. }
  676.  
  677. #ifndef INCL_32
  678. /**********************************************************************\
  679.  * ReallocHeap
  680.  *
  681.  *
  682.  * History
  683. \**********************************************************************/
  684. BOOL ReallocHeap (PHEAP pFirstHeap,
  685.                   PHEAP FAR * ppHeap,
  686.                   PBLOCK FAR * ppBlock,
  687.                   ULONG lSize)
  688. {
  689.    USHORT rc;
  690.    PHEAP  pHeap;
  691.    PBLOCK pBlock;
  692.    PBLOCK pNextBlock;
  693.  
  694.    for (pHeap = pFirstHeap; pHeap; pHeap = pHeap->pNext) {
  695.  
  696.       if ((LONG)0xffffL - (LONG)pHeap->lSize >= (LONG)lSize) { /* ReSize segment */
  697.          /* Only Supported with 64K Segments */
  698.          rc = DosReallocSeg ((USHORT)(pHeap->lSize+lSize), SELECTOROF(pHeap));
  699.          if (rc) return (FALSE);                    /* No Memory */
  700.  
  701.          pHeap->lSize += lSize;                     /* Increase Heap Size */
  702.  
  703.          for (pBlock = pHeap->pBlock; pBlock->pNext; pBlock = pBlock->pNext); /* Last */
  704.          if (pBlock->fAlloc) {                     /* Last Block Allocated */
  705.             pNextBlock = (PBLOCK)((PCHAR)pBlock + sizeof(BLOCK) + pBlock->lBlockSize);
  706.             pNextBlock->pPrev = pBlock;
  707.             pNextBlock->pNext = NULL;
  708.             pBlock->pNext = pNextBlock;
  709.             pNextBlock->lBlockSize = (lSize - (ULONG)sizeof(BLOCK));
  710.             pNextBlock->magic = HEAP_MAGIC;
  711.             pNextBlock->fAlloc = FALSE;
  712.             pBlock = pNextBlock;
  713.          } else {
  714.             pBlock->lBlockSize += lSize;
  715.          }
  716.          *ppHeap = pHeap;
  717.          *ppBlock = pBlock;
  718.          return (TRUE);                            /* success */
  719.  
  720.       }
  721.  
  722.    }
  723.    return (FALSE);
  724.  
  725. }
  726.  
  727. #endif
  728.  
  729. /*************************************************************************\
  730.  * HhpGetPID
  731.  *
  732.  *
  733. \*************************************************************************/
  734. PID APIENTRY HhpGetPID (VOID)
  735. {
  736.    USHORT rc;
  737.  
  738. #ifndef INCL_32
  739.  
  740.    PIDINFO pInfo;
  741.  
  742.    rc = DosGetPID (&pInfo);                  /* Get Pid Info */
  743.    if (rc) return ((PID)NULL);               /* Bad News */
  744.  
  745.    return (pInfo.pid);                       /* Return Current PID */
  746.  
  747. #else
  748.  
  749.    PPIB ppib;
  750.    PTIB ptib;
  751.  
  752.    rc = (USHORT) DosGetInfoBlocks (&ptib, &ppib);  /* Get Info Blocks */
  753.    if (rc) return ((PID)NULL);
  754.  
  755.    return (ppib->pib_ulpid);                 /* return PID */
  756.  
  757. #endif
  758.  
  759. }
  760.  
  761.  
  762. // Trace the file and line number for allocated blocks
  763.  
  764. PVOID APIENTRY HhpTAllocMem (HHUGEHEAP hHeap, ULONG cbLen, PSZ pszFile, ULONG uLine)
  765. {
  766.    PBLOCK pBlock;
  767.    PVOID  pData;
  768.  
  769.    pszFile; uLine; pBlock;
  770.  
  771.    pData = (PVOID) HhpIAllocMem (hHeap, cbLen);
  772.  
  773. #ifdef MMDEBUG
  774.    if (pData)
  775.    {
  776.      if (pszFile == NULL)
  777.      {
  778.        pBlock = (PBLOCK)((PCHAR)pData - sizeof(BLOCK));   /* get Block Pointer */
  779.        strncpy (pBlock->szFile, "Retail", 14);
  780.        pBlock->szFile[14] = 0;
  781.        pBlock->uLine = 0;
  782.      }
  783.      else
  784.      {
  785.        pBlock = (PBLOCK)((PCHAR)pData - sizeof(BLOCK));   /* get Block Pointer */
  786.        strncpy (pBlock->szFile, pszFile, 14);
  787.        pBlock->szFile[14] = 0;
  788.        pBlock->uLine = uLine;
  789.      }
  790.    }
  791. #endif
  792.  
  793.    return (pData);
  794.  
  795. }
  796.  
  797.  
  798. USHORT APIENTRY HhpDumpHeap( HHUGEHEAP hheap )
  799. {
  800.    PHEAP  pHeap = (PHEAP) hheap;
  801.    PBLOCK pBlock;
  802.    ULONG  cbytes;
  803.    CHAR   szBuffer[CCHMAXPATH];
  804.  
  805.    for (; pHeap; pHeap = pHeap->pNext)
  806.    {
  807.       strcpy (szBuffer, "Heap: ");
  808.       _ultoa ((ULONG)pHeap, &szBuffer[strlen(szBuffer)], 16);
  809.       strcat (szBuffer, " AllocCnt: ");
  810.       _ultoa ((ULONG)pHeap->uAllocCnt, &szBuffer[strlen(szBuffer)], 10);
  811.       strcat (szBuffer, " Size: ");
  812.       _ultoa ((ULONG)pHeap->lSize, &szBuffer[strlen(szBuffer)], 10);
  813.       strcat (szBuffer, "\r\n");
  814.       DosWrite (1, szBuffer, strlen(szBuffer), &cbytes);
  815.  
  816.  
  817.       for (pBlock = pHeap->pBlock; pBlock; pBlock = pBlock->pNext)
  818.       {
  819.          strcpy (szBuffer, "   Block: ");
  820.          _ultoa ((ULONG)pBlock, &szBuffer[strlen(szBuffer)], 16);
  821.          strcat (szBuffer, " Size: ");
  822.          _ultoa ((ULONG)pBlock->lBlockSize, &szBuffer[strlen(szBuffer)], 10);
  823.          strcat (szBuffer, " fAlloc:");
  824.          _ultoa ((ULONG)pBlock->fAlloc, &szBuffer[strlen(szBuffer)], 10);
  825. #ifdef MMDEBUG
  826.          strcat (szBuffer, "  File: ");
  827.          strcat (szBuffer, pBlock->szFile);
  828.          strcat (szBuffer, " Line: ");
  829.          _ultoa ((ULONG)pBlock->uLine, &szBuffer[strlen(szBuffer)], 10);
  830. #endif
  831.          strcat (szBuffer, "\r\n");
  832.          DosWrite (1, szBuffer, strlen(szBuffer), &cbytes);
  833.       }
  834.    }
  835.  
  836.    return (0);
  837. }
  838.