📄 smmemlib.c
字号:
/* smMemLib.c - shared memory management library (VxMP Option) *//* Copyright 1995-2002 Wind River Systems, Inc. *//*modification history--------------------01p,03may02,mas default now is always MEM_BLOCK_CHECK (SPR 3756); cache flush and volatile fix (SPR 68334); bridge flush fix (SPR 68844)01o,24oct01,mas doc update (SPR 71149)01n,09oct01,mas smMemPartFindMax() can now return zero; code cleanup(SPR70280)01m,14mar99,dat SPR 20308, fixed smMemBlockSplit.01l,14mar99,jdi doc: removed refs to config.h and/or configAll.h (SPR 25663).01k,21jun96,dbt Update copyright. Removed warning concerning SM_ALIGN_BOUNDARY (SPR #4903).01j,08feb93,jdi documentation cleanup. pme removed BLOCK_CHECK default option.01i,29jan93,pme added little endian support. added partOptions where needed to get rid of i960 cc warnings. made smMemAddToPool() return STATUS. Made smMemFindMax() return ERROR if access to the partition fails. documentation.01h,21nov92,jdi documentation cleanup.01g,02oct92,pme added SPARC support. documentation cleanup.01f,29sep92,pme changed user callable routine names for coherency added ERRNO section in comments. rounded down poolSize in smMemPartAddToPool changed smMemPartFree() to mark coalesced blocks as not free01e,29jul92,pme removed partition access release from smMemPartBlockIsValid.01d,28jul92,pme made smMemPartCreate return PART_ID instead of SM_PART_ID.01c,28jul92,pme changed SM_OBJ_ALIGN_BOUNDARY to SM_ALIGN_BOUNDARY.01b,28jul92,pme changed memory alignement to SM_OBJ_ALIGN_BOUNDARY bytes. replaced MEM_ROUND_UP by SM_MEM_ROUND_UP and MEM_IS_ROUND by SM_MEM_IS_ROUND. added smMemPartAlignedAlloc() and smMemAlignedBlockSplit().01a,19jul92,pme simplified smMemPartBlockError and smMemPartAllocError. moved smMemShow() and smMemPartShow() to smMemShow.c written from 04l memLib.c*//*DESCRIPTIONThis library provides facilities for managing the allocation of blocks ofshared memory from ranges of memory called shared memory partitions. Theroutine memPartSmCreate() is used to create shared memory partitions inthe shared memory pool. The created partition can be manipulated usingthe generic memory partition calls, memPartAlloc(), memPartFree(), etc.(for a complete list of these routines, see the manual entry formemPartLib). The maximum number of partitions that can be created isdetermined by the configuration parameter SM_OBJ_MAX_MEM_PART .The smMem...() routines provide an easy-to-use interface to the sharedmemory system partition. The shared memory system partition is created when the shared memory object facility is initialized.Shared memory management information and statistics display routines areprovided by smMemShow.The allocation of memory, using memPartAlloc() in the general case and smMemMalloc() for the shared memory system partition, is done with a first-fit algorithm. Adjacent blocks of memory are coalesced when freedusing memPartFree() and smMemFree().There is a 28-byte overhead per allocated block (architecture dependent),and allocated blocks are aligned on a 16-byte boundary.All memory used by the shared memory facility must be in the same address space, that is, it must be reachable from all the CPUs with the same offset as the one used for the shared memory anchor.CONFIGURATIONBefore routines in this library can be called, the shared memory objectsfacility must be initialized by a call to usrSmObjInit(), which is found in \f3target/config/comps/src/usrSmObj.c\f1. This is done automaticallyby VxWorks when the INCLUDE_SM_OBJ component is included.ERROR OPTIONSVarious debug options can be selected for each partition usingmemPartOptionsSet() and smMemOptionsSet(). Two kinds of errors aredetected: attempts to allocate more memory than is available, and badblocks found when memory is freed. In both cases, options can be selectedfor system actions to take place when the error is detected: (1) returnthe error status, (2) log an error message and return the error status, or(3) log an error message and suspend the calling task.One of the following options can be specified to determinethe action to be taken when there is an attempt to allocate morememory than is available in the partition:\is\i `MEM_ALLOC_ERROR_RETURN'just return the error status to the calling task.\i `MEM_ALLOC_ERROR_LOG_MSG'log an error message and return the status to the calling task.\i `MEM_ALLOC_ERROR_LOG_AND_SUSPEND'log an error message and suspend the calling task.\ieThe following option is specified by default to check everyblock freed to the partition. If this option is specified, memPartFree()and smMemFree() will make a consistency check of various pointers and valuesin the header of the block being freed.\is\i `MEM_BLOCK_CHECK'check each block freed.\ieOne of the following options can be specified to determine the action tobe taken when a bad block is detected when freed. These options applyonly if the MEM_BLOCK_CHECK option is selected.\is\i `MEM_BLOCK_ERROR_RETURN'just return the status to the calling task.\i `MEM_BLOCK_ERROR_LOG_MSG'log an error message and return the status to the calling task.\i `MEM_BLOCK_ERROR_LOG_AND_SUSPEND'log an error message and suspend the calling task.\ieThe default options when a shared partition is created areMEM_ALLOC_ERROR_LOG_MSG, MEM_BLOCK_CHECK, MEM_BLOCK_ERROR_RETURN.When setting options for a partition with memPartOptionsSet() orsmMemOptionsSet(), use the logical OR operator between each specifiedoption to construct the <options> parameter. For example:\cs memPartOptionsSet (myPartId, MEM_ALLOC_ERROR_LOG_MSG | MEM_BLOCK_CHECK | MEM_BLOCK_ERROR_LOG_MSG);\ceAVAILABILITYThis module is distributed as a component of the unbundled shared memoryobjects support option, VxMP.INCLUDE FILES: smMemLib.hSEE ALSO: smMemShow, memLib, memPartLib, smObjLib, usrSmObjInit(),\tb VxWorks Programmer's Guide: Shared Memory ObjectsINTERNALBlocks allocated by smMemMalloc() are actually larger than the sizerequested by the user. Each block is prefaced by a header which containsthe size and status of that block and a pointer to the previous block.The pointer returned to the user points just past this header. Likewisewhen a block is freed, the header is found just in front of the blockpointer passed by the user.The header data is arranged so that the pointer to the previous blockcomes first and is therefore adjacent to that previous block. Thus eachblock has 4 bytes of redundant information on either side of it (the 4bytes of size and status before it in its own header, and the 4-bytepointer after it in the next header). This redundant information isoptionally used in smMemFree() and smMemRealloc() to make a consistencycheck on blocks specified by the user. This mechanism helps to detect twocommon errors: (1) bad block pointers passed to smMemFree() orsmMemRealloc() are usually detected, and (2) trashing up to 4 bytes oneither side of the block will only affect that block and will also bedetected by smMemFree() or smMemRealloc().There is a minimum block size which malloc() allocates; this is to insurethat there will be enough room for the free list links that must be usedwhen the block is freed if it cannot be coalesced with an adjacent block.The malloc() and realloc() routines always force the requested block size tobe multiple of SM_ALIGN_BOUNDARY; since smMemPartInit() forces the initial pool to be on a SM_ALIGN_BOUNDARY-byte boundary, this causes all blocks to lie on a SM_ALIGN_BOUNDARY-byte boundaries, thus insuring that the block passed back to the user will always lie on a SM_ALIGN_BOUNDARY byte boundary.The memory partition shared semaphore is a structure in the partitiondescriptor rather than a pointer to a dynamically created shared semaphorestructure. This is because of the chicken-and-the-egg problem of smMemLibusing semaphores and semBSmCreate calling smMemPartAlloc. Instead thestructure is simply declared directly in the partition structure and we callsemSmBInit() instead of semBSmCreate().All blocks allocated from a shared memory partition are aligned onSM_ALIGN_BOUNDARY which defines the minimum common alignement valueneeded by all the supported architecture. *//* includes */#include "vxWorks.h"#include "memLib.h"#include "semLib.h"#include "logLib.h"#include "intLib.h"#include "taskLib.h"#include "cacheLib.h"#include "string.h"#include "errnoLib.h"#include "netinet/in.h"#include "smLib.h"#include "smMemLib.h"#include "private/smObjLibP.h"#include "private/memPartLibP.h"/* defines *//* * Macros for rounding: all allocated blocks are aligned * on the maximum required alignement value across all available * architectures. This value named SM_ALIGN_BOUNDARY * is set to 16 bytes since i960 version is available. */#define SM_MEM_ROUND_UP(x) (ROUND_UP(x, SM_ALIGN_BOUNDARY))#define SM_MEM_ROUND_DOWN(x) (ROUND_DOWN(x, SM_ALIGN_BOUNDARY))#define SM_MEM_IS_ROUND(x) (ALIGNED(x, SM_ALIGN_BOUNDARY))/* locals */LOCAL char * smMemMsgBlockTooBig = "smMemPartAlloc: block too big - %d in shared partition %#x.\n";LOCAL char * smMemMsgBlockError = "%s: invalid block %#x in shared partition %#x.\n";/* forward declarations */LOCAL void smMemPartAllocError (SM_PART_ID volatile pPart, unsigned nBytes);LOCAL void smMemPartBlockError (SM_PART_ID volatile pPart, char * pBlock, char * label);LOCAL SM_BLOCK_HDR volatile * smMemBlockSplit (SM_BLOCK_HDR volatile * pHdr, unsigned nWords, unsigned minWords);LOCAL SM_BLOCK_HDR volatile * smMemAlignedBlockSplit (\ SM_PART_ID volatile partId, SM_BLOCK_HDR volatile * pHdr, unsigned nWords, unsigned minWords, unsigned alignment);/******************************************************************************** smMemPartLibInit - initialize the shared memory manager facility** This routine initializes the shared memory manager function pointers to* allow generic memory management calls to manipulate shared memory* partitions. It is called by smObjInit().** RETURNS: N/A.** NOMANUAL*/void smMemPartLibInit (void) { /* Initialize shared memory manager function pointers */ smMemPartAddToPoolRtn = (FUNCPTR) smMemPartAddToPool; smMemPartFreeRtn = (FUNCPTR) smMemPartFree; smMemPartAllocRtn = (FUNCPTR) smMemPartAlloc; smMemPartOptionsSetRtn = (FUNCPTR) smMemPartOptionsSet; smMemPartFindMaxRtn = (FUNCPTR) smMemPartFindMax; smMemPartReallocRtn = (FUNCPTR) smMemPartRealloc; }/******************************************************************************** memPartSmCreate - create a shared memory partition (VxMP Option)** This routine creates a shared memory partition that can be used by tasks* on all CPUs in the system. It returns a partition ID which can then be* passed to generic memPartLib routines to manage the partition (i.e., to* allocate and free memory blocks in the partition).** <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 as the shared memory anchor and shared memory pool.** <poolSize> is the size in bytes of shared memory dedicated to the partition.** Before this routine can be called, the shared memory objects facility must* be initialized (see smMemLib).** NOTE* The descriptor for the new partition is allocated out of an internal* dedicated shared memory partition. The maximum number of partitions that can* be created is SM_OBJ_MAX_MEM_PART .** Memory pool size is rounded down to a 16-byte boundary.** AVAILABILITY* This routine is distributed as a component of the unbundled shared memory* objects support option, VxMP.* * RETURNS:* The partition ID, or NULL if there is insufficient memory in the dedicated* partition for a new partition descriptor.** ERRNO:* S_memLib_NOT_ENOUGH_MEMORY* S_smObjLib_LOCK_TIMEOUT ** SEE ALSO: memLib*/PART_ID memPartSmCreate ( char * pPool, /* global address of shared memory area */ unsigned poolSize /* size in bytes */ ) { SM_PART_ID pPart; /* created partition ID */ int tmp; /* temp storage */ /* * Allocate a shared partition structure from the internal * shared partition memory pool. */ pPart = (SM_PART_ID) smMemPartAlloc ((SM_PART_ID) smPartPartId, sizeof (SM_PARTITION)); if (pPart != LOC_NULL) { smMemPartInit ((SM_PART_ID) pPart, pPool, poolSize); /* update smObj statistics */ CACHE_PIPE_FLUSH (); /* CACHE FLUSH [SPR 68334] */ tmp = pSmObjHdr->curNumPart; /* PCI bridge bug [SPR 68844] */ pSmObjHdr->curNumPart = htonl (ntohl (pSmObjHdr->curNumPart) + 1); CACHE_PIPE_FLUSH (); /* CACHE FLUSH [SPR 68334] */ tmp = pSmObjHdr->curNumPart; /* BRIDGE FLUSH [SPR 68334] */ } /* now return the global address of the partition */ return ((PART_ID) SM_OBJ_ADRS_TO_ID (pPart)); }/******************************************************************************** smMemPartInit - initialize a shared memory partition** This routine initializes a shared partition free list, seeding it with the* memory block passed as an argument. It must be called exactly once* for each memory partition created. * * <partId> is the local address of the partition structure * previously allocated from the shared partitions structures partition * (smPartPartId). ** <pPool> is the global address of shared memory dedicated to the partition.** <poolSize> is the size in bytes of shared memory dedicated to the partition.** SEE ALSO: memPartSmCreate()** NOMANUAL*/void smMemPartInit ( SM_PART_ID volatile partId, /* partition to initialize */ char * pPool, /* pointer to memory pool */ unsigned poolSize /* pool size in bytes */ ) { int tmp; /* temp storage */ /* initialize partition descriptor */ bzero ((char *) partId, sizeof (*partId)); partId->options = htonl (MEM_ALLOC_ERROR_LOG_FLAG | MEM_BLOCK_CHECK | MEM_BLOCK_ERROR_RETURN); partId->minBlockWords = htonl (sizeof (SM_FREE_BLOCK) >> 1); CACHE_PIPE_FLUSH (); /* CACHE FLUSH [SPR 68334] */ tmp = partId->options; /* BRIDGE FLUSH [SPR 68334] */ /* initialize partition semaphore and free list and add memory to pool */ semSmBInit (&partId->sem, SEM_Q_FIFO, SEM_FULL); smDllInit (&partId->freeList); partId->objType = htonl (MEM_PART_TYPE_SM_STD); /* verify field must contain partition header global address */ partId->verify = (UINT32) htonl (LOC_TO_GLOB_ADRS (partId)); CACHE_PIPE_FLUSH (); /* CACHE FLUSH [SPR 68334] */ tmp = partId->options; /* BRIDGE FLUSH [SPR 68334] */ (void) smMemPartAddToPool (partId, pPool, poolSize); }/******************************************************************************** smMemPartAddToPool - add memory to a shared memory partition** This routine adds memory to a shared memory partition after the initial * call to memPartSmCreate(). The memory added need not be contiguous with * memory previously assigned to the partition but it must be in the same* address space.** 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 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 volatile partId, /* partition to modify */ char * pPool, /* pointer to memory pool */ unsigned poolSize /* pool size in bytes */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -