_CRTIMP size_t __cdecl _heapused(size_t *pUsed, size_t *pCommit) #endif /* _MT */ { _PBLKDESC p; _PBLKDESC next; int index ; size_t usedbytes; /* bytes devoted to in-use blocks */ size_t freebytes; /* bytes devoted to free blocks */ size_t rsrvbytes; /* total bytes of reserved address space */ void * * pageptr ; if ( (p = _heap_desc.pfirstdesc) == NULL || _heap_desc.pfirstdesc == &_heap_desc.sentinel ) { return 0 ; /* invalid heap */ } /* * Scan through the heap, counting free and used blocks. * Include the overhead of each block and its heap descriptor. */ freebytes = 0 ; usedbytes = 0 ; while (p != NULL) { next = p->pnextdesc; if (p == &_heap_desc.sentinel) { if (next != NULL) { return 0 ; } } else if (_IS_FREE(p)) { freebytes += _BLKSIZE(p) + _HDRSIZE; } else if (_IS_INUSE(p)) { usedbytes += _BLKSIZE(p) + _HDRSIZE; } p = next; } /* * Now we need to count the pages used for descriptors as reserved memory. * _heap_descpages points to the head of a singly-linked list of the pages. * The descriptors for in-use blocks are considered in-use memory. */ pageptr = _heap_descpages; rsrvbytes = 0 ; while ( pageptr ) { rsrvbytes += _HEAP_EMPTYLIST_SIZE ; pageptr = * pageptr ; } usedbytes += rsrvbytes ; /* * Loop through the region descriptor table */ for ( index=0 ; index < _HEAP_REGIONMAX ; index++ ) { rsrvbytes += _heap_regions[index]._totalsize ; } if ( pUsed ) * pUsed = usedbytes ; if ( pCommit ) * pCommit = freebytes + usedbytes ; return rsrvbytes ; }
void __cdecl _heap_print_heaplist(void) { _PBLKDESC p; _PBLKDESC next; int i; int error = 0; printf("\n--- Heap Descriptor List ---\n\n"); if ((p = _heap_desc.pfirstdesc) == NULL) { printf("\t *** List is empty ***\n"); return; } for (i=1; p != NULL; i++) { next = p->pnextdesc; /* Print descriptor address */ printf("\t(%i) Address = %p ", i, p); if (p == &_heap_desc.sentinel) printf("<SENTINEL>\n"); else if (p == _heap_desc.proverdesc) printf("<ROVER>\n"); else printf("\n"); /* Print descriptor contents */ printf("\t\tpnextdesc = %p, pblock = %p", p->pnextdesc, p->pblock); if (p == &_heap_desc.sentinel) { if (next != NULL) { printf("\n\t*** ERROR: sentinel.pnextdesc != NULL ***\n"); error++; } } else if (_IS_INUSE(p)) printf(", usersize = %u <INUSE>", _BLKSIZE(p)); else if (_IS_FREE(p)) printf(", usersize = %u <FREE>", _BLKSIZE(p)); else if (_IS_DUMMY(p)) printf(", size = %u <DUMMY>", _MEMSIZE(p)); else { printf(",\n\t*** ERROR: unknown status ***\n"); error++; } printf("\n\n"); if (_heap_desc.pfirstdesc == &_heap_desc.sentinel) { printf("[No memory in heap]\n"); } p = next; } if (error) printf("\n\t *** ERRORS IN HEAP TABLE ***\n"); printf("\t--- End of table ---\n"); }
static int __cdecl _heap_checkset ( unsigned int _fill ) { REG1 _PBLKDESC pdesc; REG2 _PBLKDESC pnext; int roverfound=0; int retval = _HEAPOK; /* * lock the heap */ _mlock(_HEAP_LOCK); /* * Validate the sentinel */ if (_heap_desc.sentinel.pnextdesc != NULL) { _PRINTERR(_BADSENTINEL); retval = _HEAPBADNODE; goto done; } /* * Test for an empty heap */ if ( (_heap_desc.pfirstdesc == &_heap_desc.sentinel) && (_heap_desc.proverdesc == &_heap_desc.sentinel) ) { retval = _HEAPEMPTY; goto done; } /* * Get and validate the first descriptor */ if ((pdesc = _heap_desc.pfirstdesc) == NULL) { _PRINTERR(_EMPTYHEAP); retval = _HEAPBADBEGIN; goto done; } /* * Walk the heap descriptor list */ while (pdesc != &_heap_desc.sentinel) { /* * Make sure address for this entry is in range. */ if ( (_ADDRESS(pdesc) < _ADDRESS(_heap_desc.pfirstdesc)) || (_ADDRESS(pdesc) > _heap_desc.sentinel.pblock) ) { _PRINTERR(_BADRANGE); retval = _HEAPBADNODE; goto done; } pnext = pdesc->pnextdesc; /* * Make sure the blocks corresponding to pdesc and pnext are * in proper order. */ if ( _ADDRESS(pdesc) >= _ADDRESS(pnext) ) { _PRINTERR(_BADORDER); retval = _HEAPBADNODE; goto done; } /* * Check the backpointer. */ if (_IS_INUSE(pdesc) || _IS_FREE(pdesc)) { if (!_CHECK_PDESC(pdesc)) { retval = _HEAPBADPTR; goto done; } } /* * Check for proverdesc */ if (pdesc == _heap_desc.proverdesc) roverfound++; /* * If it is free, fill it in if appropriate */ if ( _IS_FREE(pdesc) && (_fill != _HEAP_NOFILL) ) memset( (void *)((unsigned)_ADDRESS(pdesc)+_HDRSIZE), _fill, _BLKSIZE(pdesc) ); /* * Onto the next block */ pdesc = pnext; } /* * Make sure we found 1 and only 1 rover */ if (_heap_desc.proverdesc == &_heap_desc.sentinel) roverfound++; if (roverfound != 1) { _PRINTERR(_BADROVER); retval = _HEAPBADBEGIN; goto done; } /* * Walk the empty list. We can't really compare values against * anything but we may loop forever or may cause a fault. */ pdesc = _heap_desc.emptylist; while (pdesc != NULL) { pnext = pdesc->pnextdesc; /* * Header should only appear once */ if (pnext == _heap_desc.emptylist) { _PRINTERR(_EMPTYLOOP) retval = _HEAPBADPTR; goto done; } pdesc = pnext; } /* * Common return */ done: /* * release the heap lock */ _munlock(_HEAP_LOCK); return(retval); }