free.c 2.42 KB

/**************************************************************************
 *									  *
 *		 Copyright (C) 1994, Silicon Graphics, Inc.		  *
 *									  *
 *  These coded instructions, statements, and computer programs  contain  *
 *  unpublished  proprietary  information of Silicon Graphics, Inc., and  *
 *  are protected by Federal copyright law.  They  may  not be disclosed  *
 *  to  third  parties  or copied or duplicated in any form, in whole or  *
 *  in part, without the prior written consent of Silicon Graphics, Inc.  *
 *									  *
 **************************************************************************/

/**************************************************************************
 *
 *  Module: free.c
 *
 *  $Revision: 1.1.1.2 $
 *  $Date: 2002/10/29 08:06:43 $
 *  $Author: blythe $
 *  $Source: /root/leakn64/depot/rf/sw/n64os20l/libultra/monegi/rg/free.c,v $
 *
 **************************************************************************/


#include "os.h"
#include "os_internal.h"
#include "region.h"
#include "ultraerror.h"
#include "assert.h"


/*
 * Name:   osFree
 *
 * Description:
 *	This routine frees a buffer pointed by 'addr' to the region
 *	pointed by 'region'.
 *
 * Globals Referenced: 
 *	None
 */
void 
osFree(void *region, void *addr) 
{
    register OSRegion *rp = region;
    int i;

#ifdef _DEBUG
    /* Make sure that region and buffer address are not null */
    assert((region != NULL) && (addr != NULL));
    if (((char *)rp + ALIGN(sizeof(OSRegion), RP(alignSize))) != 
        RP(startBufferAddress)) {
	__osError(ERR_OSFREE_REGION, 1, region);
	return;
    }
#endif

    /* Calculate the buffer index number */
    i = ((unsigned char *)addr - RP(startBufferAddress)) / RP(bufferSize);

#ifdef _DEBUG
    /* Check for valid array index range */
    if ((i < 0) || (i >= RP(bufferCount))) {
	__osError(ERR_OSFREE_ADDR, 2, addr, region);
        return;
    }

    /*
     * Double-check for valid input 'addr': must aligned with buffer size
     */
    if (((unsigned char *)addr - RP(startBufferAddress)) % (RP(bufferSize)) != 0) {
	__osError(ERR_OSFREE_ADDR, 2, addr, region);
        return;
    }
#endif

    /* 
     * Mark the released buffer as FREE by inserting it to the front of 
     * the free list
     */
    *(unsigned short *)(RP(startBufferAddress) + (i*RP(bufferSize))) = 
		RP(freeList);

    /* Adjust the free list to point to the new released buffer */
    RP(freeList) = i;

}  /* end of osFree */