home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / viscobv6.zip / vac22os2 / ibmcobol / samples / toolkit / mm / ultimoio / hhpheap.c < prev    next >
C/C++ Source or Header  |  1996-11-19  |  30KB  |  870 lines

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