Changeset 496


Ignore:
Timestamp:
Jul 3, 2010, 7:44:25 PM (15 years ago)
Author:
David Azarewicz
Message:

changes to debug output

Location:
OCO/trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • OCO/trunk/drv16/malloc.c

    r478 r496  
    33/* SCCSID = %W% %E% */
    44/****************************************************************************
    5  *                                                                          *
    6  * Copyright (c) IBM Corporation 1994 - 1997.                               *
    7  *                                                                          *
    8  * The following IBM OS/2 source code is provided to you solely for the     *
     5 *                                                                                                                                                      *
     6 * Copyright (c) IBM Corporation 1994 - 1997.                                                           *
     7 *                                                                                                                                                      *
     8 * The following IBM OS/2 source code is provided to you solely for the         *
    99 * the purpose of assisting you in your development of OS/2 device drivers. *
    10  * You may use this code in accordance with the IBM License Agreement       *
    11  * provided in the IBM Device Driver Source Kit for OS/2.                   *
    12  *                                                                          *
     10 * You may use this code in accordance with the IBM License Agreement           *
     11 * provided in the IBM Device Driver Source Kit for OS/2.                                       *
     12 *                                                                                                                                                      *
    1313 ****************************************************************************/
    1414/**@internal %W%
    15  *  Implementation of the driver's built in memory management.
     15 *      Implementation of the driver's built in memory management.
    1616 * @version %I%
    1717 * @context
    18  *  Unless otherwise noted, all interfaces are Ring-3 and Ring-0, 16-bit,
    19  *  kernel stack.
     18 *      Unless otherwise noted, all interfaces are Ring-3 and Ring-0, 16-bit,
     19 *      kernel stack.
    2020 * @notes
    2121 * @history
    22  *  01-Jul-95  Timur Tabi   Creation
     22 *      01-Jul-95  Timur Tabi   Creation
    2323 */
    2424
    2525#include <os2.h>
    26 #include <string.h>                    // memcpy(), memset()
     26#include <string.h>                                     // memcpy(), memset()
    2727#include <include.h>
     28#include <dbgos2.h>
    2829#include "end.h"
    29 #include "sizedefs.h"                  // HEAP_SIZE, DEFAULT_HEAP.
    30                                        // MustBe divisible by 4.
    31 
    32 #define  SIGNATURE      0xBEEFDEAD      // "DeadBeef" when view in hex in word order.
     30#include "sizedefs.h"                                   // HEAP_SIZE, DEFAULT_HEAP.
     31                                                                                // MustBe divisible by 4.
     32#ifdef DEBUG
     33#define HEAP_DEBUG
     34#endif
     35#define  SIGNATURE              0xBEEFDEAD              // "DeadBeef" when view in hex in word order.
    3336
    3437typedef struct _MEMBLOCK {
    35    unsigned long ulSignature;
    36    unsigned uSize;
    37    struct _MEMBLOCK *pmbNext;
    38    char achBlock[1];
     38        unsigned long ulSignature;
     39        unsigned uSize;
     40        struct _MEMBLOCK *pmbNext;
     41        char achBlock[1];
    3942} MEMBLOCK, __near *PMEMBLOCK;
    4043
     
    4952//--- Global Variables used to manage the heap:
    5053//
    51 PMEMBLOCK pmbUsed=0;    // Points to head of list of allocated memory blocks.
    52                         // Newly allocated blocks are inserted into head of list.
    53 PMEMBLOCK pmbFree;      // Points to head of list of available memory blocks.
    54 unsigned uMemFree;      // N bytes available for allocation.
    55 char __near
    56    acHeap[HEAP_SIZE] = {0};   // The heap.  NOTE:  This must be the last data definition in the HEAP segment,
    57                         // although not done currently, we are planning to size the heap down at INIT
    58                         // time.  If this is done, any vbls in the HEAP segment that
    59                         // appear after the HEAP would become unaddressable.
     54PMEMBLOCK pmbUsed=0;    // Points to head of list of allocated memory blocks.
     55                                                // Newly allocated blocks are inserted into head of list.
     56PMEMBLOCK pmbFree;              // Points to head of list of available memory blocks.
     57unsigned uMemFree;              // N bytes available for allocation.
     58char __near acHeap[HEAP_SIZE] = {0};    // The heap.    NOTE:  This must be the last data definition in the HEAP segment,
     59                                                // although not done currently, we are planning to size the heap down at INIT
     60                                                // time.  If this is done, any vbls in the HEAP segment that
     61                                                // appear after the HEAP would become unaddressable.
    6062
    6163//--- Heap methods:
    6264
     65#ifdef HEAP_DEBUG
    6366void dumpheap(void)
    6467{
    65    int i;
    66    PMEMBLOCK pmb;
    67    unsigned u=0;
    68 
    69    pmb=pmbUsed;
    70 //   ddprintf("HEAP: Heap Dump - Used blocks\n");
    71    for (i=0; i<10; i++) {
    72 //      ddprintf("  pmb=%p, length=%ui\n",(void __far *) pmb, pmb->uSize);
    73       u+=pmb->uSize;
    74       pmb=pmb->pmbNext;
    75       if (!pmb) break;
    76    }
    77 //   ddprintf("  Total used = %ui\n",u);
    78 
    79    u=0;
    80    pmb=pmbFree;
    81 //   ddprintf("HEAP: Heap Dump - Free blocks\n");
    82    for (i=0; i<50; i++) {
    83 //      ddprintf("  pmb=%p, length=%ui\n",(void __far *) pmb, pmb->uSize);
    84       u+=pmb->uSize;
    85       pmb=pmb->pmbNext;
    86       if (!pmb) break;
    87    }
    88 //   ddprintf("  Total free = %ui\n",u);
    89 }
    90 
    91 USHORT fMemoryDoc = 0;
    92 USHORT nAlloc = 0;           // Current number of allocated blocks.
    93 USHORT cAlloc = 0;           // Total memory in allocated blocks incl. headers.
    94 USHORT nAllocCalls = 0;      // Cumulative total, number of malloc() calls.
    95 USHORT nFree  = 0;           // Current number of free blocks.
    96 USHORT cFree  = 0;           // Total memory in free blocks incl. headers.
    97 USHORT nFreeCalls  = 0;      // Cumulative total, number of free() calls.
    98 USHORT nCompact = 0;         // Num of times we've joined two adjacent free
    99                              // blocks into a single larger block.
     68        int i;
     69        PMEMBLOCK pmb;
     70        unsigned u=0;
     71
     72        pmb=pmbUsed;
     73        dprintf(("HEAP:Heap Dump - Used blocks\n"));
     74        for (i=0; i<10; i++) {
     75                dprintf(("  pmb=%lx, length=%x\n",(void __far *) pmb, pmb->uSize));
     76                u+=pmb->uSize;
     77                pmb=pmb->pmbNext;
     78                if (!pmb) break;
     79        }
     80        dprintf(("  Total used = %x\n",u));
     81
     82        u=0;
     83        pmb=pmbFree;
     84        dprintf(("HEAP:Heap Dump - Free blocks\n"));
     85        for (i=0; i<50; i++) {
     86                dprintf(("  pmb=%lx, length=%x\n",(void __far *) pmb, pmb->uSize));
     87                u+=pmb->uSize;
     88                pmb=pmb->pmbNext;
     89                if (!pmb) break;
     90        }
     91        dprintf(("  Total free = %x\n",u));
     92}
     93#endif
     94
     95USHORT fMemoryDoc = 1;
     96USHORT nAlloc = 0;                       // Current number of allocated blocks.
     97USHORT cAlloc = 0;                       // Total memory in allocated blocks incl. headers.
     98USHORT nAllocCalls = 0;          // Cumulative total, number of malloc() calls.
     99USHORT nFree  = 0;                       // Current number of free blocks.
     100USHORT cFree  = 0;                       // Total memory in free blocks incl. headers.
     101USHORT nFreeCalls  = 0;          // Cumulative total, number of free() calls.
     102USHORT nCompact = 0;             // Num of times we've joined two adjacent free
     103                                                         // blocks into a single larger block.
    100104USHORT cTotalHeap = HEAP_SIZE;
    101105
    102106void SignatureCheck ( PMEMBLOCK p, PSZ idText )
    103107{
    104 
    105    bool bGoodPointer;
    106 
    107    // Set bGoodPointer to indicate whether or not 'p' points within heap.
    108    bGoodPointer = (((USHORT) p) >= ((USHORT) acHeap))
    109                   && (((USHORT) p) <= (((USHORT) acHeap) + HEAP_SIZE)) ;
    110                               //### heap might have less than HEAP_SIZE bytes
    111 
    112    // Check for correct signature.
    113    if (bGoodPointer)
    114       bGoodPointer = (p->ulSignature == SIGNATURE);
    115 
    116    if (! bGoodPointer)
    117    {
    118 //      ddprintf( "Heap pointer out of range, or signature exception: %p %s\n", p, idText );
    119       int3();
    120    }
     108        bool bGoodPointer;
     109
     110        // Set bGoodPointer to indicate whether or not 'p' points within heap.
     111        bGoodPointer = (((USHORT) p) >= ((USHORT) acHeap))
     112                                  && (((USHORT) p) <= (((USHORT) acHeap) + HEAP_SIZE)) ;
     113                                                          //### heap might have less than HEAP_SIZE bytes
     114
     115        // Check for correct signature.
     116        if (bGoodPointer)
     117                bGoodPointer = (p->ulSignature == SIGNATURE);
     118
     119        if (! bGoodPointer)
     120        {
     121#ifdef HEAP_DEBUG
     122                dprintf(( "Heap pointer out of range or signature exception: %lx %s\n", p, idText ));
     123#endif
     124                int3();
     125        }
    121126}
    122127
    123128void HeapCheck ( PSZ idText )
    124129{
    125    PMEMBLOCK p;
    126    for ( nAlloc = 0, cAlloc = 0, p = pmbUsed; p; p = p->pmbNext ) {
    127       ++nAlloc;
    128       cAlloc += p->uSize + HDR_SIZE;
    129       SignatureCheck( p,(PSZ) "HeapCheck() Used list" );
    130    }
    131    for ( nFree = 0, cFree = 0, p = pmbFree; p; p = p->pmbNext ) {
    132       ++nFree;
    133       cFree += p->uSize + HDR_SIZE;
    134       SignatureCheck( p,(PSZ) "HeapCheck() Free list" );
    135    }
    136    if (fMemoryDoc & 1) {
    137       if (cAlloc + cFree != cTotalHeap) {
    138 //         ddprintf( "Heap Alloc + Free != Total\n" );
    139 //       dumpheap();
    140          int3();
    141       }
    142    }
     130        PMEMBLOCK p;
     131        for ( nAlloc = 0, cAlloc = 0, p = pmbUsed; p; p = p->pmbNext ) {
     132                ++nAlloc;
     133                cAlloc += p->uSize + HDR_SIZE;
     134                SignatureCheck( p,(PSZ) "HeapCheck() Used list" );
     135        }
     136        for ( nFree = 0, cFree = 0, p = pmbFree; p; p = p->pmbNext ) {
     137                ++nFree;
     138                cFree += p->uSize + HDR_SIZE;
     139                SignatureCheck( p,(PSZ) "HeapCheck() Free list" );
     140        }
     141        if (fMemoryDoc & 1) {
     142                if (cAlloc + cFree != cTotalHeap) {
     143#ifdef HEAP_DEBUG
     144                        dprintf(( "Heap Alloc + Free != Total\n" ));
     145                        dumpheap();
     146#endif
     147                        int3();
     148                }
     149        }
    143150}
    144151
     
    146153
    147154// Threshold for creating a new free block.
    148 #define  MIN_Leftover (HDR_SIZE + MIN_FragSize)
     155#define MIN_Leftover (HDR_SIZE + MIN_FragSize)
    149156
    150157/* make_new_free()
    151    Formats the back part of an existing free MEMBLOCK as a new, smaller
    152    "Free" MEMBLOCK.  Doesn't update Global vbls (caller responsibility).
    153       IN:   pmbOldFree - pointer to existing memory block.
    154             uSize - offset, which won't be included in new allocation.
    155                     it's assumed HDR is not included in uSize.
    156       OUT:  pointer to new free MEMBLOCK, is  a new block of free memory,
    157             is created at pmbOldFree + uRequest.  The memory block header
    158             in both the new block and the old block are properly initialized
    159             on return, but we don't update the Free list or Allocated list.
    160       OUT:  NULL if the new free memory block is smaller than the
    161             framentation threshold.
     158        Formats the back part of an existing free MEMBLOCK as a new, smaller
     159        "Free" MEMBLOCK.  Doesn't update Global vbls (caller responsibility).
     160          IN:   pmbOldFree - pointer to existing memory block.
     161                        uSize - offset, which won't be included in new allocation.
     162                                        it's assumed HDR is not included in uSize.
     163          OUT:  pointer to new free MEMBLOCK, is  a new block of free memory,
     164                        is created at pmbOldFree + uRequest.  The memory block header
     165                        in both the new block and the old block are properly initialized
     166                        on return, but we don't update the Free list or Allocated list.
     167          OUT:  NULL if the new free memory block is smaller than the
     168                        framentation threshold.
    162169
    163170The fragmentation consideration comes into play when we find a block that's
     
    165172part to be useful as another free block.
    166173
    167     _______________________free block_______________________________________
    168    |  free    |                                                             |
    169    |  block   |       space available                                       |
    170    |  header  |          (pmbFree->uSize bytes long)                        |
    171    |(HDR_SIZE |                                                             |
    172    |__bytes)__|_____________________________________________________________|
     174   _______________________free block_______________________________________
     175   |  free    |                                                            |
     176   |  block   |      space available                                       |
     177   |  header  |        (pmbFree->uSize bytes long)                         |
     178   |(HDR_SIZE |                                                            |
     179   |__bytes)__|____________________________________________________________|
    173180
    174181   <-- HDR --> <------------------------- l -------------------------------->
     
    176183Must either be allocated in total, or must become:
    177184
    178     _______________________used block_______________________________________
    179    |  used    |                                     |  free    |            |
    180    |  block   |  space allocated                    |  block   | space      |
    181    |  header  |  == uSize (following DWORD align't) |  header  | available  |
    182    |(HDR_SIZE |     (pmbUsed->uSize bytes long)     |(HDR_SIZE |            |
    183    |__bytes)__|_____________________________________|__bytes)__|____________|
     185   _______________________used block_______________________________________
     186   |  used    |                                     |  free    |           |
     187   |  block   |  space allocated                    |  block   | space     |
     188   |  header  |  == uSize (following DWORD align't) |  header  | available |
     189   |(HDR_SIZE |    (pmbUsed->uSize bytes long)      |(HDR_SIZE |           |
     190   |__bytes)__|_____________________________________|__bytes)__|___________|
    184191
    185192   <-- HDR --> <-------------- n ------------------><-- HDR --> <--- m ----->
     
    205212PMEMBLOCK make_new_free(PMEMBLOCK pmbOldFree, unsigned uRequest)
    206213{
    207    PMEMBLOCK pmbNewFree;    // If we create a new free block, it goes here.
    208 
    209    // Which of the two cases (as described in function header) have we got?
    210    // We know we're big enough to satisfy request, is there enough leftover
    211    // for a new free block?
    212 
    213     if ((uRequest + MIN_Leftover) > pmbOldFree->uSize) {
    214        // Not enough leftover, allocate the entire free block.  Don't
    215        // change pmbOldFree->uSize.
    216        pmbNewFree = 0;
    217     }
    218     else {
    219        // We've got enough leftover to make a new free block.
    220        pmbNewFree = (PMEMBLOCK) ((char __near *) pmbOldFree + HDR_SIZE + uRequest );
    221        pmbNewFree->ulSignature = SIGNATURE;
    222        pmbNewFree->uSize = pmbOldFree->uSize - (uRequest + HDR_SIZE);
    223        pmbNewFree->pmbNext = pmbOldFree->pmbNext;
    224 
    225        // Update the size of the free block that was passed in.
    226        pmbOldFree->uSize -= (pmbNewFree->uSize + HDR_SIZE);
    227     }
    228 
    229    return pmbNewFree;
     214        PMEMBLOCK pmbNewFree;    // If we create a new free block, it goes here.
     215
     216        // Which of the two cases (as described in function header) have we got?
     217        // We know we're big enough to satisfy request, is there enough leftover
     218        // for a new free block?
     219
     220        if ((uRequest + MIN_Leftover) > pmbOldFree->uSize) {
     221                // Not enough leftover, allocate the entire free block. Don't
     222                // change pmbOldFree->uSize.
     223                pmbNewFree = 0;
     224        }
     225        else {
     226                // We've got enough leftover to make a new free block.
     227                pmbNewFree = (PMEMBLOCK) ((char __near *) pmbOldFree + HDR_SIZE + uRequest );
     228                pmbNewFree->ulSignature = SIGNATURE;
     229                pmbNewFree->uSize = pmbOldFree->uSize - (uRequest + HDR_SIZE);
     230                pmbNewFree->pmbNext = pmbOldFree->pmbNext;
     231
     232                // Update the size of the free block that was passed in.
     233                pmbOldFree->uSize -= (pmbNewFree->uSize + HDR_SIZE);
     234        }
     235
     236        return pmbNewFree;
    230237}
    231238
     
    235242unsigned _msize(void __near *pvBlock)
    236243{
    237    PMEMBLOCK pmb;
    238 
    239    if (!pvBlock)
    240       return 0;
    241 
    242    pmb = (PMEMBLOCK) ((char __near *) pvBlock - HDR_SIZE);
    243 
    244    return pmb->uSize;
     244        PMEMBLOCK pmb;
     245
     246        if (!pvBlock) return 0;
     247
     248        pmb = (PMEMBLOCK) ((char __near *) pvBlock - HDR_SIZE);
     249
     250        return pmb->uSize;
    245251}
    246252
    247253
    248254/**@internal pmbAllocateBlock
    249  *  Update all data structures for allocation of one memory block.  It's
    250  *  assumed, on entry, that the block is large enough for the requested
    251  *  allocation.
     255 *      Update all data structures for allocation of one memory block.  It's
     256 *      assumed, on entry, that the block is large enough for the requested
     257 *      allocation.
    252258 * @param PMEMBLOCK pmb - the current memory block on the Free list to
    253  *  allocate.
     259 *      allocate.
    254260 * @param USHORT uRequest - size of the memory request to fill, not counting
    255  *  memory block header.
     261 *      memory block header.
    256262 * @param PMEMBLOCK pmbPrev - the memory block which precedes the block being
    257  *  allocated in the Free list.  NULL if no predecessor (ie, pmb is pointed to
    258  *  by ::pmbFree).
     263 *      allocated in the Free list.  NULL if no predecessor (ie, pmb is pointed to
     264 *      by ::pmbFree).
    259265 * @return PMEMBLOCK - pointer to the data part of the allocated memory block,
    260  *  suitable for return to malloc() caller.
     266 *      suitable for return to malloc() caller.
    261267 */
    262268void __near *
    263269npvAllocateBlock( PMEMBLOCK pmb, USHORT uRequest, PMEMBLOCK pmbPrev )
    264270{
    265    //pmb points to the selected block.
    266    //pmbPrev points to the block prior to the selected block, NULL if pmbFree.
    267    PMEMBLOCK pmbOldNext;            // Original free block that follows the block being allocated.
    268    PMEMBLOCK pmbNewFree;            // Leftover free memory from the allocated block.
    269 
    270    // Split this block into an allocated + free part if it's big enough.
    271    pmbNewFree = make_new_free( pmb, uRequest );
    272 
    273    // Update global memory counter.
    274    uMemFree -= (pmb->uSize + HDR_SIZE);
    275 
    276    // Add this block into the front of the Allocated list.
    277    pmbOldNext = pmb->pmbNext;
    278    pmb->pmbNext = pmbUsed;
    279    pmbUsed = pmb;
    280 
    281    // Remove the new allocation from the Free list.
    282    if (pmbNewFree) {                // If we split off a new free block
    283       pmbNewFree->pmbNext = pmbOldNext;
    284       if (pmbPrev)                  // If we're not at head of Free list
    285          pmbPrev->pmbNext = pmbNewFree;
    286       else
    287          pmbFree = pmbNewFree;
    288    }
    289    else {                           // We allocated the entire free block.
    290       if (pmbPrev)                  // If we're not at head of Free list
    291          pmbPrev->pmbNext = pmbOldNext;
    292       else
    293          pmbFree = pmbOldNext;
    294    }
    295 
    296    return (void __near *) pmb->achBlock;
     271        //pmb points to the selected block.
     272        //pmbPrev points to the block prior to the selected block, NULL if pmbFree.
     273        PMEMBLOCK pmbOldNext;                   // Original free block that follows the block being allocated.
     274        PMEMBLOCK pmbNewFree;                   // Leftover free memory from the allocated block.
     275
     276        // Split this block into an allocated + free part if it's big enough.
     277        pmbNewFree = make_new_free( pmb, uRequest );
     278
     279        // Update global memory counter.
     280        uMemFree -= (pmb->uSize + HDR_SIZE);
     281
     282        // Add this block into the front of the Allocated list.
     283        pmbOldNext = pmb->pmbNext;
     284        pmb->pmbNext = pmbUsed;
     285        pmbUsed = pmb;
     286
     287        // Remove the new allocation from the Free list.
     288        if (pmbNewFree) {                               // If we split off a new free block
     289                pmbNewFree->pmbNext = pmbOldNext;
     290                if (pmbPrev)                                    // If we're not at head of Free list
     291                        pmbPrev->pmbNext = pmbNewFree;
     292                else
     293                        pmbFree = pmbNewFree;
     294        }
     295        else {                                                  // We allocated the entire free block.
     296                if (pmbPrev)                                    // If we're not at head of Free list
     297                        pmbPrev->pmbNext = pmbOldNext;
     298                else
     299                        pmbFree = pmbOldNext;
     300        }
     301
     302        return (void __near *) pmb->achBlock;
    297303}
    298304
     
    311317void __near *malloc( unsigned uSize )
    312318{
    313    USHORT uRequest;                    // Request size after alignment.
    314    PMEMBLOCK pmb, pmbPrev;             // Use to walk free lists.
    315    void __near *npvReturn = 0;         // Return value.
    316 
    317    ++nAllocCalls;                      // Diagnostics.
    318    HeapCheck((PSZ) "malloc() entry" );
    319 
    320    if (! uSize) return 0;
    321 
    322    uRequest = (uSize + 3) & -4;        // Force DWORD alignment.
    323 
    324     if (pmbFree->uSize >= uRequest)
    325     {
    326         npvReturn = npvAllocateBlock(pmbFree, uRequest, NULL);
    327     }
    328     else
    329     {
    330         pmbPrev = pmbFree;
    331         for (pmb=pmbFree->pmbNext; pmb; pmbPrev=pmb, pmb=pmb->pmbNext)
    332         {
    333              if (pmb->uSize >= uRequest)
    334              {
    335                  npvReturn = npvAllocateBlock(pmb, uRequest, pmbPrev);
    336                  break;
    337              }
    338         }
    339     }
    340 
    341     if (npvReturn)
    342     {
    343         SignatureCheck( (PMEMBLOCK) (((PUCHAR) npvReturn) - HDR_SIZE), (PSZ) "malloc() exit, allocated block" );
    344     }
    345     else
    346     {
    347        // Out of Memory !!!
    348        int3();
    349     }
    350 
    351     HeapCheck((PSZ) "malloc() exit" );
    352     return npvReturn;
     319        USHORT uRequest;                                        // Request size after alignment.
     320        PMEMBLOCK pmb, pmbPrev;                         // Use to walk free lists.
     321        void __near *npvReturn = 0;                     // Return value.
     322
     323        ++nAllocCalls;                                          // Diagnostics.
     324        HeapCheck((PSZ) "malloc() entry" );
     325
     326        if (! uSize) return 0;
     327
     328        uRequest = (uSize + 3) & -4;            // Force DWORD alignment.
     329
     330        if (pmbFree->uSize >= uRequest)
     331        {
     332                npvReturn = npvAllocateBlock(pmbFree, uRequest, NULL);
     333        }
     334        else
     335        {
     336                pmbPrev = pmbFree;
     337                for (pmb=pmbFree->pmbNext; pmb; pmbPrev=pmb, pmb=pmb->pmbNext)
     338                {
     339                        if (pmb->uSize >= uRequest)
     340                        {
     341                                npvReturn = npvAllocateBlock(pmb, uRequest, pmbPrev);
     342                                break;
     343                        }
     344                }
     345        }
     346
     347        if (npvReturn)
     348        {
     349                SignatureCheck( (PMEMBLOCK) (((PUCHAR) npvReturn) - HDR_SIZE), (PSZ) "malloc() exit, allocated block" );
     350        }
     351        else
     352        {
     353                // Out of Memory !!!
     354                int3();
     355        }
     356
     357        HeapCheck((PSZ) "malloc() exit" );
     358        return npvReturn;
    353359}
    354360
     
    356362This function compacts the free blocks together.  This function is a
    357363companion to free(), and thus the algorithm is tailored to how free()
    358 works.  Change the algorithm in free(), and you'll have to change this
     364works.  Change the algorithm in free(), and you'll have to change this
    359365function too.
    360366
     
    3733793. Physically after another free block
    3743804. Between two free blocks (i.e. the block occupies the entire space
    375    between two free blocks)
     381        between two free blocks)
    376382
    377383Since the newly freed block is the first in the free list, compact()
    378384starts with the second block in the list (i.e. pmbFree->pmbNext).
    379385Each free block is then compared with the newly freed block for
    380 adjacency.  If a given block is located before the new block, then it
     386adjacency.      If a given block is located before the new block, then it
    381387can't possibly be also located after, and vice versa.  Hence, the
    382388"else if" statement in the middle of the loop.
     
    384390Also, the newly freed block can only be adjacent to at most two other
    385391blocks.  Therefore, the operation of combining two adjacent free blocks can
    386 only happen at most twice.  The variable nFreed counts the number of times
     392only happen at most twice.      The variable nFreed counts the number of times
    387393two blocks are combined.  The function exits if nFreed reaches two.  nFreed
    388394is initially 0.
     
    399405void remove(PMEMBLOCK pmb)
    400406{
    401    PMEMBLOCK pmbPrev;
    402 
    403    if (pmb == pmbFree) {
    404       pmbFree = pmbFree->pmbNext;
    405       return;
    406    }
    407 
    408    for (pmbPrev=pmbFree; pmbPrev; pmbPrev=pmbPrev->pmbNext)
    409       if (pmbPrev->pmbNext == pmb) {
    410          pmbPrev->pmbNext = pmb->pmbNext;
    411          return;
    412       }
     407        PMEMBLOCK pmbPrev;
     408
     409        if (pmb == pmbFree) {
     410                pmbFree = pmbFree->pmbNext;
     411                return;
     412        }
     413
     414        for (pmbPrev=pmbFree; pmbPrev; pmbPrev=pmbPrev->pmbNext)
     415                if (pmbPrev->pmbNext == pmb) {
     416                        pmbPrev->pmbNext = pmb->pmbNext;
     417                        return;
     418                }
    413419}
    414420
    415421void compact(void)
    416422{
    417    PMEMBLOCK pmb;
    418    int iFreed = 0;
    419 
    420    for (pmb=pmbFree->pmbNext; pmb; pmb=pmb->pmbNext) {
    421       if (pmb == pmb->pmbNext) {
    422 //         ddprintf("HEAP: heap loop, %p points to itself\n", (void __far *) pmb);
    423          int3();
    424       }
    425 
    426       if (after(pmb)  == pmbFree) {
    427 // ddprintf("HEAP: compact found pointer %p (size=%ui) before pmbFree %p\n", (void __far *) pmb, pmb->uSize, (void __far *) pmbFree);
    428          pmb->uSize += HDR_SIZE + pmbFree->uSize;
    429          remove(pmbFree);
    430          if (++iFreed == 2) goto exit;
    431       } else if (after(pmbFree) == pmb) {
    432 // ddprintf("HEAP: compact found pointer %p (size=%ui) after pmbFree %p\n", (void __far *) pmb, pmb->uSize, (void __far *) pmbFree);
    433          pmbFree->uSize += HDR_SIZE + pmb->uSize;
    434          remove(pmb);
    435          if (++iFreed == 2) goto exit;
    436       }
    437    }
     423        PMEMBLOCK pmb;
     424        int iFreed = 0;
     425
     426        for (pmb=pmbFree->pmbNext; pmb; pmb=pmb->pmbNext) {
     427                if (pmb == pmb->pmbNext) {
     428#ifdef HEAP_DEBUG
     429                 dprintf(("HEAP:heap loop, %lx points to itself\n", (void __far *) pmb));
     430#endif
     431                 int3();
     432                }
     433
     434                if (after(pmb)  == pmbFree) {
     435#ifdef HEAP_DEBUG
     436                        //dprintf(("HEAP:compact found pointer %lx (size=%x) before pmbFree %lx\n", (void __far *) pmb, pmb->uSize, (void __far *) pmbFree));
     437#endif
     438                        pmb->uSize += HDR_SIZE + pmbFree->uSize;
     439                        remove(pmbFree);
     440                        if (++iFreed == 2) goto exit;
     441                } else if (after(pmbFree) == pmb) {
     442#ifdef HEAP_DEBUG
     443                        //dprintf(("HEAP:compact found pointer %lx (size=%x) after pmbFree %lx\n", (void __far *) pmb, pmb->uSize, (void __far *) pmbFree));
     444#endif
     445                        pmbFree->uSize += HDR_SIZE + pmb->uSize;
     446                        remove(pmb);
     447                        if (++iFreed == 2) goto exit;
     448                }
     449        }
    438450
    439451exit:
    440    nCompact += iFreed;
     452        nCompact += iFreed;
    441453}
    442454
    443455void free(void __near *pvBlock)
    444456{
    445    PMEMBLOCK pmb,pmbPrev,pmbBlock;
    446    int fSentinel;
    447 
    448    ++nFreeCalls;
    449    if (!pvBlock) return;     // support freeing of NULL
    450 
    451    pmbBlock=(PMEMBLOCK) ((char __near *) pvBlock - HDR_SIZE);
    452 
    453    SignatureCheck( pmbBlock,(PSZ) "free() entry, Block to be freed" );
    454    HeapCheck((PSZ) "free() entry" );
    455 
    456    uMemFree += pmbBlock->uSize + HDR_SIZE;
    457 
    458    if (pmbBlock == pmbUsed) {       // are we freeing the first block?
    459       pmbUsed = pmbUsed->pmbNext;   // the 2nd block is now the 1st
    460       pmbBlock->pmbNext = pmbFree;  // this block is now free, so it points to 1st free block
    461       pmbFree = pmbBlock;           // this is now the 1st free block
    462       compact();
    463       goto exit;
    464    }
    465 
    466    pmbPrev=pmbUsed;
    467    fSentinel = FALSE;
    468    for (pmb=pmbUsed->pmbNext; pmb; pmbPrev=pmb, pmb=pmb->pmbNext)
    469       if (pmb == pmbBlock) {
    470          if (fSentinel) {
    471 //            ddprintf("HEAP: free sentinel triggered, pmb=%p\n", (void __far *) pmb);
    472             int3();
    473          }
    474          pmbPrev->pmbNext = pmb->pmbNext;   // delete this block from the chain
    475          pmbBlock->pmbNext = pmbFree;
    476          pmbFree = pmbBlock;
    477          compact();
    478          fSentinel = TRUE;
    479       }
     457        PMEMBLOCK pmb,pmbPrev,pmbBlock;
     458        int fSentinel;
     459
     460        ++nFreeCalls;
     461        if (!pvBlock) return;    // support freeing of NULL
     462
     463        pmbBlock=(PMEMBLOCK) ((char __near *) pvBlock - HDR_SIZE);
     464
     465        SignatureCheck( pmbBlock,(PSZ) "free() entry, Block to be freed" );
     466        HeapCheck((PSZ) "free() entry" );
     467
     468        uMemFree += pmbBlock->uSize + HDR_SIZE;
     469
     470        if (pmbBlock == pmbUsed) {              // are we freeing the first block?
     471                pmbUsed = pmbUsed->pmbNext;     // the 2nd block is now the 1st
     472                pmbBlock->pmbNext = pmbFree;    // this block is now free, so it points to 1st free block
     473                pmbFree = pmbBlock;                     // this is now the 1st free block
     474                compact();
     475                goto exit;
     476        }
     477
     478        pmbPrev=pmbUsed;
     479        fSentinel = FALSE;
     480        for (pmb=pmbUsed->pmbNext; pmb; pmbPrev=pmb, pmb=pmb->pmbNext)
     481                if (pmb == pmbBlock) {
     482                        if (fSentinel) {
     483#ifdef HEAP_DEBUG
     484                                dprintf(("HEAP:free sentinel triggered, pmb=%lx\n", (void __far *) pmb));
     485#endif
     486                                int3();
     487                        }
     488                        pmbPrev->pmbNext = pmb->pmbNext;        // delete this block from the chain
     489                        pmbBlock->pmbNext = pmbFree;
     490                        pmbFree = pmbBlock;
     491                        compact();
     492                        fSentinel = TRUE;
     493                }
    480494
    481495exit: //--- Check things are still intact.
    482    HeapCheck((PSZ) "free() exit" );
     496        HeapCheck((PSZ) "free() exit" );
    483497}
    484498
    485499unsigned _memfree(void)
    486500{
    487    return uMemFree;
     501        return uMemFree;
    488502}
    489503
    490504void __near *realloc(void __near *pvBlock, unsigned usLength)
    491505{
    492    void __near *pv;
    493 
    494    if (!pvBlock)                // if ptr is null, alloc block
    495       return malloc(usLength);
    496 
    497    if (!usLength) {              // if length is 0, free block
    498       free(pvBlock);
    499       return 0;
    500    }
    501 
    502    pv=malloc(usLength);          // attempt to allocate the new block
    503    if (!pv)                      // can't do it?
    504       return 0;                  // just fail.  Version 2 will try harder
    505 
    506    memcpy(pv, pvBlock, min( _msize(pvBlock), usLength));
    507    free(pvBlock);
    508    return pv;
     506        void __near *pv;
     507
     508        if (!pvBlock)                            // if ptr is null, alloc block
     509                return malloc(usLength);
     510
     511        if (!usLength) {                        // if length is 0, free block
     512                free(pvBlock);
     513                return 0;
     514        }
     515
     516        pv=malloc(usLength);            // attempt to allocate the new block
     517        if (!pv)                                        // can't do it?
     518                return 0;                                // just fail.  Version 2 will try harder
     519
     520        memcpy(pv, pvBlock, min( _msize(pvBlock), usLength));
     521        free(pvBlock);
     522        return pv;
    509523}
    510524
     
    513527unsigned HeapInit(unsigned uSize)
    514528{
    515    unsigned max_heap=(unsigned) &end_of_heap - (unsigned) &end_of_data;
    516 
    517    if (!uSize)
    518       uSize = DEFAULT_HEAP;
    519 
    520    if (uSize > max_heap)
    521       uSize = max_heap;
    522 
    523    pmbFree=(PMEMBLOCK) acHeap;
    524    pmbFree->uSize = uSize - HDR_SIZE;
    525    pmbFree->ulSignature = SIGNATURE;
    526    pmbFree->pmbNext = 0;
    527    uMemFree = pmbFree->uSize;
    528    return pmbFree->uSize;
    529 }
     529        unsigned max_heap=(unsigned) &end_of_heap - (unsigned) &end_of_data;
     530
     531        if (!uSize)
     532                uSize = DEFAULT_HEAP;
     533
     534        if (uSize > max_heap)
     535                uSize = max_heap;
     536
     537        pmbFree=(PMEMBLOCK) acHeap;
     538        pmbFree->uSize = uSize - HDR_SIZE;
     539        pmbFree->ulSignature = SIGNATURE;
     540        pmbFree->pmbNext = 0;
     541        uMemFree = pmbFree->uSize;
     542        return pmbFree->uSize;
     543}
  • OCO/trunk/drv16/waudio.cpp

    r483 r496  
    13161316
    13171317#ifdef DEBUG
    1318     dprintf(("WAVEAUDIO::ConfigDev"));
     1318    //dprintf(("WAVEAUDIO::ConfigDev"));
    13191319#endif
    13201320    //Reset sample rate conversion position
     
    13781378    }
    13791379    pConfigInfo->ulBytesPerIRQ = ulBytesPerIRQ;
    1380     dprintf(("WAVEAUDIO::ConfigDev BytesPerIRQ:%ld",ulBytesPerIRQ));
     1380    dprintf4(("WAVEAUDIO::ConfigDev BytesPerIRQ:%ld",ulBytesPerIRQ));
    13811381
    13821382
  • OCO/trunk/include/dbgos2.h

    r483 r496  
    2424#define dprintf3(a) if(dbglevel >= 3) PrintfOut a
    2525#define dprintf4(a) if(dbglevel >= 4) PrintfOut a
    26 #define ddprintf(a) if(dbglevel >= 1) PrintfOut a
    27 #define dgprintf(a) if(dbglevel >= 1) PrintfOut a
    2826#else
    2927#define dprintf(a)  //if(dbglevel >= 1) PrintfOut a
     
    3129#define dprintf3(a) //if(dbglevel >= 3) PrintfOut a
    3230#define dprintf4(a) //if(dbglevel >= 4) PrintfOut a
    33 #define ddprintf(a) //if(dbglevel >= 1) PrintfOut a
    34 #define dgprintf(a) //if(dbglevel >= 1) PrintfOut a
    3531#endif
    3632
Note: See TracChangeset for help on using the changeset viewer.