📄 smobjlib.c
字号:
* int maxMemParts; /@ max number of shared memory partitions @/* int maxNames; /@ max number of names of shared objects @/* } SM_OBJ_PARAMS;* \ce** INTERNAL* * During initialization, 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 as defined in the* configuration parameter SM_OBJ_MAX_TASK.* 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 as defined in the configuration parameter* SM_OBJ_MAX_SEM.** - 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 as defined in the configuration* parameter SM_OBJ_MAX_NAME.** - 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 as defined in the configuration parameter* SM_OBJ_MAX_MSG_Q.** - 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 as defined in the configuration* parameter SM_OBJ_MAX_PART.** 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 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 volatile * pAnchor; /* shared memory anchor */ int tmp; /* temp storage */ /* 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 = (SM_ANCHOR volatile *)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 ((SM_ANCHOR *)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 volatile *) ((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 ((SM_PART_ID volatile) 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 ((SM_PART_ID volatile) 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 ((SM_PART_ID volatile) 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 ((SM_PART_ID volatile) smPartPartId, (char *) LOC_TO_GLOB_ADRS(partAdrs), partSize); /* initialize system shared partition with remaining memory */ partAdrs = (char *) (partAdrs + partSize); partSize = smObjMemSize - internalPartsSize; smMemPartInit ((SM_PART_ID volatile) 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 ((UINT *) &pSmObjHdr->heartBeat); pSmObjHdr->initDone = htonl (TRUE); /* indicate initialization done */ CACHE_PIPE_FLUSH (); /* CACHE FLUSH [SPR 68334] */ tmp = pSmObjHdr->initDone; /* BRIDGE FLUSH [SPR 68334] */ 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 component INCLUDE_SM_OBJ is* included.* * Only the shared memory descriptor itself is modified by this routine.* No structures in shared memory are affected.** Parameters:* \is* \i `<pSmObjDesc>'* The address of the shared memory descriptor to be initialized; this* structure must be allocated before smObjInit() is called.* \i `<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).* \i `<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.* \i `<smObjMaxTries>'* Specifies the maximum number of tries to obtain access to an internal* mutually exclusive data structure.* \i `<intType>, <intArg1>, <intArg2>, <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.* \ie** 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 */ /* XXXmas these should be turned into one or more components in a folder */ smObjShowInit (); smNameShowInit (); smMemShowInit (); semSmShowInit (); msgQSmShowInit (); /* generic show routine for shared memory objects called by show() */ _func_smObjObjShow = (FUNCPTR) smObjObjShow; }/******************************************************************************** smObjAttach - attach the calling CPU to the shared memory objects facility (VxMP Option)** This routine "attaches" the calling CPU to the shared memory objects* facility. The shared memory area is identified by the shared memory* descriptor with an address specified by <pSmObjDesc>. The descriptor must* already have been initialized by calling smObjInit().** This routine is called automatically when the component INCLUDE_SM_OBJ is* included.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -