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

📄 smmemlib.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 4 页
字号:
* This routine is not user callable, it is called by the generic memory* partition routine memPartAddToPool().** <partId> is the shared partition header local address of the partition to use.** <pPool> is the global address of shared memory dedicated to the partition.* The memory area pointed to by <pPool> must be in the same address space* than the shared memory anchor and shared memory pool since shared* memory cannot be referenced using different offsets.** <poolSize> is the size in bytes of shared memory added to the partition.* * NOTE: Internally memory pool size is rounded down to a 16-byte boundary.** RETURNS: OK or ERROR.** ERRNO:*  S_objLib_OBJ_ID_ERROR*  S_smObjLib_LOCK_TIMEOUT ** SEE ALSO: memPartSmCreate()** NOMANUAL*/STATUS smMemPartAddToPool     (    SM_PART_ID partId,     /* partition to modify */    char *     pPool,      /* pointer to memory pool */    unsigned   poolSize    /* pool size in bytes */    )    {    SM_BLOCK_HDR * pHdrStart;    SM_BLOCK_HDR * pHdrMid;    SM_BLOCK_HDR * pHdrEnd;    char *         tmp;    if (SM_OBJ_VERIFY (partId) != OK)	return (ERROR);     /* insure that the pool starts on an even byte boundry */    tmp       = (char *) SM_MEM_ROUND_UP (pPool);	/* get actual start */    poolSize  = SM_MEM_ROUND_DOWN (poolSize - (tmp - pPool));       							/* adjust length */    pPool     = (char *) GLOB_TO_LOC_ADRS (tmp);/* convert to local address */    /*      * initialize three blocks one at each end of the pool      * for end cases and real initial free block      */    pHdrStart		= (SM_BLOCK_HDR *) pPool;    pHdrStart->pPrevHdr = NULL;    pHdrStart->free     = htonl (FALSE);    pHdrStart->nWords   = htonl (sizeof (SM_BLOCK_HDR) >> 1);    pHdrMid		= 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_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);    if (smMemPartAccessGet(partId) != OK) return (ERROR);    smDllInsert(&partId->freeList, (SM_DL_NODE *)NULL, SM_HDR_TO_NODE(pHdrMid));    partId->totalWords = htonl (ntohl (partId->totalWords) + (poolSize >> 1));    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  partId,    /* partition for which to set option */    unsigned    options    /* memory management options */    )    {    if (SM_OBJ_VERIFY (partId) != OK)        return (ERROR);    if (smMemPartAccessGet(partId) != OK) return (ERROR);    partId->options = htonl (options);    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		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 *	pNode;    SM_BLOCK_HDR *	pHdr;    SM_BLOCK_HDR *	pNewHdr;    SM_BLOCK_HDR 	origpHdr;    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;    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 *) 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 *) SM_DL_NEXT (pNode);	    }		if (pNode == LOC_NULL)	    {    	    if (smMemPartAccessRelease (partId) != OK) return (NULL);	    smMemPartAllocError (partId, nBytes);	    return (NULL);	    }	pHdr = 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 *) 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));    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 a 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 partId,	/* partition to reallocate from */    char *     pBlock,	/* block to be reallocated */    unsigned   nBytes	/* new block size in bytes */    )    {    SM_BLOCK_HDR *   pHdr = SM_BLOCK_TO_HDR (pBlock);    SM_BLOCK_HDR *   pNextHdr;    unsigned         nWords;    void *           pNewBlock;    int 	     partOptions;		/* partition options */    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;    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 */    if (nWords > ntohl (pHdr->nWords))	{	/* increase size of block -	 * check if next block is free and is big enough to satisfy request*/	pNextHdr = 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);	    bcopy (pBlock, (char *) pNewBlock,		   (int) (2 * ntohl (pHdr->nWords) - sizeof (SM_BLOCK_HDR)));	    (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 	     */	    smDllRemove (&partId->freeList, SM_HDR_TO_NODE (pNextHdr));

⌨️ 快捷键说明

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