📄 smobjlib.c
字号:
** The <smObjParams> parameter is a pointer to a structure containing the* values used to describe the shared memory objects setup. This * structure is defined as follows in smObjLib.h:* .CS* typedef struct sm_obj_params /@ setup parameters @/* {* BOOL allocatedPool; /@ TRUE if shared memory pool is malloced @/* SM_ANCHOR * pAnchor; /@ shared memory anchor @/* char * smObjFreeAdrs; /@ start address of shared memory pool @/* int smObjMemSize; /@ memory size reserved for shared memory @/* int maxCpus; /@ max number of CPUs in the system @/* int maxTasks; /@ max number of tasks using smObj @/* int maxSems; /@ max number of shared semaphores @/* int maxMsgQueues; /@ max number of shared message queues @/* int maxMemParts; /@ max number of shared memory partitions @/* int maxNames; /@ max number of names of shared objects @/* } SM_OBJ_PARAMS;* .CE** INTERNAL* * During initialisation five partitions dedicated to each shared* memory object type are created to avoid runtime memory fragmentation.** - smTcbPartId : shared TCBs partition.** This partition is a fixed block size partition protected * against concurrent access by a spinlock mechanism and * taskSafe()/taskUnsafe().* The size of this partition is defined by the maximum number of* tasks using shared memory objects facility (SM_OBJ_MAX_TASK)* defined in configAll.h.* We use a fixed block size partition for the shared TCBs because * it is less time consuming than the variable block size memory * manager. Interrupt lattency is thus reduced. * * - smSemPartId : shared semaphores partition.** This partition is protected against concurrent access* by a shared semaphore and taskSafe()/taskUnsafe().* The size of this partition is defined by the maximum number of* shared semaphores (SM_OBJ_MAX_SEM) defined in configAll.h.** - smNamePartId : shared name database elements partition.** This partition is protected against concurrent access* by a shared semaphore and taskSafe()/taskUnsafe().* The size of this partition is defined by the maximum number of* names to be entered in the database (SM_OBJ_MAX_NAME) defined* in configAll.h.** - smMsgQPartId : shared message queues partition.** This partition is protected against concurrent access* by a shared semaphore and taskSafe()/taskUnsafe().* The size of this partition is defined by the maximum number of* shared message queues (SM_OBJ_MAX_MSG_Q) defined in configAll.h.** - smPartPartId : user created shared partitions partition.** This partition is protected against concurrent access* by a shared semaphore and taskSafe()/taskUnsafe().* The size of this partition is defined by the maximum number of* user created shared partitions (SM_OBJ_MAX_PART) defined* in configAll.h.** The remaining memory is dedicated to the default system* shared partition : smSystemPart** This partition is used by smMemMalloc, smMemFree ... system calls.* This partition is protected against concurrent access* by a shared semaphore and taskSafe()/taskUnsafe().* The size of this partition is the remaining part of the declared* shared memory pool.** All those partition headers are stored in the shared memory object* descriptor reachable by all CPUs via the shared memory anchor.** AVAILABILITY* This routine is distributed as a component of the unbundled shared memory* objects support option, VxMP.* * RETURNS: OK, or ERROR if the shared memory pool cannot hold all the requested* objects or the number of CPUs exceeds the maximum.* * ERRNO:* S_smObjLib_TOO_MANY_CPU * S_smObjLib_SHARED_MEM_TOO_SMALL** SEE ALSO: smObjInit(), smObjAttach() */STATUS smObjSetup ( SM_OBJ_PARAMS * smObjParams /* setup parameters */ ) { int reqMemSize; /* required memory pool size */ int partSize; /* size of each partition */ char * partAdrs; /* free address for each partition */ int bytesUsed; /* bytes already used by smSetup */ int internalPartsSize;/* sum of bytes used by all partitions */ char * smObjFreeAdrs; /* start address of shared memory pool */ int smObjMemSize; /* memory size reserved for shared memory */ SM_ANCHOR * pAnchor; /* shared memory anchor */ /* check that only master CPU is calling us */ if (sysProcNumGet () != SM_MASTER) return (ERROR); /* * Check that we don't want to use more than absolute maximum * number of CPUs. */ if (smObjParams->maxCpus > SM_OBJ_MAX_CPU) { errno = S_smObjLib_TOO_MANY_CPU; return (ERROR); } smObjFreeAdrs = smObjParams->smObjFreeAdrs; smObjMemSize = smObjParams->smObjMemSize; pAnchor = smObjParams->pAnchor; /* * common shared memory setup . * If smSetup has already been called by the bp driver bytesUsed * will be 0 indicating that all the shared memory can be used * by shared memory objects. */ if (smSetup (pAnchor, smObjFreeAdrs, SM_TAS_HARD, smObjParams->maxCpus, &bytesUsed) == ERROR) return (ERROR); /* * Move address pool after already used memory and set the * new size of the pool. Already used memory can be the anchor * when an external memory is used and/or memory dedicated * to the packet based backplane driver. */ smObjMemSize -= bytesUsed; smObjFreeAdrs += bytesUsed; /* check that shared memory pool is big enough */ reqMemSize = sizeof (SM_OBJ_MEM_HDR) + (sizeof (SM_OBJ_CPU_DESC) * SM_OBJ_MAX_CPU) + (smObjParams->maxTasks * SM_OBJ_SIZE (SM_OBJ_TCB)) + (smObjParams->maxSems * SM_OBJ_SIZE (SM_SEMAPHORE)) + (smObjParams->maxNames * SM_OBJ_SIZE (SM_OBJ_NAME)) + (smObjParams->maxMsgQueues * SM_OBJ_SIZE (SM_MSG_Q)) + (smObjParams->maxMemParts * SM_OBJ_SIZE (SM_PARTITION)) + 4 * PART_OVH + 5 * SM_ALIGN_BOUNDARY; if (smObjMemSize < reqMemSize) { errno = S_smObjLib_SHARED_MEM_TOO_SMALL; return (ERROR); } /* clear shared memory */ bzero (smObjFreeAdrs, smObjMemSize); /* store shared memory objects header at the top of shared memory */ pSmObjHdr = (SM_OBJ_MEM_HDR *) ((int) smObjFreeAdrs); /* set global values needed while initializing */ localToGlobalOffset = (int) pAnchor; smObjPoolMinusOne = localToGlobalOffset - 1; /* set test and set routine pointer */ smObjTasRoutine = (FUNCPTR) sysBusTas; smObjTasClearRoutine = (FUNCPTR) smUtilTasClearRtn; /* set shared memory objects header in the anchor */ pAnchor->smObjHeader = htonl (LOC_TO_GLOB_ADRS (pSmObjHdr)); /* initialize shared TCB partition id */ smTcbPartId = (SM_FIX_BLK_PART_ID) (LOC_TO_GLOB_ADRS ((&pSmObjHdr->smTcbPart))); /* free memory is now behind shared memory objects header */ smObjFreeAdrs += sizeof (SM_OBJ_MEM_HDR); smObjMemSize -= sizeof (SM_OBJ_MEM_HDR); /* store the objects CPU table behind the shared mem obj header */ pSmObjHdr->objCpuTbl = htonl (LOC_TO_GLOB_ADRS ((int) pSmObjHdr + sizeof (SM_OBJ_MEM_HDR))); /* free memory is now behind the smObj CPU table */ smObjFreeAdrs += sizeof (SM_OBJ_CPU_DESC) * SM_OBJ_MAX_CPU; smObjMemSize -= sizeof (SM_OBJ_CPU_DESC) * SM_OBJ_MAX_CPU; internalPartsSize = 0; /* initialize shared TCBs partition */ partAdrs = smObjFreeAdrs; partSize = SM_ALIGN_BOUNDARY + smObjParams->maxTasks * sizeof (SM_OBJ_TCB); internalPartsSize += partSize; smFixBlkPartInit (smTcbPartId, (char *) LOC_TO_GLOB_ADRS (partAdrs), partSize, sizeof (SM_OBJ_TCB)); /* initialize shared semaphores partition */ /* * align partition address otherwise partition size can * be reduced in smMemPartInit() */ partAdrs = (char *) ROUND_UP ((partAdrs + partSize), SM_ALIGN_BOUNDARY); partSize = PART_OVH + (smObjParams->maxSems * SM_OBJ_SIZE (SM_SEMAPHORE)); internalPartsSize += partSize; smMemPartInit (smSemPartId, (char *) LOC_TO_GLOB_ADRS(partAdrs), partSize); /* initialize shared name database partition */ partAdrs = (char *) ROUND_UP ((partAdrs + partSize), SM_ALIGN_BOUNDARY); partSize = PART_OVH + (smObjParams->maxNames * SM_OBJ_SIZE (SM_OBJ_NAME)); internalPartsSize += partSize; smMemPartInit (smNamePartId, (char *) LOC_TO_GLOB_ADRS(partAdrs), partSize); /* initialize shared message queues partition */ partAdrs = (char *) ROUND_UP ((partAdrs + partSize), SM_ALIGN_BOUNDARY); partSize = PART_OVH + (smObjParams->maxMsgQueues * SM_OBJ_SIZE (SM_MSG_Q)); internalPartsSize += partSize; smMemPartInit (smMsgQPartId, (char *) LOC_TO_GLOB_ADRS(partAdrs), partSize); /* initialize shared partitions headers partition */ partAdrs = (char *) ROUND_UP ((partAdrs + partSize), SM_ALIGN_BOUNDARY); partSize = PART_OVH +(smObjParams->maxMemParts * SM_OBJ_SIZE(SM_PARTITION)); internalPartsSize += partSize; smMemPartInit (smPartPartId, (char *) LOC_TO_GLOB_ADRS(partAdrs), partSize); /* initialize system shared partition with remaining memory */ partAdrs = (char *) (partAdrs + partSize); partSize = smObjMemSize - internalPartsSize; smMemPartInit (smSystemPartId, (char *) LOC_TO_GLOB_ADRS(partAdrs), partSize); /* put version number */ pSmObjHdr->version = htonl (SM_OBJ_VERSION); /* fills information fields */ pSmObjHdr->maxSems = htonl (smObjParams->maxSems); pSmObjHdr->maxMsgQueues = htonl (smObjParams->maxMsgQueues); pSmObjHdr->maxTasks = htonl (smObjParams->maxTasks); pSmObjHdr->maxMemParts = htonl (smObjParams->maxMemParts); pSmObjHdr->maxNames = htonl (smObjParams->maxNames); /* start smObj heartbeat */ smObjHeartBeatRate = sysClkRateGet (); smObjWdog = wdCreate (); smObjBeat (&pSmObjHdr->heartBeat); pSmObjHdr->initDone = htonl (TRUE); /* indicate initialization done */ smNameInit (smObjParams->maxNames); /* initialize shared name database */ return (OK); }/********************************************************************************* smObjInit - initialize a shared memory objects descriptor (VxMP Option)** This routine initializes a shared memory descriptor. The descriptor must* already be allocated in the CPU's local memory. Once the descriptor has* been initialized by this routine, the CPU may attach itself to the shared * memory area by calling smObjAttach().** This routine is called automatically when the configuration macro* INCLUDE_SM_OBJ is defined.* * Only the shared memory descriptor itself is modified by this routine.* No structures in shared memory are affected.** Parameters:* .iP <pSmObjDesc>* the address of the shared memory descriptor to be initialized; this* structure must be allocated before smObjInit() is called.* .iP <anchorLocalAdrs>* the memory address by which the local CPU may access the shared memory* anchor. This address may vary among CPUs in the system because of address* offsets (particularly if the anchor is located in one CPU's dual-ported* memory).* .iP <cpuNum>* the number to be used to identify this CPU during shared memory operations.* CPUs are numbered starting with zero for the master CPU, up to 1 less than* the maximum number of CPUs defined during the master CPU's smObjSetup()* call. CPUs can attach in any order, regardless of their CPU number.* .iP <ticksPerBeat>* specifies the frequency of the shared memory anchor's heartbeat. The* frequency is expressed in terms of how many CPU ticks on the local CPU* correspond to one heartbeat period.* .iP <smObjMaxTries>* specifies the maximum number of tries to obtain access to an internal* mutually exclusive data structure. Its default value is 100, but it can* be set to a higher value for a heavily loaded system.* .iP "<intType>, <intArg1>, <intArg2>, and <intArg3>"* allow a CPU to announce the method by which it is to be notified of shared* memory events. See the manual entry for if_sm for a discussion about* interrupt types and their associated parameters.* .LP** AVAILABILITY* This routine is distributed as a component of the unbundled shared memory* objects support option, VxMP.* * RETURNS: N/A** SEE ALSO: smObjSetup(), smObjAttach()*/void smObjInit ( SM_OBJ_DESC * pSmObjDesc, /* ptr to shared memory descriptor */ SM_ANCHOR * anchorLocalAdrs,/* shared memory anchor local adrs */ int ticksPerBeat, /* cpu ticks per heartbeat */ int smObjMaxTries, /* max no. of tries to obtain spinLock */ int intType, /* interrupt method */ int intArg1, /* interrupt argument #1 */ int intArg2, /* interrupt argument #2 */ int intArg3 /* interrupt argument #3 */ ) { if (pSmObjDesc == NULL) return; /* don't use null ptr */ /* generic shared memory descriptor initialization */ smInit (&pSmObjDesc->smDesc, anchorLocalAdrs, ticksPerBeat, intType, intArg1, intArg2, intArg3); /* set global processor number */ smObjProcNum = pSmObjDesc->smDesc.cpuNum; /* set test and set routine pointer */ smObjTasRoutine = (FUNCPTR) sysBusTas; smObjTasClearRoutine = (FUNCPTR) smUtilTasClearRtn; /* allow message to be printed if lock take fails */ smObjTimeoutLogEnable (TRUE); /* set system wide maximum number of tries to obtain lock */ smObjSpinTries = smObjMaxTries; /* install show routines PME : must be done in usrConfig.c one day */ smObjShowInit (); smNameShowInit (); smMemShowInit (); semSmShowInit ();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -