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

📄 mempartlib.c

📁 vxworks 5.5 kernel code
💻 C
📖 第 1 页 / 共 3 页
字号:
    /* 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);    }/********************************************************************************* memPartBlockIsValid - check validity of block** This routine checks the validity of a block. If the pointer to the block* header is bogus we could run into bus errors and the calling task could take* the partId semaphore with it. To prvent this from happening we make the task* preemption proof and release the semaphore before doing the block validity * check. ** NOMANUAL*/BOOL memPartBlockIsValid     (    PART_ID partId,    FAST BLOCK_HDR *pHdr,    BOOL isFree                 /* expected status */    )    {    BOOL valid;    TASK_LOCK ();					/* LOCK PREEMPTION */    semGive (&partId->sem);				/* release mutex */    valid = MEM_ALIGNED (pHdr)				/* aligned */            && MEM_ALIGNED (2 * pHdr->nWords)		/* size is round */            && (pHdr->nWords <= partId->totalWords)	/* size <= total */	    && (pHdr->free == isFree)			/* right alloc-ness */#if (CPU_FAMILY == SH)	    && MEM_ALIGNED(NEXT_HDR (pHdr))		/* aligned(08aug95,sa)*/	    && MEM_ALIGNED(PREV_HDR (pHdr))		/* aligned(08aug95,sa)*/#endif	    && (pHdr == PREV_HDR (NEXT_HDR (pHdr)))	/* matches next block */	    && (pHdr == NEXT_HDR (PREV_HDR (pHdr)));	/* matches prev block */    semTake (&partId->sem, WAIT_FOREVER);		/* reacquire mutex */    TASK_UNLOCK ();					/* UNLOCK PREEMPTION */    return (valid);    }/******************************************************************************* memAlignedBlockSplit - split a block on the free list into two blocks** This routine is like memBlockSplit, 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 */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);    }/******************************************************************************** memAddToPool - add memory to the system memory partition** This routine adds memory to the system memory partition, after the initial* allocation of memory to the system memory partition.** RETURNS: N/A** SEE ALSO: memPartAddToPool()*/void memAddToPool     (    FAST char *pPool,           /* pointer to memory block */    FAST unsigned poolSize      /* block size in bytes */    )    {    (void) memPartAddToPool (&memSysPartition, pPool, poolSize);    }/********************************************************************************* malloc - allocate a block of memory from the system memory partition (ANSI)** This routine allocates a block of memory from the free list.  The size of* the block will be equal to or greater than <nBytes>.** RETURNS: A pointer to the allocated block of memory, or a null pointer if* there is an error.** SEE ALSO: * .I "American National Standard for Information Systems -"* .I "Programming Language - C, ANSI X3.159-1989: General Utilities (stdlib.h)"*/void *malloc     (    size_t nBytes             /* number of bytes to allocate */    )    {    return (memPartAlloc (&memSysPartition, (unsigned) nBytes));    }/********************************************************************************* free - free a block of memory (ANSI)** This routine returns to the free memory pool a block of memory previously* allocated with malloc() or calloc().** RETURNS: N/A** SEE ALSO: * malloc(), calloc(),* .I "American National Standard for Information Systems -"* .I "Programming Language - C, ANSI X3.159-1989: General Utilities (stdlib.h)"*/void free     (    void *ptr       /* pointer to block of memory to free */    )    {    (void) memPartFree (&memSysPartition, (char *) ptr);    }/********************************************************************************* memPartSemInit - initialize the partition semaphore as type binary** This routine initializes the partition semaphore as a binary semaphore.* This function is called indirectly from memPartInit().  This coupling* allows alternative semaphore types to serve as the basis for memory* partition interlocking.*/LOCAL void memPartSemInit    (    PART_ID partId		/* partition to initialize semaphore for */    )    {    semBInit (&partId->sem, SEM_Q_PRIORITY, SEM_FULL);    }

⌨️ 快捷键说明

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