Changeset 509


Ignore:
Timestamp:
Jul 11, 2010, 5:32:48 PM (15 years ago)
Author:
David Azarewicz
Message:

Malloc fixes

Location:
OCO/trunk
Files:
2 edited

Legend:

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

    r496 r509  
    11/* $Id: malloc.c,v 1.1.1.1 2003/07/02 13:57:06 eleph Exp $ */
    22
    3 /* SCCSID = %W% %E% */
    43/****************************************************************************
    54 *                                                                                                                                                      *
     
    1211 *                                                                                                                                                      *
    1312 ****************************************************************************/
    14 /**@internal %W%
     13/*
    1514 *      Implementation of the driver's built in memory management.
    16  * @version %I%
    1715 * @context
    1816 *      Unless otherwise noted, all interfaces are Ring-3 and Ring-0, 16-bit,
     
    2018 * @notes
    2119 * @history
    22  *      01-Jul-95  Timur Tabi   Creation
     20 *      01-Jul-95       Timur Tabi              Creation
     21 *  05-Jul-2010 David Azarewicz Major code rework
    2322 */
    2423
     
    2726#include <include.h>
    2827#include <dbgos2.h>
     28#include <devhelp.h>
    2929#include "end.h"
    3030#include "sizedefs.h"                                   // HEAP_SIZE, DEFAULT_HEAP.
     
    3333#define HEAP_DEBUG
    3434#endif
    35 #define  SIGNATURE              0xBEEFDEAD              // "DeadBeef" when view in hex in word order.
     35#define  SIGNATURE              0xBEEFDEAD
    3636
    3737typedef struct _MEMBLOCK {
    3838        unsigned long ulSignature;
    39         unsigned uSize;
     39        unsigned short usSize;
    4040        struct _MEMBLOCK *pmbNext;
    4141        char achBlock[1];
     
    5555                                                // Newly allocated blocks are inserted into head of list.
    5656PMEMBLOCK pmbFree;              // Points to head of list of available memory blocks.
    57 unsigned uMemFree;              // N bytes available for allocation.
     57USHORT usMemFree;               // N bytes available for allocation.
     58USHORT usUnused;
     59
     60/* HeapCheck global variables */
     61USHORT usnAlloc = 0;            // Current number of allocated blocks.
     62USHORT uscAlloc = 0;            // Total memory in allocated blocks incl. headers.
     63USHORT usnAllocCalls = 0;       // Cumulative total, number of malloc() calls.
     64USHORT usnFree  = 0;            // Current number of free blocks.
     65USHORT uscFree  = 0;            // Total memory in free blocks incl. headers.
     66USHORT usnFreeCalls  = 0;       // Cumulative total, number of free() calls.
     67USHORT usnCompact = 0;          // Num of times we've joined two adjacent free blocks into a single larger block.
     68USHORT uscTotalHeap = HEAP_SIZE;
     69
    5870char __near acHeap[HEAP_SIZE] = {0};    // The heap.    NOTE:  This must be the last data definition in the HEAP segment,
    5971                                                // although not done currently, we are planning to size the heap down at INIT
     
    6678void dumpheap(void)
    6779{
    68         int i;
     80        SHORT sI;
    6981        PMEMBLOCK pmb;
    70         unsigned u=0;
    71 
     82        USHORT usSize;
     83
     84        usSize=0;
    7285        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;
     86        dprintf(("HEAP:Heap Dump acHeap=%lx Used=%x Free=%x\n", (void __far *)acHeap, pmbUsed, pmbFree));
     87        dprintf(("Used blocks\n"));
     88        for (sI=0; sI<10; sI++) {
     89                dprintf(("  pmb=%lx, length=%x\n",(void __far *) pmb, pmb->usSize));
     90                usSize+=pmb->usSize;
    7791                pmb=pmb->pmbNext;
    7892                if (!pmb) break;
    7993        }
    80         dprintf(("  Total used = %x\n",u));
    81 
    82         u=0;
     94        dprintf(("  Total used = %x\n", usSize));
     95
     96        usSize=0;
    8397        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;
     98        dprintf(("Free blocks\n"));
     99        for (sI=0; sI<50; sI++) {
     100                dprintf(("  pmb=%lx, length=%x\n",(void __far *) pmb, pmb->usSize));
     101                usSize+=pmb->usSize;
    88102                pmb=pmb->pmbNext;
    89103                if (!pmb) break;
    90104        }
    91         dprintf(("  Total free = %x\n",u));
    92 }
    93 #endif
    94 
    95 USHORT fMemoryDoc = 1;
    96 USHORT nAlloc = 0;                       // Current number of allocated blocks.
    97 USHORT cAlloc = 0;                       // Total memory in allocated blocks incl. headers.
    98 USHORT nAllocCalls = 0;          // Cumulative total, number of malloc() calls.
    99 USHORT nFree  = 0;                       // Current number of free blocks.
    100 USHORT cFree  = 0;                       // Total memory in free blocks incl. headers.
    101 USHORT nFreeCalls  = 0;          // Cumulative total, number of free() calls.
    102 USHORT nCompact = 0;             // Num of times we've joined two adjacent free
    103                                                          // blocks into a single larger block.
    104 USHORT cTotalHeap = HEAP_SIZE;
     105        dprintf(("  Total free = %x\n", usSize));
     106}
     107#endif
     108
    105109
    106110void SignatureCheck ( PMEMBLOCK p, PSZ idText )
    107111{
    108         bool bGoodPointer;
     112        SHORT sGoodPointer;
    109113
    110114        // Set bGoodPointer to indicate whether or not 'p' points within heap.
    111         bGoodPointer = (((USHORT) p) >= ((USHORT) acHeap))
     115        sGoodPointer = (((USHORT) p) >= ((USHORT) acHeap))
    112116                                  && (((USHORT) p) <= (((USHORT) acHeap) + HEAP_SIZE)) ;
    113                                                           //### heap might have less than HEAP_SIZE bytes
     117                                  //### heap might have less than HEAP_SIZE bytes
    114118
    115119        // Check for correct signature.
    116         if (bGoodPointer)
    117                 bGoodPointer = (p->ulSignature == SIGNATURE);
    118 
    119         if (! bGoodPointer)
    120         {
     120        if (sGoodPointer) sGoodPointer = (p->ulSignature == SIGNATURE);
     121
     122        if (!sGoodPointer) {
     123                dprintf(( "SignatureCheck: Bad pointer %lx %s\n", p, idText ));
     124                int3();
     125        }
     126}
     127
     128void HeapCheck ( PSZ idText )
     129{
     130        PMEMBLOCK p;
     131        for ( usnAlloc = 0, uscAlloc = 0, p = pmbUsed; p; p = p->pmbNext ) {
     132                ++usnAlloc;
     133                uscAlloc += p->usSize + HDR_SIZE;
     134                SignatureCheck( p,(PSZ) "HeapCheck: Used list" );
     135                if (p == p->pmbNext) {
     136                        dprintf(("HeapCheck: used %lx points to itself\n", p));
     137                        int3();
     138                }
     139        }
     140        for ( usnFree = 0, uscFree = 0, p = pmbFree; p; p = p->pmbNext ) {
     141                ++usnFree;
     142                uscFree += p->usSize + HDR_SIZE;
     143                SignatureCheck( p,(PSZ) "HeapCheck: Free list" );
     144                if (p == p->pmbNext) {
     145                        dprintf(("HeapCheck: free %lx points to itself\n", p));
     146                        int3();
     147                }
     148        }
     149        if (uscAlloc + uscFree != uscTotalHeap) {
     150                dprintf(( "HeapCheck: Alloc+Free != Total\n" ));
    121151#ifdef HEAP_DEBUG
    122                 dprintf(( "Heap pointer out of range or signature exception: %lx %s\n", p, idText ));
     152                dumpheap();
    123153#endif
    124154                int3();
    125         }
    126 }
    127 
    128 void HeapCheck ( PSZ idText )
    129 {
    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                 }
    149155        }
    150156}
     
    155161#define MIN_Leftover (HDR_SIZE + MIN_FragSize)
    156162
    157 /* make_new_free()
     163/**@internal pmbAllocateBlock
    158164        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.
     165        "Free" MEMBLOCK.
    169166
    170167The fragmentation consideration comes into play when we find a block that's
     
    175172   |  free    |                                                            |
    176173   |  block   |      space available                                       |
    177    |  header  |        (pmbFree->uSize bytes long)                         |
     174   |  header  |        (pmbFree->usSize bytes long)                        |
    178175   |(HDR_SIZE |                                                            |
    179176   |__bytes)__|____________________________________________________________|
     
    183180Must either be allocated in total, or must become:
    184181
    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)__|___________|
     182   _______________________used block________________________________________
     183   |  used    |                                      |  free    |           |
     184   |  block   |  space allocated                     |  block   | space     |
     185   |  header  |  == usSize (following DWORD align't) |  header  | available |
     186   |(HDR_SIZE |    (pmbUsed->usSize bytes long)      |(HDR_SIZE |           |
     187   |__bytes)__|______________________________________|__bytes)__|___________|
    191188
    192189   <-- HDR --> <-------------- n ------------------><-- HDR --> <--- m ----->
     
    208205  We split the block into an allocated part to satisfy the allocation request,
    209206  and a free block which can be allocated in a subsequent request.
    210 */
    211 
    212 PMEMBLOCK make_new_free(PMEMBLOCK pmbOldFree, unsigned uRequest)
    213 {
    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;
    237 }
    238 
    239 
    240 /**@internal _msize
    241  */
    242 unsigned _msize(void __near *pvBlock)
    243 {
    244         PMEMBLOCK pmb;
    245 
    246         if (!pvBlock) return 0;
    247 
    248         pmb = (PMEMBLOCK) ((char __near *) pvBlock - HDR_SIZE);
    249 
    250         return pmb->uSize;
    251 }
    252 
    253 
    254 /**@internal pmbAllocateBlock
     207
     208
     209
    255210 *      Update all data structures for allocation of one memory block.  It's
    256211 *      assumed, on entry, that the block is large enough for the requested
     
    267222 */
    268223void __near *
    269 npvAllocateBlock( PMEMBLOCK pmb, USHORT uRequest, PMEMBLOCK pmbPrev )
     224npvAllocateBlock( PMEMBLOCK pmb, USHORT usRequest, PMEMBLOCK pmbPrev )
    270225{
    271226        //pmb points to the selected block.
     
    275230
    276231        // Split this block into an allocated + free part if it's big enough.
    277         pmbNewFree = make_new_free( pmb, uRequest );
     232        pmbNewFree = 0;
     233        if (pmb->usSize >= (usRequest + MIN_Leftover)) {
     234                // We've got enough leftover to make a new free block.
     235
     236                /* create the new free block */
     237                pmbNewFree = (PMEMBLOCK) ((char __near *) pmb + HDR_SIZE + usRequest );
     238                pmbNewFree->ulSignature = SIGNATURE;
     239                pmbNewFree->usSize = pmb->usSize - (usRequest + HDR_SIZE);
     240                pmbNewFree->pmbNext = pmb->pmbNext;
     241
     242                // Update the size of the original free block that was passed in.
     243                pmb->usSize -= (pmbNewFree->usSize + HDR_SIZE);
     244        }
    278245
    279246        // Update global memory counter.
    280         uMemFree -= (pmb->uSize + HDR_SIZE);
     247        usMemFree -= (pmb->usSize + HDR_SIZE);
    281248
    282249        // Add this block into the front of the Allocated list.
     
    286253
    287254        // Remove the new allocation from the Free list.
    288         if (pmbNewFree) {                               // If we split off a new free block
     255        if (pmbNewFree) { // If we split off a new free block
    289256                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;
     257                if (pmbPrev) pmbPrev->pmbNext = pmbNewFree; // If we're not at head of Free list
     258                else pmbFree = pmbNewFree;
     259        } else { // We allocated the entire free block.
     260                if (pmbPrev) pmbPrev->pmbNext = pmbOldNext; // If we're not at head of Free list
     261                else pmbFree = pmbOldNext;
    300262        }
    301263
     
    306268/* malloc()
    307269This function searches the list of free blocks until it finds one big enough
    308 to hold the amount of memory requested, which is passed in uSize.  The uSize
     270to hold the amount of memory requested, which is passed in usSize.  The usSize
    309271request is sized up for:
    310272  - a memory block header
     
    315277*/
    316278
    317 void __near *malloc( unsigned uSize )
    318 {
    319         USHORT uRequest;                                        // Request size after alignment.
     279void __near *malloc( USHORT usSize )
     280{
     281        USHORT usRequest;                                       // Request size after alignment.
    320282        PMEMBLOCK pmb, pmbPrev;                         // Use to walk free lists.
    321         void __near *npvReturn = 0;                     // Return value.
    322 
    323         ++nAllocCalls;                                          // Diagnostics.
     283        void __near *npvReturn;                         // Return value.
     284        USHORT usCpuFlags;
     285
     286        npvReturn = 0;
     287        ++usnAllocCalls;                                                // Diagnostics.
     288
     289        if (! usSize) return 0;
     290    usCpuFlags = DevPushfCli();
    324291        HeapCheck((PSZ) "malloc() entry" );
    325292
    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         {
     293        usRequest = (usSize + 3) & -4;          // Force DWORD alignment.
     294
     295        for (pmbPrev=NULL, pmb=pmbFree; pmb; pmbPrev=pmb, pmb=pmb->pmbNext) {
     296                if (pmb->usSize >= usRequest) {
     297                        npvReturn = npvAllocateBlock(pmb, usRequest, pmbPrev);
     298                        break;
     299                }
     300        }
     301
     302        if (npvReturn) {
    349303                SignatureCheck( (PMEMBLOCK) (((PUCHAR) npvReturn) - HDR_SIZE), (PSZ) "malloc() exit, allocated block" );
    350         }
    351         else
    352         {
    353                 // Out of Memory !!!
    354                 int3();
     304        } else {
     305                dprintf(("malloc: out of memory"));
     306#ifdef HEAP_DEBUG
     307                dumpheap();
     308#endif
     309                int3(); // Out of Memory !!!
    355310        }
    356311
    357312        HeapCheck((PSZ) "malloc() exit" );
     313    DevPopf(usCpuFlags);
    358314        return npvReturn;
    359315}
     
    390346Also, the newly freed block can only be adjacent to at most two other
    391347blocks.  Therefore, the operation of combining two adjacent free blocks can
    392 only happen at most twice.      The variable nFreed counts the number of times
    393 two blocks are combined.  The function exits if nFreed reaches two.  nFreed
     348only happen at most twice.      The variable usnFreed counts the number of times
     349two blocks are combined.  The function exits if usnFreed reaches two.  usnFreed
    394350is initially 0.
    395351
     
    401357*/
    402358
    403 #define after(pmb) ((PMEMBLOCK) ((char __near *) pmb + pmb->uSize + HDR_SIZE))
     359#define after(pmb) ((PMEMBLOCK) ((char __near *) pmb + pmb->usSize + HDR_SIZE))
    404360
    405361void remove(PMEMBLOCK pmb)
     
    412368        }
    413369
    414         for (pmbPrev=pmbFree; pmbPrev; pmbPrev=pmbPrev->pmbNext)
     370        for (pmbPrev=pmbFree; pmbPrev; pmbPrev=pmbPrev->pmbNext) {
    415371                if (pmbPrev->pmbNext == pmb) {
    416372                        pmbPrev->pmbNext = pmb->pmbNext;
    417373                        return;
    418374                }
     375        }
    419376}
    420377
     
    422379{
    423380        PMEMBLOCK pmb;
    424         int iFreed = 0;
    425 
     381        SHORT sFreed;
     382
     383        sFreed = 0;
    426384        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 
    434385                if (after(pmb)  == pmbFree) {
    435386#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;
     387                        //dprintf(("HEAP:compact found pointer %lx (size=%x) before pmbFree %lx\n", (void __far *) pmb, pmb->usSize, (void __far *) pmbFree));
     388#endif
     389                        pmb->usSize += HDR_SIZE + pmbFree->usSize;
    439390                        remove(pmbFree);
    440                         if (++iFreed == 2) goto exit;
     391                        if (++sFreed == 2) break;
    441392                } else if (after(pmbFree) == pmb) {
    442393#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;
     394                        //dprintf(("HEAP:compact found pointer %lx (size=%x) after pmbFree %lx\n", (void __far *) pmb, pmb->usSize, (void __far *) pmbFree));
     395#endif
     396                        pmbFree->usSize += HDR_SIZE + pmb->usSize;
    446397                        remove(pmb);
    447                         if (++iFreed == 2) goto exit;
    448                 }
    449         }
    450 
    451 exit:
    452         nCompact += iFreed;
     398                        if (++sFreed == 2) break;
     399                }
     400        }
     401
     402        usnCompact += sFreed;
    453403}
    454404
    455405void free(void __near *pvBlock)
    456406{
    457         PMEMBLOCK pmb,pmbPrev,pmbBlock;
    458         int fSentinel;
    459 
    460         ++nFreeCalls;
     407        PMEMBLOCK pmb, pmbPrev, pmbBlock;
     408        USHORT usCpuFlags;
     409
     410        ++usnFreeCalls;
    461411        if (!pvBlock) return;    // support freeing of NULL
    462412
    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();
     413        pmbBlock = (PMEMBLOCK) ((char __near *) pvBlock - HDR_SIZE);
     414
     415    usCpuFlags = DevPushfCli();
     416        SignatureCheck(pmbBlock, (PSZ) "free() entry, Block to be freed");
     417        HeapCheck((PSZ) "free() entry");
     418
     419        usMemFree += pmbBlock->usSize + HDR_SIZE;
     420
     421        /* find the block on the used chain */
     422        for (pmbPrev=NULL, pmb=pmbUsed; pmb; pmbPrev=pmb, pmb=pmb->pmbNext) {
     423                if (pmb == pmbBlock) { /* found the block */
     424                        if (pmbPrev) { /* it is in the middle of the chain */
     425                                pmbPrev->pmbNext = pmb->pmbNext; /* delete this block from the chain */
     426                        } else { /* it is the first block on the used list */
     427                                pmbUsed = pmbUsed->pmbNext;     // the 2nd block is now the head
    487428                        }
    488                         pmbPrev->pmbNext = pmb->pmbNext;        // delete this block from the chain
    489                         pmbBlock->pmbNext = pmbFree;
    490                         pmbFree = pmbBlock;
    491                         compact();
    492                         fSentinel = TRUE;
    493                 }
    494 
    495 exit: //--- Check things are still intact.
     429                        pmbBlock->pmbNext = pmbFree; /* This block is now free, so it points to the first free block */
     430                        pmbFree = pmbBlock; /* This is now the first free block */
     431                        break;
     432                }
     433        }
     434        if (pmb == 0) {
     435                dprintf(("free: block not found %x\n", pmb));
     436                int3();
     437        }
     438        compact();
     439
    496440        HeapCheck((PSZ) "free() exit" );
     441    DevPopf(usCpuFlags);
    497442}
    498443
    499444unsigned _memfree(void)
    500445{
    501         return uMemFree;
    502 }
    503 
    504 void __near *realloc(void __near *pvBlock, unsigned usLength)
     446        return usMemFree;
     447}
     448
     449/**@internal _msize
     450 */
     451unsigned _msize(void __near *pvBlock)
     452{
     453        PMEMBLOCK pmb;
     454
     455        if (!pvBlock) return 0;
     456
     457        pmb = (PMEMBLOCK) ((char __near *) pvBlock - HDR_SIZE);
     458
     459        return pmb->usSize;
     460}
     461
     462void __near *realloc(void __near *pvBlock, USHORT usLength)
    505463{
    506464        void __near *pv;
     
    525483#pragma code_seg ("_inittext");
    526484
    527 unsigned HeapInit(unsigned uSize)
    528 {
    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;
     485USHORT HeapInit(USHORT usSize)
     486{
     487        unsigned max_heap=(USHORT) &end_of_heap - (USHORT) &end_of_data;
     488
     489        if (!usSize) usSize = DEFAULT_HEAP;
     490
     491        if (usSize > max_heap) usSize = max_heap;
    536492
    537493        pmbFree=(PMEMBLOCK) acHeap;
    538         pmbFree->uSize = uSize - HDR_SIZE;
     494        pmbFree->usSize = usSize - HDR_SIZE;
    539495        pmbFree->ulSignature = SIGNATURE;
    540496        pmbFree->pmbNext = 0;
    541         uMemFree = pmbFree->uSize;
    542         return pmbFree->uSize;
    543 }
     497        usMemFree = pmbFree->usSize;
     498        return pmbFree->usSize;
     499}
  • OCO/trunk/include/devhelp.h

    r132 r509  
    55#define DEVHELP_INCLUDED
    66
    7 #ifdef __WATCOMC__ 
     7#ifdef __WATCOMC__
    88
    99#ifndef OS2_INCLUDED
     
    3434   "error:" \
    3535   value [ax]
     36
     37USHORT DevPushfCli();
     38#pragma aux DevPushfCli =       \
     39  "pushf"                       \
     40  "cli"                         \
     41  "pop ax"                      \
     42  value [ax];
     43
     44VOID DevPopf(USHORT cpuflags);
     45#pragma aux DevPopf =           \
     46  "push ax"                     \
     47  "popf"                        \
     48   parm [ax];
     49
    3650
    3751USHORT DevHelp_ABIOSCall(USHORT Lid, NPBYTE ReqBlk, USHORT Entry_Type);
     
    244258
    245259typedef struct _SELDESCINFO {
    246   UCHAR    Type;                       
    247   UCHAR    Granularity;                 
    248   LIN      BaseAddr;                   
    249   ULONG    Limit;                       
    250 } SELDESCINFO, __far *PSELDESCINFO; 
    251                                        
    252 typedef struct _GATEDESCINFO {         
    253   UCHAR    Type;                       
    254   UCHAR    ParmCount;                   
    255   SEL      Selector;                   
    256   USHORT   Reserved_1;                 
    257   ULONG    Offset;                     
     260  UCHAR    Type;
     261  UCHAR    Granularity;
     262  LIN      BaseAddr;
     263  ULONG    Limit;
     264} SELDESCINFO, __far *PSELDESCINFO;
     265
     266typedef struct _GATEDESCINFO {
     267  UCHAR    Type;
     268  UCHAR    ParmCount;
     269  SEL      Selector;
     270  USHORT   Reserved_1;
     271  ULONG    Offset;
    258272} GATEDESCINFO, __far *PGATEDESCINFO;
    259273
     
    385399
    386400/* DevHelp_MonWrite has one change compared to the original specification.
    387    The DataRecord parameter was originally a far (16:16) pointer.  It has 
     401   The DataRecord parameter was originally a far (16:16) pointer.  It has
    388402   been changed to a near pointer because DS must point to the default data
    389    segment and therefore the DataRecord parameter must be near.  This 
     403   segment and therefore the DataRecord parameter must be near.  This
    390404   allows the compiler to catch the error.
    391405*/
     
    445459   modify exact [ax cx dx di];
    446460
    447 /* NOTE: After the DevHelp call, SI contains the modified selector. However, 
     461/* NOTE: After the DevHelp call, SI contains the modified selector. However,
    448462   the C interface has no provisions for returning this value to the caller.
    449463   You can, however, use the _SI() inline function defined in include.h.
     
    944958#define VMDHA_RESERVE           0x0100                               /*@V76282*/
    945959#define VMDHA_USEHIGHMEM        0x0800                               /*@V76282*/
    946  
     960
    947961USHORT DevHelp_VMAlloc(ULONG Flags, ULONG Size, ULONG PhysAddr, PLIN LinearAddr, PPVOID SelOffset);
    948962#pragma aux DevHelp_VMAlloc = \
Note: See TracChangeset for help on using the changeset viewer.