STATUS memPartFree(PART_ID partId, char* pBlock)
{
	FAST BLOCK_HDR *pHdr;
    FAST unsigned   nWords;
    FAST BLOCK_HDR *pNextHdr;

	if(!IS_CLASS(partId, memPartClassId))
	{
		return (ERROR);
	}

	if(NULL == pBlock)
	{
		return (OK);
	}

	pHdr =  BLOCK_TO_HDR(pBlock);

	/* TODO take semaphore hear */
	semTake(partId->semPartId, WAIT_FOREVER);
	if((partId->options & MEM_BLOCK_CHECK)
		&& !memPartBlockIsValid(partId, pHdr, FALSE))
	{
		/* TODO give semaphore hear */
		semGive(partId->semPartId);
		return (ERROR);
	}

	nWords = pHdr->nWords;
	if(PREV_HDR(pHdr)->free)
	{/* the prev hdr is free and than coalesce with it */
		pHdr->free = FALSE;
		pHdr = PREV_HDR(pHdr);
		pHdr->nWords += nWords;
	}
	else
	{
		pHdr->free = TRUE;
		dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));
	}

	/* check to coalesce with the next */
	pNextHdr = NEXT_HDR(pHdr);
	if(pNextHdr->free)
	{
		pHdr->nWords += pNextHdr->nWords;
		dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));
	}

	/* cannot use pNextHdr->prevHdr=pHdr hear */
	NEXT_HDR(pHdr)->prevHdr = pHdr;

	partId->curBlocksAlloc--;
	partId->curWordsAlloc -= nWords;

	/* TODO give sem hear */
	semGive(partId->semPartId);

	return (OK);
}
Beispiel #2
0
LOCAL STATUS cacheLsn2eFree
    (
    void * pBuf 
    )
    {
    void      * pCacheBuffer;
    
#ifdef IS_KSEGM
    BLOCK_HDR * pHdr;		/* pointer to block header */
    STATUS	status = OK;	/* return value */
    /* Check for unmapped case */
    if (IS_KSEG1(pBuf))
	{
#endif /* IS_KSEGM */
	pCacheBuffer = (void *)K1_TO_K0(pBuf);
	pCacheBuffer = (void *)((int)pCacheBuffer - sizeof (void *));
	free (*(void **)pCacheBuffer);
#ifdef IS_KSEGM
	}
    else
	{
	if (vmLibInfo.vmLibInstalled)
	    {
	    pHdr = BLOCK_TO_HDR (pBuf);

	    /*
	     * XXX - cache mode is set back to the default one. This may be
	     * a problem since we do not know if the original cache mode was either 
	     * COPY_BACK or WRITETHROUGH.
	     */

	    status = VM_STATE_SET (NULL, pBuf, BLOCK_SIZE (pHdr),
				   MMU_ATTR_CACHE_MSK, MMU_ATTR_CACHE_DEFAULT);
	    }
	IOBUF_FREE (pBuf);		/* free buffer after modified */

	return (status);
	}
#endif /* IS_KSEGM */
    return (OK);
    }
static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
	, FAST BLOCK_HDR* pHdr
	, FAST unsigned nWords
	, unsigned minWords
	, unsigned align)
{
	FAST BLOCK_HDR *pNewHdr;
    FAST BLOCK_HDR *pNextHdr;
    FAST char *endOfBlock;
    FAST char *pNewBlock;
    int blockSize;

	endOfBlock = (char*)pHdr + (pHdr->nWords*2);

	pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));

	pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));

	pNewHdr = BLOCK_TO_HDR(pNewBlock);

	blockSize = ((char*)pNewHdr - (char*)pHdr)/2;

	if(blockSize < minWords)
	{
		if(pNewHdr == pHdr)
		{
			dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
		}
		else
		{
			return NULL;
		}
	}
	else
	{	/* recaculate pHdr */
		pNewHdr->prevHdr = pHdr;
		pHdr->nWords = blockSize;
	}

	if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))
	{
		pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;
		pNewHdr->free = TRUE;

		NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;
	}
	else
	{/* space left is enough to be a fragment on the free list then */
		pNewHdr->nWords = nWords;
		pNewHdr->free = TRUE;

		pNextHdr = NEXT_HDR(pNewHdr);
		/* words °üÀ¨BlockHdr */
		pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;
		pNextHdr->prevHdr = pNewHdr;
		pNextHdr->free = TRUE;

		dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));

		NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;
	}

	return (pNewHdr);
}
Beispiel #4
0
LOCAL BLOCK_HDR *memAlignedBlockSplit 
    (
    PART_ID partId,
    FAST BLOCK_HDR *pHdr,
    FAST unsigned nWords,            /* number of words in second block */
    unsigned minWords,               /* min num of words allowed in a block */
    unsigned alignment		     /* boundary to align to */
    )
    {
    FAST BLOCK_HDR *pNewHdr;
    FAST BLOCK_HDR *pNextHdr;
    FAST char *endOfBlock;
    FAST char *pNewBlock;
    int blockSize;

    /* calculate end of pHdr block */

    endOfBlock = (char *) pHdr + (pHdr->nWords * 2); 

    /* caluclate unaligned beginning of new block */ 

    pNewBlock = (char *) ((unsigned) endOfBlock - 
		((nWords - sizeof (BLOCK_HDR) / 2) * 2));

    /* align the beginning of the block */

    pNewBlock = (char *)((unsigned) pNewBlock & ~(alignment - 1));

    pNewHdr = BLOCK_TO_HDR (pNewBlock);

    /* adjust original block's word count */

    blockSize = ((char *) pNewHdr - (char *) pHdr) / 2;


    if (blockSize < minWords)
	{
	/* check to see if the new block is the same as the original block -
	 * if so, delete if from the free list.  If not, reject the newly
	 * split block because it's too small to hang on the free list.
	 */

	if (pNewHdr == pHdr)
	    dllRemove (&partId->freeList, HDR_TO_NODE (pHdr));
	else
	    return (NULL);
	}
    else
	{
	pNewHdr->pPrevHdr = pHdr;
	pHdr->nWords = blockSize;
	}

    /* check to see if space left over after we aligned the new buffer
     * is big enough to be a fragment on the free list.
     */

    if (((UINT) endOfBlock - (UINT) pNewHdr - (nWords * 2)) < (minWords * 2))
	{
	/* nope - give all the memory to the newly allocated block */

	pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof (BLOCK_HDR)) / 2;
	pNewHdr->free     = TRUE; 

	/* fix next block to point to newly allocated block */

	NEXT_HDR (pNewHdr)->pPrevHdr = pNewHdr;
	}
    else
	{
	/* the extra bytes are big enough to be a fragment on the free list -
	 * first, fix up the newly allocated block.
	 */

	pNewHdr->nWords = nWords;
	pNewHdr->free     = TRUE; 

	/* split off the memory after pNewHdr and add it to the free list */

	pNextHdr = NEXT_HDR (pNewHdr);
	pNextHdr->nWords = ((UINT) endOfBlock - (UINT) pNextHdr) / 2;
	pNextHdr->pPrevHdr = pNewHdr;
	pNextHdr->free = TRUE;

	dllAdd (&partId->freeList, HDR_TO_NODE (pNextHdr));	

	/* fix next block to point to the new fragment on the free list */

	NEXT_HDR (pNextHdr)->pPrevHdr = pNextHdr;
	}

    return (pNewHdr);
    }
