📄 memlib.c
字号:
MEM_BLOCK_CHECK; memLibInstalled = TRUE; } return ((memLibInstalled) ? OK : ERROR); }/********************************************************************************* memInit - initialize the system memory partition** This routine initializes the system partition free list with the* specified memory block. It must be called exactly once before invoking any* other routine in memLib. It is called by kernelInit() in usrRoot()* in usrConfig.c.** RETURNS: OK or ERROR.** NOMANUAL*/STATUS memInit ( char *pPool, /* pointer to memory block */ unsigned poolSize /* block size in bytes */ ) { memLibInit (); /* attach memLib functions to memPartLib */ return (memPartLibInit (pPool, poolSize)); }/********************************************************************************* memPartOptionsSet - set the debug options for a memory partition** This routine sets the debug options for a specified 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 error status is returned. There are four error-handling* options that can be individually selected:* * .iP "MEM_ALLOC_ERROR_LOG_FLAG" 8* Log a message when there is an error in allocating memory.* .iP "MEM_ALLOC_ERROR_SUSPEND_FLAG"* Suspend the task when there is an error in allocating memory (unless* the task was spawned with the VX_UNBREAKABLE option, in which case it* cannot be suspended).* .iP "MEM_BLOCK_ERROR_LOG_FLAG"* Log a message when there is an error in freeing memory.* .iP "MEM_BLOCK_ERROR_SUSPEND_FLAG"* Suspend the task when there is an error in freeing memory (unless* the task was spawned with the VX_UNBREAKABLE option, in which case it* cannot be suspended).* .LP* * These options are discussed in detail in the library manual entry for* memLib.* * RETURNS: OK or ERROR.** ERRNO: S_smObjLib_NOT_INITIALIZED** SEE ALSO: smMemLib*/STATUS memPartOptionsSet ( PART_ID partId, /* partition to set option for */ unsigned options /* memory management options */ ) { if ((!memLibInstalled) && (memLibInit () != OK)) /* initialize package */ return (ERROR); if (ID_IS_SHARED (partId)) /* partition is shared? */ { if (smMemPartOptionsSetRtn == NULL) { errno = S_smObjLib_NOT_INITIALIZED; return (ERROR); } return ((*smMemPartOptionsSetRtn)(SM_OBJ_ID_TO_ADRS (partId), options)); } /* partition is local */ if (OBJ_VERIFY (partId, memPartClassId) != OK) return (ERROR); semTake (&partId->sem, WAIT_FOREVER); /* * Need to convert old-style options to new-style options */ if (options & (MEM_ALLOC_ERROR_MASK | MEM_BLOCK_ERROR_MASK)) { if (options & MEM_ALLOC_ERROR_LOG_MSG) options |= MEM_ALLOC_ERROR_LOG_FLAG; if (options & MEM_ALLOC_ERROR_LOG_AND_SUSPEND) options |= (MEM_ALLOC_ERROR_LOG_FLAG | MEM_ALLOC_ERROR_SUSPEND_FLAG); if (options & MEM_BLOCK_ERROR_LOG_MSG) options |= MEM_BLOCK_ERROR_LOG_FLAG; if (options & MEM_BLOCK_ERROR_LOG_AND_SUSPEND) options |= (MEM_BLOCK_ERROR_LOG_FLAG | MEM_BLOCK_ERROR_SUSPEND_FLAG); } /* * If either of the MEM_BLOCK options have been set, also set * MEM_BLOCK_CHECK. */ if (options & (MEM_BLOCK_ERROR_LOG_FLAG | MEM_BLOCK_ERROR_SUSPEND_FLAG)) options |= MEM_BLOCK_CHECK; partId->options = options; semGive (&partId->sem); return (OK); }/********************************************************************************* memalign - allocate aligned memory ** This routine allocates a buffer of size <size> from the system memory * partition. Additionally, it insures that the allocated buffer begins * on a memory address evenly divisible by the specified 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.*/void *memalign ( unsigned alignment, /* boundary to align to (power of 2) */ unsigned size /* number of bytes to allocate */ ) { return (memPartAlignedAlloc (memSysPartId, size, alignment)); }/********************************************************************************* valloc - allocate memory on a page boundary ** This routine allocates a buffer of <size> bytes from the system memory* partition. Additionally, it insures that the allocated buffer* begins on a page boundary. Page sizes are architecture-dependent.** RETURNS:* A pointer to the newly allocated block, or NULL if the buffer could not be* allocated or the memory management unit (MMU) support library has not been* initialized.** ERRNO: S_memLib_PAGE_SIZE_UNAVAILABLE*/void * valloc ( unsigned size /* number of bytes to allocate */ ) { int pageSize = VM_PAGE_SIZE_GET(); if (pageSize == ERROR) { errno = S_memLib_PAGE_SIZE_UNAVAILABLE; return (NULL); } return (memalign (pageSize, size)); }/********************************************************************************* memPartRealloc - reallocate a block of memory in a specified partition** This routine changes the size of a specified block of memory and returns a* pointer to the new block. The contents that fit inside the new size (or* old size if smaller) remain unchanged. The memory alignment of the new* block is not guaranteed to be the same as the original block.** If <pBlock> is NULL, this call is equivalent to memPartAlloc().** RETURNS:* A pointer to the new block of memory, or NULL if the call fails.** ERRNO: S_smObjLib_NOT_INITIALIZED** SEE ALSO: smMemLib*/void *memPartRealloc ( PART_ID partId, /* partition ID */ char *pBlock, /* block to be reallocated */ unsigned nBytes /* new block size in bytes */ ) { FAST BLOCK_HDR *pHdr = BLOCK_TO_HDR (pBlock); FAST BLOCK_HDR *pNextHdr; FAST unsigned nWords; void *pNewBlock; if (ID_IS_SHARED (partId)) /* partition is shared? */ { if (smMemPartReallocRtn == NULL) { errno = S_smObjLib_NOT_INITIALIZED; return (NULL); } return ((void *) (*smMemPartReallocRtn) (SM_OBJ_ID_TO_ADRS (partId), pBlock, nBytes)); } /* partition is local */ if (OBJ_VERIFY (partId, memPartClassId) != OK) return (NULL); /* Call memPartAlloc() if user passed us a NULL pointer */ if (pBlock == NULL) return (memPartAlloc (partId, (unsigned) nBytes)); /* Call memPartFree() if nBytes=0 (SPR 5858) */ if (nBytes == 0) { (void) memPartFree (memSysPartId, pBlock); return (NULL); } /* get exclusive access to the partition */ semTake (&partId->sem, WAIT_FOREVER); /* get actual new size; round-up, add overhead, check for minimum */ nWords = (MEM_ROUND_UP (nBytes) + sizeof (BLOCK_HDR)) >> 1; if (nWords < partId->minBlockWords) nWords = partId->minBlockWords; /* optional check for validity of block */ if ((partId->options & MEM_BLOCK_CHECK) && !memPartBlockIsValid (partId, pHdr, FALSE)) { semGive (&partId->sem); /* release mutual exclusion */ memPartBlockError (partId, pBlock, "memPartRealloc"); return (NULL); } /* test if we are trying to increase size of block */ if (nWords > pHdr->nWords) { /* increase size of block - * check if next block is free and is big enough to satisfy request*/ pNextHdr = NEXT_HDR (pHdr); if (!pNextHdr->free || ((pHdr->nWords + pNextHdr->nWords) < nWords)) { /* can't use adjacent free block - * allocate an entirely new block and copy data */ semGive (&partId->sem); if ((pNewBlock = memPartAlloc (partId, nBytes)) == NULL) return (NULL); bcopy (pBlock, (char *) pNewBlock, (int) (2 * pHdr->nWords - sizeof (BLOCK_HDR))); (void) memPartFree (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 */ dllRemove (&partId->freeList, HDR_TO_NODE (pNextHdr)); pHdr->nWords += pNextHdr->nWords; /* fix size */#ifdef WV_INSTRUMENTATION /* * The following call to instrumentation will log an a greater * than needed nBytesPlusHeaderAlign. This is because, at this * point, nBytesPlusHeaderAlign includes the total size of the * newly freed memory block. The unused portion will be returned * to the free list (see memBlockSplit() just below, at which * time the excess will be logged as an EVENT_MEMFREE */ EVT_OBJ_4 (OBJ, partId, memPartClassId, EVENT_MEMREALLOC,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -