⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smmemlib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	    smDllRemove (&partId->freeList, SM_HDR_TO_NODE (pNextHdr));            /* fix size */            CACHE_PIPE_FLUSH ();            /* CACHE FLUSH   [SPR 68334] */            tmp = pHdr->nWords;             /* PCI bug       [SPR 68844] */	    pHdr->nWords = htonl (ntohl (pHdr->nWords) + 				  ntohl (pNextHdr->nWords));            /* fix stats */	    partId->curWordsAllocated = htonl (ntohl (partId->curWordsAllocated)					       + ntohl (pNextHdr->nWords));	    partId->cumWordsAllocated = htonl (ntohl (partId->cumWordsAllocated)					       + ntohl (pNextHdr->nWords));								/* fix next */	    SM_NEXT_HDR (pHdr)->pPrevHdr = (SM_BLOCK_HDR *) 					    htonl (LOC_TO_GLOB_ADRS (pHdr));            CACHE_PIPE_FLUSH ();            /* CACHE FLUSH   [SPR 68334] */            tmp = pHdr->nWords;             /* BRIDGE FLUSH  [SPR 68334] */	    /* if this combined block is too big, it will get fixed below */	    }	}    /*      * split off any extra and give it back;     * note that this covers both the case of a realloc for smaller space     * and the case of a realloc for bigger space that caused a coalesce     * with the next block that resulted in larger than required block      */    pNextHdr = smMemBlockSplit (pHdr, ntohl (pHdr->nWords) - nWords,                                ntohl (partId->minBlockWords));    if (smMemPartAccessRelease (partId) != OK)        {        return (NULL);        }    if (pNextHdr != NULL)	{	(void) smMemPartFree (partId, SM_HDR_TO_BLOCK (pNextHdr));        /* adjust statistics */        partId->curBlocksAllocated = htonl(ntohl(partId->curBlocksAllocated)+1);        CACHE_PIPE_FLUSH ();                /* CACHE FLUSH   [SPR 68334] */        tmp = pHdr->nWords;                 /* BRIDGE FLUSH  [SPR 68334] */	}    return ((void *) pBlock);    }/******************************************************************************** smMemPartFree - free a block of memory in a specified shared partition** This routine takes a block of memory previously allocated with* smMemPartAlloc() and returns it to the shared partition's free memory list.** This routine is not user callable, it is called by the generic memory* partition routine memPartFree().** RETURNS: OK or ERROR if there is an invalid block.** ERRNO:*  S_objLib_OBJ_ID_ERROR*  S_memLib_BLOCK_ERROR*  S_smObjLib_LOCK_TIMEOUT:** NOMANUAL*/STATUS smMemPartFree     (    SM_PART_ID volatile partId,	/* partition to use */    char *              pBlock	/* pointer to block of memory to be freed */    )    {    SM_BLOCK_HDR volatile * pHdr;    SM_BLOCK_HDR volatile * pNextHdr;    unsigned                nWords;    int                     partOptions;	/* partition options */    unsigned                tmp;                /* temp storage */    CACHE_PIPE_FLUSH ();            /* CACHE FLUSH   [SPR 68334] */    tmp = partId->verify;           /* PCI bridge bug [SPR 68844] */    if (SM_OBJ_VERIFY (partId) != OK)        {        return (ERROR);        }    if (pBlock == NULL)        {	return (OK);				/* ANSI C compatibility */        }    pHdr   = (SM_BLOCK_HDR volatile *) SM_BLOCK_TO_HDR (pBlock);    nWords = ntohl (pHdr->nWords);    /* get exclusive access to the partition */    if (smMemPartAccessGet (partId) != OK)        {        return (ERROR);        }    /* optional check for validity of block */    tmp = partId->options;          /* PCI bug       [SPR 68844] */    partOptions = ntohl (partId->options);    if ((partOptions & MEM_BLOCK_CHECK) &&        !smMemPartBlockIsValid (partId, pHdr, FALSE))        {        smMemPartAccessRelease (partId); 	/* release access */        smMemPartBlockError (partId, pBlock, "smMemPartFree");        return (ERROR);        }    /*      * 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 (ntohl (SM_PREV_HDR (pHdr)->free))	{	pHdr->free = htonl (FALSE); 		/* this isn't a free block */	pHdr = SM_PREV_HDR (pHdr);		/* coalesce with prev block */        CACHE_PIPE_FLUSH ();            /* CACHE FLUSH   [SPR 68334] */        tmp = pHdr->nWords;             /* PCI bug       [SPR 68844] */	pHdr->nWords = htonl (ntohl (pHdr->nWords) + nWords);	}    else	{	pHdr->free = htonl (TRUE);		/* add new free block */	smDllInsert (&partId->freeList, (SM_DL_NODE *) NULL, 		     SM_HDR_TO_NODE (pHdr));	}    CACHE_PIPE_FLUSH ();            /* CACHE FLUSH   [SPR 68334] */    tmp = pHdr->nWords;             /* BRIDGE FLUSH  [SPR 68334] */    /*      * Check if we can coalesce with next block;     * if so, then we can extend our block delete next block from free list      */    pNextHdr = (SM_BLOCK_HDR volatile *) SM_NEXT_HDR (pHdr);    if (ntohl (pNextHdr->free))	{        /* coalesce with next */	pHdr->nWords = htonl (ntohl (pHdr->nWords) + ntohl (pNextHdr->nWords));	smDllRemove (&partId->freeList, SM_HDR_TO_NODE (pNextHdr));	}    /* fix up prev info of whatever block is now next */    SM_NEXT_HDR (pHdr)->pPrevHdr = (SM_BLOCK_HDR *) 					htonl (LOC_TO_GLOB_ADRS (pHdr));    /* adjust allocation stats */    partId->curBlocksAllocated = htonl (ntohl (partId->curBlocksAllocated) - 1);    partId->curWordsAllocated  = htonl (ntohl (partId->curWordsAllocated) - 					nWords);    CACHE_PIPE_FLUSH ();            /* CACHE FLUSH   [SPR 68334] */    tmp = pHdr->nWords;             /* BRIDGE FLUSH  [SPR 68334] */    if (smMemPartAccessRelease (partId) != OK)        {        return (ERROR);        }    return (OK);    }/******************************************************************************** smMemPartFindMax - find the size of the largest available free block** This routine searches for the largest block in a shared memory partition free* list, and returns its size.** This routine is not user callable, it is called by the generic memory* partition routine memPartFindMax().** RETURNS: The size (in bytes) of the largest available block or ERROR if* <partId> is not a valid partition or if attempt to get access to the * partition fails.** ERRNO:*  S_objLib_OBJ_ID_ERROR*  S_smObjLib_LOCK_TIMEOUT** NOMANUAL*/int smMemPartFindMax     (    SM_PART_ID volatile partId     /* partition to use */    )    {    SM_BLOCK_HDR volatile *    pHdr;    SM_DL_NODE volatile *      pNode;    unsigned                   biggestWords = 0;    unsigned                   tmp;                /* temp storage */    CACHE_PIPE_FLUSH ();            /* CACHE FLUSH   [SPR 68334] */    tmp = partId->verify;           /* PCI bridge bug [SPR 68844] */    if (SM_OBJ_VERIFY (partId) != OK)        {        return (ERROR);        }    if (smMemPartAccessGet (partId) != OK)        {        return (ERROR);        }    /* go through free list and find largest free */    for (pNode = (SM_DL_NODE volatile *) SM_DL_FIRST (&partId->freeList);	 pNode != LOC_NULL;	 pNode = (SM_DL_NODE volatile *) SM_DL_NEXT (pNode))	{	pHdr = (SM_BLOCK_HDR volatile *) SM_NODE_TO_HDR (pNode);	if (ntohl (pHdr->nWords) > biggestWords)	    {	    biggestWords = ntohl (pHdr->nWords);	    }	}    if (smMemPartAccessRelease (partId) != OK)        {        return (ERROR);        }    /* convert words to bytes only if non-zero value [SPR 70280] */    if (biggestWords > 0)        {        biggestWords *= 2;        biggestWords -= sizeof (SM_BLOCK_HDR);        }    return (biggestWords);    }/******************************************************************************** smMemAlignedBlockSplit - split a block on the free list into two blocks** This routine is like smMemBlockSplit(), but also aligns the data block to* the given alignment.  The block looks like this after it is split:**        |----------------------------------------------------------------|*        ^                      ^                       ^                 ^*        |                      |                       | space left over |*        |                      |<------- nWords ------>| after alignment |*        |                      |                       |                 |*   block begin       new aligned buffer begin         end           block end*** After the split, if the first block has less than minWords in it, the* block is rejected, and null is returned, since we can't place this first* block on the free list.  If the space succeeding the newly allocated* aligned buffer is less than the minimum block size, then the bytes are* added to the newly allocated buffer.  If the space is greater than the* minimum block size,  then a new memory fragment is created and added to* the free list.  Care must be taken to insure that the orignal block passed* in to be split has at least (nWords + alignment/2) words in it.  If the* block has exactly nWords and is already aligned to the given alignment, it* will be deleted from the free list and returned unsplit.  Otherwise, the* second block will be returned.** RETURNS: A pointer to a BLOCK_HDR ** NOMANUAL*/LOCAL SM_BLOCK_HDR volatile * smMemAlignedBlockSplit     (    SM_PART_ID volatile     partId,    SM_BLOCK_HDR volatile * pHdr,    unsigned                nWords,   /* number of words in second block */    unsigned                minWords, /* min num of words allowed in a block */    unsigned                alignment /* boundry to align to */    )    {    SM_BLOCK_HDR volatile * pNewHdr;    SM_BLOCK_HDR volatile * pNextHdr;    char *		    endOfBlock;    char *		    pNewBlock;    int 		    blockSize;    unsigned                   tmp;                /* temp storage */    CACHE_PIPE_FLUSH ();            /* CACHE FLUSH   [SPR 68334] */    tmp = pHdr->nWords;             /* PCI bridge bug [SPR 68844] */    /* calculate end of pHdr block */    endOfBlock = (char *) pHdr + (ntohl (pHdr->nWords) * 2);     /* calculate unaligned beginning of new block */     pNewBlock = (char *) ((unsigned) endOfBlock - 		((nWords - sizeof (SM_BLOCK_HDR) / 2) * 2));    /* align the beginning of the block */    pNewBlock = (char *)((unsigned) pNewBlock & ~(alignment - 1));    pNewHdr = (SM_BLOCK_HDR volatile *) SM_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)	    {	    smDllRemove (&partId->freeList, SM_HDR_TO_NODE (pHdr));	    }	else	    {	    return (NULL);	    }	}    else	{	pNewHdr->pPrevHdr = (SM_BLOCK_HDR *) htonl (LOC_TO_GLOB_ADRS (pHdr));	pHdr->nWords = htonl (blockSize);	}    CACHE_PIPE_FLUSH ();            /* CACHE FLUSH   [SPR 68334] */    tmp = pNewHdr->nWords;          /* BRIDGE FLUSH  [SPR 68844] */    /*      * 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 = htonl ((endOfBlock - pNewBlock + 				 sizeof (SM_BLOCK_HDR)) / 2);	pNewHdr->free   = htonl (TRUE); 	/* fix next block to point to newly allocated block */	SM_NEXT_HDR (pNewHdr)->pPrevHdr = (SM_BLOCK_HDR *) 					   htonl (LOC_TO_GLOB_ADRS (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 = htonl (nWords);	pNewHdr->free   = htonl (TRUE); 	/* split off the memory after pNewHdr and add it to the free list */	pNextHdr = SM_NEXT_HDR (pHdr);	pNextHdr->nWords   = htonl (((UINT) endOfBlock - (UINT) pNextHdr) / 2);	pNextHdr->pPrevHdr = (SM_BLOCK_HDR *) htonl (LOC_TO_GLOB_ADRS (pHdr)); 	pNextHdr->free     = htonl (TRUE);	smDllAdd (&partId->freeList, SM_HDR_TO_NODE (pNextHdr));		/* fix next block to point to the new fragment on the free list */	SM_NEXT_HDR (pNextHdr)->pPrevHdr = (SM_BLOCK_HDR *) 					    htonl (LOC_TO_GLOB_ADRS (pNewHdr)); 	}    CACHE_PIPE_FLUSH ();            /* CACHE FLUSH   [SPR 68334] */    tmp = pNewHdr->nWords;          /* BRIDGE FLUSH  [SPR 68334] */    return (pNewHdr);    }/******************************************************************************** smMemBlockSplit - split a block into two blocks** This routine splits the block pointed to into two blocks.  The second * block will have nWords words in it.  A pointer is returned to this block.* If either resultant block would end up having less than minWords in it,* NULL is returned.** RETURNS: A pointer to the second block, or NULL.* * NOMANUAL*/LOCAL SM_BLOCK_HDR volatile * smMemBlockSplit     (    SM_BLOCK_HDR volatile * pHdr,    unsigned                nWords,  /* number of words in second block */    unsigned                minWords /* min num of words allowed in a block */    )    {    unsigned                wordsLeft;    SM_BLOCK_HDR volatile * pNewHdr;    unsigned                tmp;                /* temp storage */    CACHE_PIPE_FLUSH ();            /* CACHE FLUSH   [SPR 68334] */    tmp = pHdr->nWords;             /* PCI bug       [SPR 68844] */    /* check if block can be split */    if ((nWords < minWords) ||        ((wordsLeft = (ntohl (pHdr->nWords) - nWords)) < minWords))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -