home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional Developers Kit 1992 November / Disc01 / Disc01.mdf / runnable / mmos2 / mmtoolkt / samples / admct / hhpheap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-06  |  24.6 KB  |  749 lines

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