Changeset 496
- Timestamp:
- Jul 3, 2010, 7:44:25 PM (15 years ago)
- Location:
- OCO/trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
OCO/trunk/drv16/malloc.c
r478 r496 3 3 /* SCCSID = %W% %E% */ 4 4 /**************************************************************************** 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 * 9 9 * 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 * * 13 13 ****************************************************************************/ 14 14 /**@internal %W% 15 * 15 * Implementation of the driver's built in memory management. 16 16 * @version %I% 17 17 * @context 18 * 19 * 18 * Unless otherwise noted, all interfaces are Ring-3 and Ring-0, 16-bit, 19 * kernel stack. 20 20 * @notes 21 21 * @history 22 * 01-Jul-95 Timur TabiCreation22 * 01-Jul-95 Timur Tabi Creation 23 23 */ 24 24 25 25 #include <os2.h> 26 #include <string.h> 26 #include <string.h> // memcpy(), memset() 27 27 #include <include.h> 28 #include <dbgos2.h> 28 29 #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. 33 36 34 37 typedef struct _MEMBLOCK { 35 36 37 38 38 unsigned long ulSignature; 39 unsigned uSize; 40 struct _MEMBLOCK *pmbNext; 41 char achBlock[1]; 39 42 } MEMBLOCK, __near *PMEMBLOCK; 40 43 … … 49 52 //--- Global Variables used to manage the heap: 50 53 // 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. 54 PMEMBLOCK pmbUsed=0; // Points to head of list of allocated memory blocks. 55 // Newly allocated blocks are inserted into head of list. 56 PMEMBLOCK pmbFree; // Points to head of list of available memory blocks. 57 unsigned uMemFree; // N bytes available for allocation. 58 char __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. 60 62 61 63 //--- Heap methods: 62 64 65 #ifdef HEAP_DEBUG 63 66 void dumpheap(void) 64 67 { 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 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. 100 104 USHORT cTotalHeap = HEAP_SIZE; 101 105 102 106 void SignatureCheck ( PMEMBLOCK p, PSZ idText ) 103 107 { 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 } 121 126 } 122 127 123 128 void HeapCheck ( PSZ idText ) 124 129 { 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 } 143 150 } 144 151 … … 146 153 147 154 // Threshold for creating a new free block. 148 #define MIN_Leftover(HDR_SIZE + MIN_FragSize)155 #define MIN_Leftover (HDR_SIZE + MIN_FragSize) 149 156 150 157 /* make_new_free() 151 152 153 IN:pmbOldFree - pointer to existing memory block.154 155 156 OUT:pointer to new free MEMBLOCK, is a new block of free memory,157 158 159 160 OUT:NULL if the new free memory block is smaller than the161 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. 162 169 163 170 The fragmentation consideration comes into play when we find a block that's … … 165 172 part to be useful as another free block. 166 173 167 168 | free | 169 | block | 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)__|____________________________________________________________| 173 180 174 181 <-- HDR --> <------------------------- l --------------------------------> … … 176 183 Must either be allocated in total, or must become: 177 184 178 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)__|___________| 184 191 185 192 <-- HDR --> <-------------- n ------------------><-- HDR --> <--- m -----> … … 205 212 PMEMBLOCK make_new_free(PMEMBLOCK pmbOldFree, unsigned uRequest) 206 213 { 207 PMEMBLOCK pmbNewFree;// If we create a new free block, it goes here.208 209 210 211 212 213 214 // Not enough leftover, allocate the entire free block.Don't215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 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; 230 237 } 231 238 … … 235 242 unsigned _msize(void __near *pvBlock) 236 243 { 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; 245 251 } 246 252 247 253 248 254 /**@internal pmbAllocateBlock 249 * Update all data structures for allocation of one memory block.It's250 * 251 * 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. 252 258 * @param PMEMBLOCK pmb - the current memory block on the Free list to 253 * 259 * allocate. 254 260 * @param USHORT uRequest - size of the memory request to fill, not counting 255 * 261 * memory block header. 256 262 * @param PMEMBLOCK pmbPrev - the memory block which precedes the block being 257 * 258 * 263 * allocated in the Free list. NULL if no predecessor (ie, pmb is pointed to 264 * by ::pmbFree). 259 265 * @return PMEMBLOCK - pointer to the data part of the allocated memory block, 260 * 266 * suitable for return to malloc() caller. 261 267 */ 262 268 void __near * 263 269 npvAllocateBlock( PMEMBLOCK pmb, USHORT uRequest, PMEMBLOCK pmbPrev ) 264 270 { 265 266 267 PMEMBLOCK pmbOldNext;// Original free block that follows the block being allocated.268 PMEMBLOCK pmbNewFree;// Leftover free memory from the allocated block.269 270 271 272 273 274 275 276 277 278 279 280 281 282 if (pmbNewFree) {// If we split off a new free block283 284 if (pmbPrev)// If we're not at head of Free list285 286 287 288 289 else {// We allocated the entire free block.290 if (pmbPrev)// If we're not at head of Free list291 292 293 294 295 296 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; 297 303 } 298 304 … … 311 317 void __near *malloc( unsigned uSize ) 312 318 { 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 319 320 321 322 uRequest = (uSize + 3) & -4;// Force DWORD alignment.323 324 325 326 327 328 else 329 330 331 332 333 if (pmb->uSize >= uRequest) 334 335 336 337 338 339 340 341 342 343 344 345 else 346 347 348 349 350 351 352 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; 353 359 } 354 360 … … 356 362 This function compacts the free blocks together. This function is a 357 363 companion to free(), and thus the algorithm is tailored to how free() 358 works. 364 works. Change the algorithm in free(), and you'll have to change this 359 365 function too. 360 366 … … 373 379 3. Physically after another free block 374 380 4. Between two free blocks (i.e. the block occupies the entire space 375 381 between two free blocks) 376 382 377 383 Since the newly freed block is the first in the free list, compact() 378 384 starts with the second block in the list (i.e. pmbFree->pmbNext). 379 385 Each free block is then compared with the newly freed block for 380 adjacency. 386 adjacency. If a given block is located before the new block, then it 381 387 can't possibly be also located after, and vice versa. Hence, the 382 388 "else if" statement in the middle of the loop. … … 384 390 Also, the newly freed block can only be adjacent to at most two other 385 391 blocks. Therefore, the operation of combining two adjacent free blocks can 386 only happen at most twice. 392 only happen at most twice. The variable nFreed counts the number of times 387 393 two blocks are combined. The function exits if nFreed reaches two. nFreed 388 394 is initially 0. … … 399 405 void remove(PMEMBLOCK pmb) 400 406 { 401 402 403 404 405 406 407 408 409 410 411 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 } 413 419 } 414 420 415 421 void compact(void) 416 422 { 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 } 438 450 439 451 exit: 440 452 nCompact += iFreed; 441 453 } 442 454 443 455 void free(void __near *pvBlock) 444 456 { 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 } 480 494 481 495 exit: //--- Check things are still intact. 482 496 HeapCheck((PSZ) "free() exit" ); 483 497 } 484 498 485 499 unsigned _memfree(void) 486 500 { 487 501 return uMemFree; 488 502 } 489 503 490 504 void __near *realloc(void __near *pvBlock, unsigned usLength) 491 505 { 492 493 494 if (!pvBlock)// if ptr is null, alloc block495 496 497 if (!usLength) {// if length is 0, free block498 499 500 501 502 pv=malloc(usLength);// attempt to allocate the new block503 if (!pv)// can't do it?504 return 0; // just fail.Version 2 will try harder505 506 507 508 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; 509 523 } 510 524 … … 513 527 unsigned HeapInit(unsigned uSize) 514 528 { 515 516 517 518 519 520 521 522 523 524 525 526 527 528 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 1316 1316 1317 1317 #ifdef DEBUG 1318 dprintf(("WAVEAUDIO::ConfigDev"));1318 //dprintf(("WAVEAUDIO::ConfigDev")); 1319 1319 #endif 1320 1320 //Reset sample rate conversion position … … 1378 1378 } 1379 1379 pConfigInfo->ulBytesPerIRQ = ulBytesPerIRQ; 1380 dprintf (("WAVEAUDIO::ConfigDev BytesPerIRQ:%ld",ulBytesPerIRQ));1380 dprintf4(("WAVEAUDIO::ConfigDev BytesPerIRQ:%ld",ulBytesPerIRQ)); 1381 1381 1382 1382 -
OCO/trunk/include/dbgos2.h
r483 r496 24 24 #define dprintf3(a) if(dbglevel >= 3) PrintfOut a 25 25 #define dprintf4(a) if(dbglevel >= 4) PrintfOut a 26 #define ddprintf(a) if(dbglevel >= 1) PrintfOut a27 #define dgprintf(a) if(dbglevel >= 1) PrintfOut a28 26 #else 29 27 #define dprintf(a) //if(dbglevel >= 1) PrintfOut a … … 31 29 #define dprintf3(a) //if(dbglevel >= 3) PrintfOut a 32 30 #define dprintf4(a) //if(dbglevel >= 4) PrintfOut a 33 #define ddprintf(a) //if(dbglevel >= 1) PrintfOut a34 #define dgprintf(a) //if(dbglevel >= 1) PrintfOut a35 31 #endif 36 32
Note:
See TracChangeset
for help on using the changeset viewer.