Beispiel #5
0
STATUS memPartFree 
    (
    PART_ID partId,     /* memory partition to add block to */
    char *pBlock        /* pointer to block of memory to free */
    )
    {
    FAST BLOCK_HDR *pHdr;
    FAST unsigned   nWords;
    FAST BLOCK_HDR *pNextHdr;


    if (ID_IS_SHARED (partId))  /* partition is shared? */
        {
	if (smMemPartFreeRtn == NULL)
	    {
	    errno = S_smObjLib_NOT_INITIALIZED;
	    return (ERROR);
	    }

        return ((*smMemPartFreeRtn) (SM_OBJ_ID_TO_ADRS (partId), pBlock));
	}

    /* partition is local */

    if (OBJ_VERIFY (partId, memPartClassId) != OK)
	return (ERROR);

    if (pBlock == NULL)
	return (OK);				/* ANSI C compatibility */

    pHdr   = BLOCK_TO_HDR (pBlock);

    /* get exclusive access to the partition */

    semTake (&partId->sem, WAIT_FOREVER);

    /* optional check for validity of block */

    if ((partId->options & MEM_BLOCK_CHECK) &&
        !memPartBlockIsValid (partId, pHdr, FALSE))
	{
	semGive (&partId->sem);			/* release mutual exclusion */

	if (memPartBlockErrorRtn != NULL)
	    (* memPartBlockErrorRtn) (partId, pBlock, "memPartFree");

	if (partId->options & MEM_BLOCK_ERROR_SUSPEND_FLAG)
	    {
	    if ((taskIdCurrent->options & VX_UNBREAKABLE) == 0)
		taskSuspend (0);
	    }

	errnoSet (S_memLib_BLOCK_ERROR);
	return (ERROR);
	}
#ifdef WV_INSTRUMENTATION
    EVT_OBJ_3 (OBJ, partId, memPartClassId, EVENT_MEMFREE, partId, pBlock, 2 * (pHdr->nWords));
#endif

    nWords = pHdr->nWords; 

    /* check if we can coalesce with previous block;
     * if so, then we just extend the previous block,
     * otherwise we have to add this as a new free block */

    if (PREV_HDR (pHdr)->free)
	{
	pHdr->free = FALSE;	                /* this isn't a free block */
	pHdr = PREV_HDR (pHdr);			/* coalesce with prev block */
	pHdr->nWords += nWords;
	}
    else
	{
	pHdr->free = TRUE;			/* add new free block */
	dllInsert (&partId->freeList, (DL_NODE *) NULL, HDR_TO_NODE (pHdr));
	}

    /* check if we can coalesce with next block;
     * if so, then we can extend our block delete next block from free list */

    pNextHdr = NEXT_HDR (pHdr);
    if (pNextHdr->free)
	{
	pHdr->nWords += pNextHdr->nWords;	/* coalesce with next */
	dllRemove (&partId->freeList, HDR_TO_NODE (pNextHdr));
	}

    /* fix up prev info of whatever block is now next */

    NEXT_HDR (pHdr)->pPrevHdr = pHdr;

    /* adjust allocation stats */

    partId->curBlocksAllocated--;
    partId->curWordsAllocated -= nWords;

    semGive (&partId->sem);

    return (OK);
    }