📄 smmemlib.c
字号:
{ return (NULL); /* not enough space left */ } /* adjust original block size and create new block */ pHdr->nWords = htonl (wordsLeft); pNewHdr = (SM_BLOCK_HDR volatile *) SM_NEXT_HDR (pHdr); pNewHdr->pPrevHdr = (SM_BLOCK_HDR *) htonl (LOC_TO_GLOB_ADRS (pHdr)); pNewHdr->nWords = htonl (nWords); pNewHdr->free = pHdr->free; /* fix next block */ SM_NEXT_HDR (pNewHdr)->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); }/******************************************************************************** smMemAddToPool - add memory to shared memory system partition (VxMP Option)** This routine adds memory to the shared memory system partition after the* initial allocation of memory. The memory added need not be contiguous* with memory previously assigned, but it must be in the same address* space.** <pPool> is the global address of shared memory added to the partition.* The memory area pointed to by <pPool> must be in the same address space* as the shared memory anchor and shared memory pool.** <poolSize> is the size in bytes of shared memory added to the partition.** AVAILABILITY* This routine is distributed as a component of the unbundled shared memory* objects support option, VxMP.* * RETURNS: OK, or ERROR if access to the shared memory system partition fails.** ERRNO:* S_smObjLib_LOCK_TIMEOUT*/STATUS smMemAddToPool ( char * pPool, /* pointer to memory pool */ unsigned poolSize /* block size in bytes */ ) { return (smMemPartAddToPool ((SM_PART_ID) smSystemPartId, pPool, poolSize)); }/******************************************************************************** smMemOptionsSet - set debug options for shared memory system partition (VxMP Option)** This routine sets the debug options for the shared system memory partition.* Two kinds of errors are detected: attempts to allocate more memory than* is available, and bad blocks found when memory is freed or reallocated. * In both cases, the following options can be selected for actions to be * taken when an 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.** AVAILABILITY* This routine is distributed as a component of the unbundled shared memory* objects support option, VxMP.* * RETURNS: OK or ERROR.** ERRNO* S_smObjLib_LOCK_TIMEOUT*/STATUS smMemOptionsSet ( unsigned options /* options for system partition */ ) { return (smMemPartOptionsSet ((SM_PART_ID) smSystemPartId, options)); }/******************************************************************************** smMemMalloc - allocate block of memory from shared memory system partition (VxMP Option)** This routine allocates a block of memory from the shared memory * system partition whose size is equal to or greater than <nBytes>.* The return value is the local address of the allocated shared memory block.** AVAILABILITY* This routine is distributed as a component of the unbundled shared memory* objects support option, VxMP.* * RETURNS:* A pointer to the block, or NULL if the memory cannot be allocated.** ERRNO:* S_memLib_NOT_ENOUGH_MEMORY* S_smObjLib_LOCK_TIMEOUT*/void * smMemMalloc ( unsigned nBytes /* number of bytes to allocate */ ) { return (smMemPartAlloc ((SM_PART_ID) smSystemPartId, (unsigned) nBytes)); }/******************************************************************************** smMemCalloc - allocate memory for array from shared memory system partition (VxMP Option)** This routine allocates a block of memory for an array that contains* <elemNum> elements of size <elemSize> from the shared memory system * partition.* The return value is the local address of the allocated shared memory block.** AVAILABILITY* This routine is distributed as a component of the unbundled shared memory* objects support option, VxMP.* * RETURNS:* A pointer to the block, or NULL if the memory cannot be allocated.** ERRNO:* S_memLib_NOT_ENOUGH_MEMORY* S_smObjLib_LOCK_TIMEOUT*/void * smMemCalloc ( int elemNum, /* number of elements */ int elemSize /* size of elements */ ) { void * pMem; size_t nBytes = elemNum * elemSize; if ((pMem = smMemPartAlloc ((SM_PART_ID) smSystemPartId, (unsigned) nBytes)) != NULL) { bzero ((char *) pMem, (int) nBytes); } return (pMem); }/******************************************************************************** smMemRealloc - reallocate block of memory from shared memory system partition (VxMP Option)** This routine changes the size of a specified block and returns a pointer to* the new block of shared memory. The contents that fit inside the new * size (or old size, if smaller) remain unchanged.* The return value is the local address of the reallocated shared memory block.** AVAILABILITY* This routine is distributed as a component of the unbundled shared memory* objects support option, VxMP.* * RETURNS:* A pointer to the new block of memory, or NULL if the reallocation cannot* be completed.** ERRNO:* S_memLib_NOT_ENOUGH_MEMORY* S_memLib_BLOCK_ERROR* S_smObjLib_LOCK_TIMEOUT*/void * smMemRealloc ( void * pBlock, /* block to be reallocated */ unsigned newSize /* new block size */ ) { return (smMemPartRealloc ((SM_PART_ID) smSystemPartId, (char *) pBlock, (unsigned) newSize)); }/******************************************************************************** smMemFree - free a shared memory system partition block of memory (VxMP Option)** This routine takes a block of memory previously allocated with smMemMalloc() * or smMemCalloc() and returns it to the free shared memory system pool.** It is an error to free a block of memory that was not previously allocated.** AVAILABILITY* This routine is distributed as a component of the unbundled shared memory* objects support option, VxMP.* * RETURNS: OK, or ERROR if the block is invalid.** ERRNO:* S_memLib_BLOCK_ERROR* S_smObjLib_LOCK_TIMEOUT** SEE ALSO: smMemMalloc(), smMemCalloc()*/STATUS smMemFree ( void * ptr /* pointer to block of memory to be freed */ ) { return (smMemPartFree ((SM_PART_ID) smSystemPartId, (char *) ptr)); }/******************************************************************************** smMemFindMax - find largest free block in shared memory system partition (VxMP Option)** This routine searches for the largest block in the shared memory * system partition free list and returns its size.** AVAILABILITY* This routine is distributed as a component of the unbundled shared memory* objects support option, VxMP.* * RETURNS: The size (in bytes) of the largest available block, or ERROR if* the attempt to access the partition fails.** ERRNO:* S_smObjLib_LOCK_TIMEOUT*/int smMemFindMax (void) { return (smMemPartFindMax ((SM_PART_ID) smSystemPartId)); }/******************************************************************************** smMemPartAllocError - handle allocation error** This routine handles an allocation error according to the options set for* the specified partition. <pPart> is the local address of partition to use.** RETURNS: N/A*/LOCAL void smMemPartAllocError ( SM_PART_ID volatile pPart, unsigned nBytes ) { int taskOptions; int partOptions; /* partition options */ unsigned tmp; /* temp storage */ errno = S_memLib_NOT_ENOUGH_MEMORY; CACHE_PIPE_FLUSH (); /* CACHE FLUSH [SPR 68334] */ tmp = pPart->options; /* PCI bridge bug [SPR 68844] */ partOptions = ntohl (pPart->options); if (partOptions & MEM_ALLOC_ERROR_LOG_FLAG) { logMsg (smMemMsgBlockTooBig, nBytes, (int) SM_OBJ_ADRS_TO_ID (pPart), 0, 0, 0, 0); } if (partOptions & MEM_ALLOC_ERROR_SUSPEND_FLAG) { taskOptionsGet (0, &taskOptions); if ((taskOptions & VX_UNBREAKABLE) == 0) { taskSuspend (0); } } }/******************************************************************************** smMemPartBlockError - handle invalid block error** This routine handles an invalid block error according to the options set for* the specified partition. <pPart> is the local address of partition to use.** RETURNS: N/A** NOMANUAL*/LOCAL void smMemPartBlockError ( SM_PART_ID volatile pPart, char * pBlock, char * label ) { int taskOptions; int partOptions; /* partition options */ unsigned tmp; /* temp storage */ errno = S_memLib_BLOCK_ERROR; /* * if ...LOG_FLAG is set, send a log message */ CACHE_PIPE_FLUSH (); /* CACHE FLUSH [SPR 68334] */ tmp = pPart->options; /* PCI bridge bug [SPR 68844] */ partOptions = ntohl (pPart->options); if (partOptions & MEM_BLOCK_ERROR_LOG_FLAG) { logMsg (smMemMsgBlockError, (int) label, (int) pBlock, (int) SM_OBJ_ADRS_TO_ID (pPart), 0, 0, 0); } /* * If ...SUSPEND_FLAG is set, suspend the task */ if (partOptions & MEM_BLOCK_ERROR_SUSPEND_FLAG) { taskOptionsGet (0, &taskOptions); if ((taskOptions & VX_UNBREAKABLE) == 0) { taskSuspend (0); } } }/******************************************************************************** smMemPartBlockIsValid - check validity of block** NOTE: This routine should NOT be called with the partition semaphore taken* if possible, because if the block IS screwed up, then a bus error is* not unlikely and we would hate to have the task die with the semaphore* taken, thus hanging the partition.** <pPart> is the local address of partition to use.** NOMANUAL*/BOOL smMemPartBlockIsValid ( SM_PART_ID volatile partId, SM_BLOCK_HDR volatile * pHdr, BOOL isFree /* expected status */ ) { BOOL valid; valid = SM_MEM_IS_ROUND (pHdr) /* aligned */ /* size is round */ && SM_MEM_IS_ROUND (2 * ntohl (pHdr->nWords)) /* size <= total */ && (ntohl (pHdr->nWords) <= ntohl (partId->totalWords)) && (ntohl (pHdr->free) == isFree) /* right alloc-ness */ && (pHdr == SM_PREV_HDR(SM_NEXT_HDR (pHdr)))/* matches next block*/ && (pHdr ==SM_NEXT_HDR(SM_PREV_HDR (pHdr)));/* matches prev block*/ return (valid); }/******************************************************************************** smMemPartAccessGet - obtain exclusive access to a partition** <pPart> is the local address of partition to use. <pOldLvl> is a pointer * to the processor status register value.** RETURNS: OK, or ERROR if access cannot be obtained** NOMANUAL*/STATUS smMemPartAccessGet ( SM_PART_ID volatile partId /* partition to access */ ) { TASK_SAFE (); /* prevent task deletion */ if (semSmTake (&partId->sem, WAIT_FOREVER) != OK) { /* get exclusive access */ TASK_UNSAFE (); return (ERROR); } return (OK); }/******************************************************************************** smMemPartAccessRelease - release exclusive access to a partition** <pPart> is the local address of partition to use. ** RETURNS: OK, or ERROR if access cannot be released** NOMANUAL*/STATUS smMemPartAccessRelease ( SM_PART_ID volatile partId /* partition to release */ ) { if (semSmGive (&partId->sem) != OK) /* give back partition sem */ { TASK_UNSAFE (); /* allow task deletion */ return (ERROR); } TASK_UNSAFE (); /* allow task deletion */ return (OK); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -