home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / warptlk3.zip / TOOLKIT / SAMPLES / MM / CASECONV / HHPHEAP.C < prev    next >
C/C++ Source or Header  |  1995-08-24  |  25KB  |  750 lines

  1. /*static char *SCCSID = "@(#)hhpheap.c    13.1 92/02/15";*/
  2. /*static char *SCCSID = "@(#)hhpheap.c    13.1 92/02/05";*/
  3. #pragma title ("HHPHEAP.C - Dynamic Memory Management")
  4.  
  5. /************************ START OF SPECIFICATIONS ***************************/
  6. /*                                                                          */
  7. /* SOURCE FILE NAME:  HHPHEAP.C                                             */
  8. /*                                                                          */
  9. /* DESCRIPTIVE NAME: HHP Memory Management                                  */
  10. /*                                                                          */
  11. /* COPYRIGHT:                                                               */
  12. /*                   Copyright (c) IBM Corporation 1992, 1993               */
  13. /*                          All Rights Reserved                             */
  14. /*                                                                          */
  15. /* STATUS: OS/2 MM Release 1.10                                             */
  16. /*                                                                          */
  17. /* FUNCTION: Memory Management                                              */
  18. /*                                                                          */
  19. /* NOTES:                                                                   */
  20. /*    RESTRICTIONS: Runs in 32 bit protect mode (OS/2 2.0)                  */
  21. /*                                                                          */
  22. /*    This is a Heap Manager that can manage heaps larger than 64K.  It     */
  23. /*    can grow and shrink dynamically.  It is intended to hide some of the  */
  24. /*    memory management differences between 16-bit and 32-bit.              */
  25. /*                                                                          */
  26. /* ENTRY POINTS:                                                            */
  27. /*                                                                          */
  28. /*   ROUTINES: HhpCreateHeap                                                */
  29. /*             HhpAllocMem                                                  */
  30. /*             HhpFreeMem                                                   */
  31. /*             HhpDestroyHeap                                               */
  32. /*             HhpAccessHeap                                                */
  33. /*             HhpReleaseHeap                                               */
  34. /*             HhpAllocBuffer                                               */
  35. /*             HhpFreeBuffer                                                */
  36. /*             HhpAccessBuffer                                              */
  37. /*             HhpGetPID                                                    */
  38. /*                                                                          */
  39. /* EXTERNAL REFERENCES:                                                     */
  40. /*                                                                          */
  41. /*************************** END OF SPECIFICATIONS **************************/
  42.  
  43. /*
  44.  *  Include files
  45.  */
  46.  
  47. #define INCL_BASE           // include BASE OS/2 defines
  48. #define INCL_NOPMAPI        // leave out the PM stuff
  49. #include <os2.h>            // all-inclusive OS/2 include file
  50.  
  51. #include <hhpheap.h>        // External function prototypes
  52.  
  53. PVOID _cdecl memset( PVOID pvDest, UCHAR uch, ULONG cb );
  54.  
  55. /*
  56.  *  DLL global data
  57.  */
  58.  
  59. #define PID_MAX    20
  60.  
  61. /*
  62.  *  Local Symbols
  63.  */
  64.  
  65. #define HEAP_MAGIC     0x55
  66.  
  67. typedef struct _HBLOCK {                   /* should be dword multiple */
  68.    struct _HBLOCK FAR * pNext;             /* Next Heap Descriptor */
  69.    struct _HBLOCK FAR * pPrev;             /* Prev Heap Descriptor */
  70.    ULONG lBlockSize;                       /* Block Size */
  71.    UCHAR fAlloc;                           /* Block Alloced */
  72.    UCHAR magic;                            /* Used for Magic Number */
  73. } BLOCK;
  74. typedef BLOCK FAR  * PBLOCK;
  75.  
  76.  
  77. typedef struct _HHEAP {
  78.    struct _HHEAP FAR * pNext;              /* Next Heap */
  79.    PPID     ppidList;                      /* Pointer to pid List */
  80.    PBLOCK   pBlock;                        /* Heap Block List */
  81.    USHORT   uAllocCnt;                     /* Allocated Block Cnt */
  82.    ULONG    lSize;                         /* Segment Size */
  83.    USHORT   fFlags;                        /* Flags */
  84.    BLOCK    Block;                         /* first Block */
  85. } HEAP;
  86. typedef HEAP FAR * PHEAP;
  87.  
  88. /**********************************************************************\
  89.  *  Local functions                                                   *
  90. \**********************************************************************/
  91.  
  92. BOOL   LocateFreeMem (PHEAP pFirstHeap,
  93.                       PHEAP FAR * ppHeap,
  94.                       PBLOCK FAR * ppBlock,
  95.                       ULONG cbLen);
  96. USHORT CollapseFreeBlock (PBLOCK pBlock);
  97. USHORT CollapseFreeHeap (PHEAP pFirstHeap, PHEAP pHeap);
  98.  
  99. #ifndef INCL_32
  100. /* Reallocation of a segment is used to grow a heap in 16-bit OS/2 */
  101. BOOL   ReallocHeap (PHEAP pFirstHeap,
  102.                     PHEAP FAR * ppHeap,
  103.                     PBLOCK FAR * ppBlock,
  104.                     ULONG lSize);
  105. #endif
  106.  
  107. USHORT AddPid (PHEAP pFirstHeap, PID pid, PHEAP pNewHeap);
  108. PHEAP NewHeap (PHEAP pFirstHeap, ULONG lInitSize, USHORT fFlags);
  109.  
  110. /**********************************************************************\
  111.  * HhpCreateHeap
  112.  *
  113.  * Create the First Heap
  114.  *
  115.  * History:
  116. \**********************************************************************/
  117. HHUGEHEAP APIENTRY HhpCreateHeap (ULONG lInitSize, USHORT fFlags)
  118. {
  119.    return ((HHUGEHEAP)NewHeap (NULL, lInitSize, fFlags));
  120. }
  121.  
  122.  
  123. /**********************************************************************\
  124.  * NewHeap
  125.  *
  126.  * Create a New Heap (one segment)
  127.  *
  128.  * History:
  129. \**********************************************************************/
  130. PHEAP NewHeap (PHEAP pFirstHeap, ULONG lInitSize, USHORT fFlags)
  131. {
  132.    PHEAP  pHeap;
  133.    PHEAP  pLastHeap;
  134.  
  135.    /******************************************************************/
  136.    /* Allocate a Segment or block of memory into which to build heap */
  137.    /******************************************************************/
  138.  
  139.    pHeap = (PHEAP) HhpAllocBuffer (lInitSize, fFlags);   /* Alloc Memory for Heap */
  140.    if (!pHeap) return (NULL);
  141.  
  142.    /*
  143.     * Zero the heap here.  This is more efficient than zeroing when
  144.     * each piece is allocated.
  145.     */
  146.  
  147. //   memset( pHeap, '\0', (ULONG)lInitSize );
  148.  
  149.    /*****************************************************************/
  150.    /* Setup Heap Structures                                         */
  151.    /*****************************************************************/
  152.    pHeap->pNext = 0;                            /* Last in List */
  153.    pHeap->pBlock = &pHeap->Block;               /* Point to first block */
  154.    pHeap->uAllocCnt = 0;                        /* Number of Allocated Blocks */
  155.    pHeap->lSize = lInitSize;                    /* Size of Segment */
  156.    pHeap->fFlags = fFlags;                      /* Heap Flags */
  157.    pHeap->ppidList = NULL;                      /* No Pid List */
  158.  
  159.    pHeap->pBlock->pNext = NULL;                 /* Only one block */
  160.    pHeap->pBlock->pPrev = NULL;                 /* No back pointer */
  161.    pHeap->pBlock->lBlockSize = (lInitSize - (ULONG) sizeof(HEAP));  /* Init Block Size */
  162.    pHeap->pBlock->fAlloc = FALSE;               /* Free */
  163.    pHeap->pBlock->magic = HEAP_MAGIC;           /* Initialize reserved word */
  164.  
  165.    /******************************************************************/
  166.    /* Chain Heaps                                                    */
  167.    /******************************************************************/
  168.    if (pFirstHeap) {
  169.       for (pLastHeap=pFirstHeap; pLastHeap->pNext; pLastHeap=pLastHeap->pNext);
  170.       pLastHeap->pNext = pHeap;
  171.    }
  172.  
  173.    /******************************************************************/
  174.    /* Create PID List or Give new Heap to all who Accessed Heap      */
  175.    /******************************************************************/
  176.  
  177.    if (!pFirstHeap && pHeap->fFlags & HH_SHARED) 
  178.       {
  179.       pHeap->ppidList = HhpAllocMem ((HHUGEHEAP)pHeap, sizeof(PID)*PID_MAX);
  180.  
  181.       /*
  182.        * Don't Give to anyone.
  183.        */
  184.  
  185.       if (AddPid( pHeap, HhpGetPID(), NULL ))
  186.          return (NULL);
  187.       } 
  188.    else if (pHeap->fFlags & HH_SHARED)
  189.       {
  190.  
  191.       /*
  192.        * Give This Heap to Others.
  193.        */
  194.  
  195.       if (AddPid( pFirstHeap, HhpGetPID(), pHeap )) 
  196.          return (NULL);
  197.       }
  198.  
  199.    return (pHeap);                              /* return heap pointer */
  200.  
  201. }
  202.  
  203. /**********************************************************************\
  204.  * HhpAllocMem
  205.  *
  206.  * Allocate some memory
  207.  *
  208.  * History:
  209. \**********************************************************************/
  210.  
  211. PVOID APIENTRY HhpAllocMem (HHUGEHEAP hheap, ULONG cbLen)
  212. {
  213.    PBLOCK pBlock;
  214.    PHEAP  pHeap;
  215.    PBLOCK pBlockNew;
  216.    PBLOCK pBlockNext;
  217.    BOOL   fAlloc;
  218.    ULONG  lNewBlockSize;
  219.    PHEAP  pFirstHeap = (PHEAP)hheap;
  220.    PCHAR  pData = NULL;
  221.  
  222.    if (!hheap) return (NULL);                   /* Bad handle */
  223.  
  224.    fAlloc = LocateFreeMem (pFirstHeap, &pHeap, &pBlock, cbLen); /* Locate a free Block */
  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) { /* Access All Segments Of Heap */
  568.       if (HhpAccessBuffer ((PVOID)pHeap)) return (TRUE);
  569.    }
  570.  
  571.    /********************************************************************/
  572.    /* Put New Pid Into Pid List                                        */
  573.    /********************************************************************/
  574.  
  575.    if (pFirstHeap->fFlags & HH_SHARED) 
  576.       {
  577.       if (AddPid( pFirstHeap, pid, NULL ))
  578.          return (TRUE);
  579.       }
  580.  
  581.    return (FALSE);
  582.  
  583. }
  584.  
  585. /**********************************************************************\
  586.  * HhpReleaseHeap
  587.  *
  588.  * History:
  589. \**********************************************************************/
  590. USHORT APIENTRY HhpReleaseHeap (HHUGEHEAP hheap, PID pid)
  591. {
  592.    PHEAP pHeap = (PHEAP) hheap;
  593.    USHORT i;
  594.  
  595.    if (!(pHeap->fFlags & HH_SHARED)) return (FALSE);
  596.  
  597.    if (!pHeap->ppidList) return (FALSE);
  598.  
  599.    /* Remove Pid from List */
  600.    for (i=0; i<PID_MAX && pHeap->ppidList[i] != pid; i++);   /* Locate Slot */
  601.  
  602.    if (i < PID_MAX)
  603.       pHeap->ppidList[i] = (ULONG)NULL;
  604.  
  605.    return ((USHORT)NULL);
  606.  
  607. }
  608.  
  609. /*************************************************************************\
  610.  * AddPid
  611.  *
  612.  *
  613. \*************************************************************************/
  614. USHORT AddPid (PHEAP pFirstHeap, PID pid, PHEAP pNewHeap)
  615. {
  616.    USHORT i;
  617.  
  618.    /* Save the Pid in the PidList of the First Heap only */
  619.  
  620.    for (i=0; i<PID_MAX && pFirstHeap->ppidList[i] != pid; i++); /* Existing */
  621.    if (i == PID_MAX) {
  622.       for (i=0; i<PID_MAX && pFirstHeap->ppidList[i] != 0; i++);/* Locate Slot */
  623.       if (i == PID_MAX) return (TRUE);                     /* No Access */
  624.       pFirstHeap->ppidList[i] = pid;                       /* store pid */
  625.    }
  626.  
  627.    /* Give the New Memory Block to all who have accessed this heap */
  628.  
  629.    if (pNewHeap && pNewHeap != pFirstHeap) {      /* Give Seg to All Pids */
  630.       for (i=0; i<PID_MAX; i++) {
  631.          if (pFirstHeap->ppidList[i] != 0) {
  632. #ifndef INCL_32
  633.             SEL selNew;
  634.             DosGiveSeg (SELECTOROF(pNewHeap), pFirstHeap->ppidList[i], &selNew);
  635. #else
  636.             DosGiveSharedMem (pNewHeap, pFirstHeap->ppidList[i], fGIVESHR);
  637. #endif
  638.          }
  639.       }
  640.    }
  641.  
  642.    return (FALSE);
  643.  
  644. }
  645.  
  646. #ifndef INCL_32
  647. /**********************************************************************\
  648.  * ReallocHeap
  649.  *
  650.  *
  651.  * History
  652. \**********************************************************************/
  653. BOOL ReallocHeap (PHEAP pFirstHeap,
  654.                   PHEAP FAR * ppHeap,
  655.                   PBLOCK FAR * ppBlock,
  656.                   ULONG lSize)
  657. {
  658.    USHORT rc;
  659.    PHEAP  pHeap;
  660.    PBLOCK pBlock;
  661.    PBLOCK pNextBlock;
  662.  
  663.    for (pHeap = pFirstHeap; pHeap; pHeap = pHeap->pNext) {
  664.  
  665.       if ((LONG)0xffffL - (LONG)pHeap->lSize >= (LONG)lSize) { /* ReSize segment */
  666.          /* Only Supported with 64K Segments */
  667.          rc = DosReallocSeg ((USHORT)(pHeap->lSize+lSize), SELECTOROF(pHeap));
  668.          if (rc) return (FALSE);                    /* No Memory */
  669.  
  670.          pHeap->lSize += lSize;                     /* Increase Heap Size */
  671.  
  672.          for (pBlock = pHeap->pBlock; pBlock->pNext; pBlock = pBlock->pNext); /* Last */
  673.          if (pBlock->fAlloc) {                     /* Last Block Allocated */
  674.             pNextBlock = (PBLOCK)((PCHAR)pBlock + sizeof(BLOCK) + pBlock->lBlockSize);
  675.             pNextBlock->pPrev = pBlock;
  676.             pNextBlock->pNext = NULL;
  677.             pBlock->pNext = pNextBlock;
  678.             pNextBlock->lBlockSize = (lSize - (ULONG)sizeof(BLOCK));
  679.             pNextBlock->magic = HEAP_MAGIC;
  680.             pNextBlock->fAlloc = FALSE;
  681.             pBlock = pNextBlock;
  682.          } else {
  683.             pBlock->lBlockSize += lSize;
  684.          }
  685.          *ppHeap = pHeap;
  686.          *ppBlock = pBlock;
  687.          return (TRUE);                            /* success */
  688.  
  689.       }
  690.  
  691.    }
  692.    return (FALSE);
  693.  
  694. }
  695.  
  696. #endif
  697.  
  698. /*************************************************************************\
  699.  * HhpGetPID
  700.  *
  701.  *
  702. \*************************************************************************/
  703. PID APIENTRY HhpGetPID (VOID)
  704. {
  705.    USHORT rc;
  706.  
  707. #ifndef INCL_32
  708.  
  709.    PIDINFO pInfo;
  710.  
  711.    rc = DosGetPID (&pInfo);                  /* Get Pid Info */
  712.    if (rc) return ((PID)NULL);               /* Bad News */
  713.  
  714.    return (pInfo.pid);                       /* Return Current PID */
  715.  
  716. #else
  717.  
  718.    PPIB ppib;
  719.    PTIB ptib;
  720.  
  721.    rc = (USHORT) DosGetInfoBlocks (&ptib, &ppib);  /* Get Info Blocks */
  722.    if (rc) return ((PID)NULL);
  723.  
  724.    return (ppib->pib_ulpid);                 /* return PID */
  725.  
  726. #endif
  727.  
  728. }
  729.  
  730. #ifdef DEBUG
  731. #include <stdio.h>
  732.  
  733. USHORT APIENTRY HhpDumpHeap( HHUGEHEAP hheap )
  734. {
  735.    PHEAP pHeap = (PHEAP) hheap;
  736.    PBLOCK pBlock;
  737.  
  738.    for (; pHeap; pHeap = pHeap->pNext) {
  739.       fprintf(stdout, "Heap: %.8lx  AllocCnt: %d  SegSize %.8lx\n",
  740.              (ULONG)pHeap, (USHORT)pHeap->uAllocCnt, (ULONG)pHeap->lSize);
  741.       for (pBlock = pHeap->pBlock; pBlock; pBlock = pBlock->pNext) {
  742.          fprintf(stdout, "   Block: %.8lx  Size: %.8lx  Alloc %d\n",
  743.              (ULONG)pBlock, (ULONG)pBlock->lBlockSize, (USHORT) pBlock->fAlloc);
  744.       }
  745.    }
  746.  
  747. }
  748.  
  749. #endif
  750.