Example #1
0
void __cdecl _free_base (

#endif  /* _MT */

        REG1 void *pblock
        )
{
        REG2 _PBLKDESC pdesc;


        /*
         * If the pointer is NULL, just return [ANSI].
         */

        if (pblock == NULL)
            return;

        /*
         * Point to block header and get the pointer back to the heap desc.
         */

        pblock = (char *)pblock - _HDRSIZE;
        pdesc = *(_PBLKDESC*)pblock;

        /*
         * Validate the back pointer.
         */

        if (_ADDRESS(pdesc) != pblock)
            _heap_abort();

        /*
         * Pointer is ok.  Mark block free.
         */

        _SET_FREE(pdesc);

        /*
         * Check for special conditions under which the rover is reset.
         */
        if ( (_heap_resetsize != 0xffffffff) &&
             (_heap_desc.proverdesc->pblock > pdesc->pblock) &&
             (_BLKSIZE(pdesc) >= _heap_resetsize) )
        {
            _heap_desc.proverdesc = pdesc;
        }
#if !defined (_M_MPPC) && !defined (_M_M68K)
        else if ( _heap_desc.proverdesc == pdesc->pnextdesc )
        {
            _heap_desc.proverdesc = pdesc;
        }
#endif  /* !defined (_M_MPPC) && !defined (_M_M68K) */
}
Example #2
0
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");

}
_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 ;
}
int __cdecl _heap_addblock (
        void * block,
        size_t size
        )
{
        _PBLKDESC pdesc;
        REG1 _PBLKDESC pnewdesc;
        _PBLKDESC pdescs[4] = { NULL, NULL, NULL, NULL };
        _PBLKDESC *ppdesc = pdescs;
        size_t lastsize;
        int find;

        /*
         * Make sure we enough empty descriptors to do the job! Do it here
         * and now because recovering from an out-of-descriptors condition
         * is too dicey later on.
         */
        if ( ((pdescs[0] = __getempty()) == NULL) ||
             ((pdescs[1] = __getempty()) == NULL) ||
             ((pdescs[2] = __getempty()) == NULL) )
        {
                goto error;
        }

        /*
         * Find where the address fits into the heap.
         */

        find = _heap_findaddr(block, &pdesc);


        /*
         * Fill in the new heap descriptor.
         * (1) If the new address is an exact fit, use the dummy
         *     descriptor that already exists for it.
         * (2) If the address is NOT in the heap, allocate a new one.
         */

        if ( find == _HEAPFIND_EXACT ) {

                if ( !(_IS_DUMMY(pdesc)) )
                        goto error;

                pnewdesc = pdesc;
        }
        else {
                pnewdesc = *(ppdesc++);
        }

        pnewdesc->pblock = block;       /* pointer to block */
        _SET_FREE(pnewdesc);            /* set me free (why don't ya, babe) */
        *(_PBLKDESC*)block = pnewdesc;  /* init back pointer */


        /*
         * Put the block in the heap
         * find = result of _heap_findaddr() call
         * pnewdesc = points to desc to be inserted
         * pdesc = filled in by _heap_findaddr() call as appropriate
         */

        switch (find) {


                case(_HEAPFIND_EMPTY):

                        /*
                         * No memory in heap yet
                         */

                        _heap_desc.sentinel.pblock = (char *) block + size;
                        _before(pnewdesc, size, &_heap_desc.sentinel,
                                &ppdesc);

                        _heap_desc.pfirstdesc = _heap_desc.proverdesc =
                                pnewdesc;

                        break;


                case(_HEAPFIND_BEFORE):

                        /*
                         * New block is before the heap
                         */

                        _before(pnewdesc, size, _heap_desc.pfirstdesc,
                                &ppdesc);
                        _heap_desc.pfirstdesc = pnewdesc;
                        break;


                case(_HEAPFIND_AFTER):

                        /*
                         * New block is after the heap
                         *
                         * Find the current last block in the heap
                         */

                        if ( _heap_findaddr((void *)((char *)
                            (_heap_desc.sentinel.pblock) - 1), &pdesc) !=
                            _HEAPFIND_WITHIN )
                                _heap_abort();

                        lastsize = _MEMSIZE(pdesc);

                        /*
                         * Start insertion by placing new block immediately
                         * in front of the sentinel
                         */

                        _heap_desc.sentinel.pblock = (char *) block + size;
                        pnewdesc->pnextdesc = &_heap_desc.sentinel;

                        /*
                         * Finish insertion by placing new block after the
                         * old last block (with a possible intervening dummy
                         * block being created)
                         */

                        _before(pdesc, lastsize, pnewdesc,
                                &ppdesc);
                        break;


                case(_HEAPFIND_EXACT):

                        /*
                         * Block is already in the heap (and we've checked
                         * that it was a "dummy" before this call).
                         *
                         * [NOTES: (1) pnewdesc and pdesc are the same,
                         * (2) pnewdesc is already linked to the previous
                         * heap entry, (3) pdesc->pnextdesc is still valid!
                         * (4) Also, if pdesc->pnextdesc is the sentinel,
                         * then simply update the sentinel size (calling
                         * before will cause an error if the previous last
                         * block was bigger than the current one!).
                         * (see code at top of this routine).]
                         */

                        if (pdesc->pnextdesc == &_heap_desc.sentinel)

                                _heap_desc.sentinel.pblock =
                                        (char *) _ADDRESS(pdesc) + size;

                        else
                                _before(pnewdesc, size, pdesc->pnextdesc,
                                        &ppdesc);

                        break;

                default:
                        /*
                         * New block is within heap
                         */

                        if (!(_IS_DUMMY(pdesc)))
                                goto error;

                        /*
                         * If the last block in the heap is a dummy region
                         * and a new region is allocated which lies within
                         * that region, we need to update sentinel.pblock.
                         */
                        if (pdesc->pnextdesc == &_heap_desc.sentinel)
                        {
                            void * newend = (char *) _ADDRESS(pnewdesc) + size;

                            if (_heap_desc.sentinel.pblock < newend)
                                _heap_desc.sentinel.pblock = newend;
                        }

                        _before(pnewdesc, size, pdesc->pnextdesc,
                                &ppdesc);
                        _before(pdesc, _MEMSIZE(pdesc), pnewdesc,
                                &ppdesc);
                        break;


                }

        /*
         * Update rover, if appropriate
         */

         if ( (block < _ADDRESS(_heap_desc.proverdesc)) &&
         (_BLKSIZE(pnewdesc) >= _heap_resetsize) )
                _heap_desc.proverdesc = pnewdesc;

        /*
         * Good return
         */

        /* good:   unreferenced label to be removed */
                return(0);

        /*
         * Error return
         */

        error:
                while ( *ppdesc != NULL ) {
                        _PUTEMPTY(*ppdesc);
                        ppdesc++;
                }

                return(-1);

}
Example #5
0
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);

}