home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mmpm21tk.zip / TK / CDMCT / HHPHEAP.C < prev    next >
C/C++ Source or Header  |  1993-01-25  |  25KB  |  756 lines

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