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

📄 smmemlib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    )    {    SM_BLOCK_HDR volatile * pHdrStart;    SM_BLOCK_HDR volatile * pHdrMid;    SM_BLOCK_HDR volatile * pHdrEnd;    char *                  pTmp;    int                     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);        }     /* insure that the pool starts on an even byte boundry */    pTmp      = (char *) SM_MEM_ROUND_UP (pPool);	 /* get actual start */    poolSize  = SM_MEM_ROUND_DOWN (poolSize - (pTmp - pPool)); /* adj length */    pPool     = (char *) GLOB_TO_LOC_ADRS (pTmp);        /* get local adrs */    /*      * initialize three blocks one at each end of the pool      * for end cases and real initial free block      */    pHdrStart		= (SM_BLOCK_HDR volatile *) pPool;    pHdrStart->pPrevHdr = NULL;    pHdrStart->free     = htonl (FALSE);    pHdrStart->nWords   = htonl (sizeof (SM_BLOCK_HDR) >> 1);    pHdrMid		= (SM_BLOCK_HDR volatile *) SM_NEXT_HDR (pHdrStart);    pHdrMid->pPrevHdr   = (SM_BLOCK_HDR *)htonl (LOC_TO_GLOB_ADRS (pHdrStart));    pHdrMid->free       = htonl (TRUE);    pHdrMid->nWords     = htonl ((poolSize - 2 * sizeof (SM_BLOCK_HDR)) >> 1);    pHdrEnd		= (SM_BLOCK_HDR volatile *) SM_NEXT_HDR (pHdrMid);    pHdrEnd->pPrevHdr   = (SM_BLOCK_HDR *) htonl (LOC_TO_GLOB_ADRS (pHdrMid));    pHdrEnd->free       = htonl (FALSE);    pHdrEnd->nWords     = htonl (sizeof (SM_BLOCK_HDR) >> 1);    CACHE_PIPE_FLUSH ();            /* CACHE FLUSH   [SPR 68334] */    tmp = partId->options;          /* BRIDGE FLUSH  [SPR 68334] */    if (smMemPartAccessGet (partId) != OK)        {        return (ERROR);        }    smDllInsert(&partId->freeList, (SM_DL_NODE *)NULL, SM_HDR_TO_NODE(pHdrMid));    CACHE_PIPE_FLUSH ();            /* CACHE FLUSH   [SPR 68334] */    tmp = partId->totalWords;       /* PCI bug       [SPR 68844] */    partId->totalWords = htonl (ntohl (partId->totalWords) + (poolSize >> 1));    CACHE_PIPE_FLUSH ();            /* CACHE FLUSH   [SPR 68334] */    tmp = partId->options;          /* BRIDGE FLUSH  [SPR 68334] */    if (smMemPartAccessRelease (partId) != OK)        {        return (ERROR);        }    return (OK);    }/******************************************************************************** smMemPartOptionsSet - set the debug options for a shared memory partition** This routine sets the debug options for a specified shared memory partition.* Two kinds of errors are detected:  attempts to allocate more memory than* is available, and bad blocks found when memory is freed.  In both cases,* the following options can be selected for actions to be taken when the error* is detected:  (1) return the error status, (2) log an error message and* return the error status, or (3) log an error message and suspend the* calling task.  These options are discussed in detail in the library manual* entry for smMemLib.** This routine is not user callable, it is called by the generic memory* partition routine memPartOptionsSet().** RETURNS: OK or ERROR.** ERRNO:*  S_objLib_OBJ_ID_ERROR*  S_smObjLib_LOCK_TIMEOUT** NOMANUAL*/STATUS smMemPartOptionsSet    (    SM_PART_ID volatile partId,    /* partition for which to set option */    unsigned            options    /* memory management options */    )    {    int                 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);        }    partId->options = htonl (options);    CACHE_PIPE_FLUSH ();            /* CACHE FLUSH   [SPR 68334] */    tmp = partId->options;          /* BRIDGE FLUSH  [SPR 68334] */    if (smMemPartAccessRelease (partId) != OK)        {        return (ERROR);        }    return (OK);    }/******************************************************************************** smMemPartAlignedAlloc - allocate aligned memory from a partition** This routine allocates a buffer of size nBytes from the given * shared partition.  Additionally, it will insure the allocated buffer * begins on a memory address that is evenly divisable by the given * alignment parameter.  The alignment parameter must be a power of 2.** RETURNS:* A pointer to the newly allocated block, or NULL if the buffer could not be* allocated.** NOMANUAL*/void * smMemPartAlignedAlloc     (    SM_PART_ID volatile	partId,		/* memory partition to allocate from */    unsigned		nBytes,		/* number of bytes to allocate */    unsigned		alignment	/* boundry to align to */    )    {    unsigned			nWords;    unsigned			nWordsExtra;    SM_DL_NODE volatile *	pNode;    SM_BLOCK_HDR volatile *	pHdr;    SM_BLOCK_HDR volatile *	pNewHdr;    SM_BLOCK_HDR 		origpHdr;    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 (NULL);        }    /* get actual size to allocate; add overhead, check for minimum */    nWords = (SM_MEM_ROUND_UP (nBytes) + sizeof (SM_BLOCK_HDR)) >> 1;    tmp = partId->minBlockWords;    /* PCI bug       [SPR 68844] */    if (nWords < ntohl (partId->minBlockWords))        {	nWords = ntohl (partId->minBlockWords);        }    /* get exclusive access to the partition */    if (smMemPartAccessGet (partId) != OK)        {        return (NULL);        }    /* first fit */    pNode = (SM_DL_NODE volatile *) SM_DL_FIRST (&partId->freeList);    /*     * We need a free block with extra room to do the alignment.       * Worst case we'll need alignment extra bytes.     */    nWordsExtra = nWords + alignment / 2;    FOREVER	{	while (pNode != LOC_NULL)	    {	    /*	     * fits if:	     *	- blocksize > requested size + extra room for alignment or,	     *	- block is already aligned and exactly the right size	     */	    if ((ntohl (SM_NODE_TO_HDR (pNode)->nWords) > nWordsExtra) ||		((((UINT) SM_HDR_TO_BLOCK (SM_NODE_TO_HDR (pNode)) % alignment)		  == 0) &&		 (ntohl (SM_NODE_TO_HDR (pNode)->nWords) == nWords)))                {		break;                }	    pNode = (SM_DL_NODE volatile *) SM_DL_NEXT (pNode);	    }	if (pNode == LOC_NULL)	    {    	    if (smMemPartAccessRelease (partId) != OK)    	        {    	        return (NULL);    	        }	    smMemPartAllocError (partId, nBytes);	    return (NULL);	    }	pHdr = (SM_BLOCK_HDR volatile *) SM_NODE_TO_HDR (pNode);	origpHdr = *pHdr;	/* 	 * Now we split off from this block, the amount required by the user;	 * note that the piece we are giving the user is at the end of the	 * block so that the remaining piece is still the piece that is	 * linked in the free list;  if smMemAlignedBlockSplit returned NULL,	 * it couldn't split the block because the split would leave the	 * first block too small to be hung on the free list, so we continue	 * trying blocks.	 */	pNewHdr = smMemAlignedBlockSplit (partId, pHdr, nWords,                                          ntohl (partId->minBlockWords),                                          alignment);	if (pNewHdr != NULL)	    {	    pHdr = pNewHdr;			/* give split off block */	    break;	    }		pNode = (SM_DL_NODE volatile *) SM_DL_NEXT (pNode);	}    /* mark the block we're giving as not free  */    pHdr->free = htonl (FALSE);    /* update allocation statistics */    partId->curBlocksAllocated = htonl (ntohl (partId->curBlocksAllocated) +1);    partId->cumBlocksAllocated = htonl (ntohl (partId->cumBlocksAllocated) +1);    partId->curWordsAllocated  = htonl (ntohl (partId->curWordsAllocated) + 					ntohl (pHdr->nWords));    partId->cumWordsAllocated  = htonl (ntohl (partId->cumWordsAllocated) + 					ntohl (pHdr->nWords));    CACHE_PIPE_FLUSH ();            /* CACHE FLUSH   [SPR 68334] */    tmp = partId->options;          /* BRIDGE FLUSH  [SPR 68334] */    if (smMemPartAccessRelease (partId) != OK)        {        return (NULL);        }    return ((void *) SM_HDR_TO_BLOCK (pHdr));    }/******************************************************************************** smMemPartAlloc - allocate a block of memory from a specified shared partition** From a specified shared partition, this routine allocates a block of memory* whose size is equal to or greater than <nBytes>.  The shared partition * must have been previously created with memPartSmCreate().** This routine is not user callable, it is called by the generic memory* partition routine memPartAlloc.** RETURNS:* A pointer to a block, or* NULL if the call fails.** ERRNO:*  S_objLib_OBJ_ID_ERROR*  S_memLib_NOT_ENOUGH_MEMORY*  S_smObjLib_LOCK_TIMEOUT** SEE ALSO: smMemPartInit()** NOMANUAL*/void * smMemPartAlloc     (    SM_PART_ID partId,     /* partition to allocate from */    unsigned   nBytes      /* number of bytes to allocate */    )    {    return (smMemPartAlignedAlloc (partId, nBytes, SM_ALIGN_BOUNDARY));    }/******************************************************************************** smMemPartRealloc - reallocate a block of memory in specified shared partition** This routine changes the size of a specified block and returns a pointer to* the new block of memory.  The contents that fit inside the new size (or old* size if smaller) remain unchanged.** This routine is not user callable, it is called by the generic memory* partition routine memPartRealloc.** RETURNS:* A pointer to the new block of memory, or NULL if the call fails.** ERRNO:*  S_objLib_OBJ_ID_ERROR*  S_memLib_NOT_ENOUGH_MEMORY*  S_memLib_BLOCK_ERROR*  S_smObjLib_LOCK_TIMEOUT** NOMANUAL*/void * smMemPartRealloc     (    SM_PART_ID volatile partId,	/* partition to reallocate from */    char *              pBlock,	/* block to be reallocated */    unsigned            nBytes	/* new block size in bytes */    )    {    SM_BLOCK_HDR volatile * pHdr = SM_BLOCK_TO_HDR (pBlock);    SM_BLOCK_HDR volatile * pNextHdr;    unsigned                nWords;    void *                  pNewBlock;    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 (NULL);        }    /* get exclusive access to the partition */    if (smMemPartAccessGet (partId) != OK)        {        return (NULL);        }    /* get actual new size; round-up, add overhead, check for minimum */    nWords = (SM_MEM_ROUND_UP (nBytes) + sizeof (SM_BLOCK_HDR)) >> 1;    tmp = partId->minBlockWords;    /* PCI bug       [SPR 68844] */    if (nWords < ntohl (partId->minBlockWords))        {	nWords = ntohl (partId->minBlockWords);        }    /* optional check for validity of block */    partOptions = ntohl (partId->options);    if ((partOptions & MEM_BLOCK_CHECK) &&        !smMemPartBlockIsValid (partId, pHdr, FALSE))        {        smMemPartAccessRelease (partId); 	/* release access */        smMemPartBlockError (partId, pBlock, "smMemPartRealloc");        return (NULL);        }    /* test if we are trying to increase size of block */    tmp = pHdr->nWords;             /* PCI bug       [SPR 68844] */    if (nWords > ntohl (pHdr->nWords))	{	/*	 * increase size of block -	 * check if next block is free and is big enough to satisfy request	 */	pNextHdr = (SM_BLOCK_HDR volatile *) SM_NEXT_HDR (pHdr);	if (!(ntohl (pNextHdr->free)) || 	    ((ntohl (pHdr->nWords) + ntohl (pNextHdr->nWords)) < nWords))	    {	    /*	     * can't use adjacent free block -	     * allocate an entirely new block and copy data	     */            if (smMemPartAccessRelease (partId) != OK)                {                return (NULL);                }	    if ((pNewBlock = smMemPartAlloc (partId, nBytes)) == NULL)	        {		return (NULL);	        }            CACHE_PIPE_FLUSH ();            /* CACHE FLUSH   [SPR 68334] */            tmp = pHdr->nWords;             /* PCI bug       [SPR 68844] */	    bcopy (pBlock, (char *) pNewBlock,		   (int) (2 * ntohl (pHdr->nWords) - sizeof (SM_BLOCK_HDR)));            CACHE_PIPE_FLUSH ();            /* CACHE FLUSH   [SPR 68334] */            tmp = pHdr->nWords;             /* BRIDGE FLUSH  [SPR 68334] */	    (void) smMemPartFree (partId, pBlock);	    return (pNewBlock);		/* RETURN, don't fall through */	    }	else	    {	    /* 	     * append next block to this one -	     *  - delete next block from freelist,	     *  - add its size to this block,	     *  - update allocation statistics,	     *  - fix prev info in new "next" block header 	     */

⌨️ 快捷键说明

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