⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smlib.c

📁 VxWorks操作系统内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    SM_ANCHOR * anchorLocalAdrs,	/* local addr of anchor */    char *	smLocalAdrs,		/* local addr of sh mem area */    int		tasType,		/* method of test-and-set */    int		maxCpus,		/* max number of cpu's */    int	*	pMemUsed		/* amount of memory used */    )    {    SM_ANCHOR volatile * pAnchorv = (SM_ANCHOR volatile *) anchorLocalAdrs;    SM_HDR volatile *	 pHdr;			/* local addr of sh mem hdr */    char		 temp = 0;		/* temp location */    /* Initialize shared memory region table */    if (!smLibInitialized)	{	bzero ((char *) smRegions, sizeof (smRegions));	smLibInitialized = TRUE;	}    /* Probe shared memory */    if (smUtilMemProbe (smLocalAdrs, VX_WRITE, sizeof (char), &temp) != OK)        {       	errno = S_smLib_MEMORY_ERROR;	return (ERROR);	}    /* Find the Region */    if (smRegionFind (anchorLocalAdrs) != ERROR)	{	pHdr = SM_OFFSET_TO_LOCAL (ntohl (pAnchorv->smHeader), (int) pAnchorv,                                   SM_HDR volatile *);	if ((ntohl (pHdr->maxCpus) != maxCpus) ||	    (ntohl (pHdr->tasType) != tasType))	    printf ("smSetup:Warning! previous parameters differ!\n");	*pMemUsed = 0;	return (OK);	}    if (smRegionGet (anchorLocalAdrs) == ERROR)	return (ERROR);    *pMemUsed = sizeof (SM_HDR) + (maxCpus * sizeof (SM_CPU_DESC));    /* Partially initialize shared memory header */    bzero (smLocalAdrs, *pMemUsed);    pHdr 	   = (SM_HDR volatile *) smLocalAdrs; /* header = SM start */    pHdr->tasType  = htonl (tasType);		/* test-and-set method */    pHdr->maxCpus  = htonl (maxCpus);		/* max number of cpu's */    pHdr->cpuTable = htonl (SM_LOCAL_TO_OFFSET (pHdr + sizeof (SM_HDR),					        (int) anchorLocalAdrs));    /* Set up the anchor */    bzero ((char *) pAnchorv, sizeof (SM_ANCHOR));    pAnchorv->version    = htonl (SM_VERSION);  /* sh mem version */    pAnchorv->smHeader   = htonl (SM_LOCAL_TO_OFFSET (pHdr, (int) pAnchorv));    pAnchorv->masterCpu  = htonl (SM_MASTER); /* sh mem  master */    pAnchorv->readyValue = htonl (SM_READY);  /* sh mem available */    CACHE_PIPE_FLUSH ();                /* CACHE FLUSH   [SPR 68334] */    maxCpus = pHdr->maxCpus;		/* BRIDGE FLUSH  [SPR 68334] */    return (OK);				/* shared mem init complete */    }/******************************************************************************** smInit - initialize shared memory descriptor** This routine initializes a shared memory descriptor.  The descriptor* must have been previously allocated (generally 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* smAttach().** Only the shared memory descriptor itself is modified by this routine.* No structures in shared memory are affected.** The <pSmDesc> paramter is the address of the shared memory descriptor* which is to be initialized; this structure must have already been* allocated before smInit() is called.** The <anchorLocalAdrs> parameter is the memory address by which the local* CPU may access the shared memory anchor.  This address may vary for* different CPU's because of address offsets (particularly if the anchor is* located in one CPU's dual-ported memory).** The <ticksPerBeat> parameter 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.** The <intType>, <intArg1>, <intArg2>, and <intArg3> parameters allow a* CPU to announce the method by which it is to be notified of input packets* which have been queued to it.  Once this CPU has attached to the shared* memory region, other CPU's will be able to determine these interrupt* parameters by calling smCpuInfoGet().  ** RETURNS: N/A*/void smInit    (    SM_DESC *	pSmDesc,	 /* sh mem descr to init*/    SM_ANCHOR *	anchorLocalAdrs, /* local addr of sh mem anchor*/    int		ticksPerBeat,	 /* cpu ticks per heartbeat */    int		intType,	 /* interrupt method */    int		intArg1,	 /* interrupt argument #1 */    int		intArg2,	 /* interrupt argument #2 */    int		intArg3		 /* interrupt argument #3 */    )    {    if (pSmDesc == NULL)	return;					/* don't use null ptr */    bzero ((char *) pSmDesc, sizeof (SM_DESC));    /* Copy input parameters */    pSmDesc->anchorLocalAdrs  = anchorLocalAdrs;    pSmDesc->base	      = (int) anchorLocalAdrs;    pSmDesc->cpuNum	      = smUtilProcNumGet ();    pSmDesc->ticksPerBeat     = (ticksPerBeat == 0) ? smUtilRateGet () :						      ticksPerBeat;    pSmDesc->intType	      = intType;    pSmDesc->intArg1	      = intArg1;    pSmDesc->intArg2	      = intArg2;    pSmDesc->intArg3	      = intArg3;    pSmDesc->status	      = SM_CPU_NOT_ATTACHED;	/* initial status */    }/******************************************************************************** smIsAlive - determine if shared memory is initialized and active** This routine examines the shared memory anchor and heartbeat to* determine whether the shared memory has been initialized and that* it is running.  The shared memory is specified by <pAnchor>, the* address of the shared memory anchor.  If the shared* memory network is active, TRUE is returned; otherwise, FALSE is* returned.  <pHeader> points to the location of the header containing* the heartbeat.  <base> is the base address from which to calculate the* address of the heartbeat counter in the header in shared memory.** The anchor ready-value must contain the special value SM_READY to* indicate that the master CPU has successfully initialized the shared* memory region.  The heartbeat must increment at least twice* within the timeout period to be recognized as active.** <heartBeats> specifies the number of beats to wait for a correct* ready-value and active heartbeat before timing out.  A zero value* indicates the use of a default value, specified by the global variable * 'smAliveTimeout'.** <ticksPerBeat> specifies the number of ticks per heartbeat.** This routine safely probes the anchor addresses to avoid bus errors* (in case the anchor address is not yet accessable).  Occasional* messages are written to standard output if a bus error occurs but is* handled.  Occasional messages will also appear to indicate the most* recently obtained values for the ready-value and heartbeat.** This routine may not be called from interrupt level.** This routine does not set errno.** RETURNS: TRUE or FALSE.*/BOOL smIsAlive    (    SM_ANCHOR *	pAnchor,	/* ptr to shared mem anchor */    int *	pHeader,	/* {smObj/smPkt} header */    int		base,		/* base */    int		heartBeats,	/* heartbeat periods */    int 	ticksPerBeat   	/* ticks per beat */    )    {    UINT	readyValue;        /* ready value from anchor */    UINT	newHeartBeat;      /* beat value from anchor */    UINT	oldHeartBeat;      /* saved beat value */    int		incCnt;            /* number of beat increments observed*/    int *	pHeartBeat = NULL; /* ptr to heartbeat */    int		temp;              /* temp storage */    newHeartBeat = 0;				/* init beat values */    oldHeartBeat = 0;    incCnt = 0;    /* Determine number of heartbeat periods to wait */    if (ticksPerBeat == 0)        {	ticksPerBeat = smUtilRateGet ();        }    if (heartBeats == 0)        {	heartBeats = smAliveTimeout * (smUtilRateGet ()) / ticksPerBeat;        }    /* Check anchor and heartbeat until ready or countdown expires */    while (heartBeats-- > 0)	{	/* XXX - invalidate data cache here ?? */	/* Probe and get anchor ready-value */	if (smUtilMemProbe ((char *) &pAnchor->readyValue, VX_READ, 			    sizeof (int), (char *) &readyValue) != OK)	    {	    if ((heartBeats % 10) == 8)		/* print error occasionally */                {                printf ("\nsmIsAlive: bus error checking anchor\n");                }	    }	readyValue = ntohl (readyValue);	if (readyValue == SM_READY)	/* if anchor appears ready */	    {	    /*	     * Calculate the location of the heartbeat.	     * The heartbeat must be the first location in {smPkt/smObj}	     * header. 	     */            CACHE_PIPE_FLUSH ();		/* FLUSH BUFFER  [SPR 68334] */            temp = *(int *)pHeader;		/* PCI bridge bug [SPR 68844]*/	    pHeartBeat = SM_OFFSET_TO_LOCAL (ntohl (*pHeader), base, int *);	    /* Probe and get heartbeat value */	    if (smUtilMemProbe ((char *) pHeartBeat, VX_READ, sizeof (int),				(char *) &newHeartBeat) == OK)		{		newHeartBeat = ntohl (newHeartBeat);	    	/* Check if heartbeat incremented */	    	if ((newHeartBeat <= oldHeartBeat) || (oldHeartBeat == 0))	    	    {	    	    oldHeartBeat = newHeartBeat; /* no beat - try again */	    	    }	    	else				/* beat incremented! */	    	    {		    if (++incCnt >= 2)		/* if 2 incr's have been seen*/		        {	    	    	return (TRUE);		/* SHARED MEM IS ALIVE & WELL*/		        }	    	    }		}	    else				/* could not probe heartbeat */	    	{		if ((heartBeats % 10) == 8)	/* print error occasionally */		    {	    	    printf ("\nsmIsAlive: bus error getting heartbeat\n");		    }	    	}	    }  /* end if (readyValue) */	/* Occasionally display last obtained ready-value and heartbeat */	if ((heartBeats % 10) == 6)	    {	    printf ("smIsAlive:  readyValue = 0x%x, heartbeat = 0x%x\n",		    readyValue, newHeartBeat);	    }	/* Wait before checking heartbeat again */	if (smUtilDelay ((char *) pHeartBeat, ticksPerBeat) != OK)	    {					/* wait enough for 1 beat */	    return (FALSE);			/* called from int level?? */	    }	}  /* end while */    return (FALSE);				/* timed out */    }/******************************************************************************** smAttach - attach a node to shared memory** This routine "attaches" the local CPU to a shared memory area.  The* shared memory area is identified by the shared memory descriptor* whose address specified by <pSmDesc>.  The descriptor must have* already been initialized by calling smInit().** This routine should get called only after and when the shared memory has* been initialized by the master CPU.  To determine this, smIsAlive() must* have been called to check the shared memory anchor for both the proper * value (SM_READY_VALUE) in the anchor's ready-value field and an * active heartbeat.** The attachment to shared memory may be ended by calling smDetach().** RETURNS: OK, or ERROR.** ERRNO: S_smLib_INVALID_CPU_NUMBER** SEE ALSO: smIsAlive(), smInit()*/STATUS smAttach    (    SM_DESC *	pSmDesc		/* ptr to shared mem descriptor */    )    {    SM_HDR volatile *	   pHdr;        /* ptr to shared mem header */    SM_CPU_DESC volatile * pCpuDesc;    /* ptr to shared mem cpu descriptor */    int			   cpuNum;      /* this cpu's number */    int			   temp;        /* temp storage */    cpuNum = pSmDesc->cpuNum;    /* Get local address for shared mem header */    CACHE_PIPE_FLUSH ();			/* FLUSH BUFFER  [SPR 68334] */    temp = pSmDesc->anchorLocalAdrs->smHeader;	/* PCI bridge bug [SPR 68844]*/    pHdr = SM_OFFSET_TO_LOCAL (ntohl (pSmDesc->anchorLocalAdrs->smHeader),                               pSmDesc->base, SM_HDR volatile *);    pSmDesc->headerLocalAdrs = (SM_HDR *) pHdr;    /* Copy data from shared mem header */    pSmDesc->maxCpus         = ntohl (pHdr->maxCpus);    pSmDesc->cpuTblLocalAdrs = SM_OFFSET_TO_LOCAL (ntohl (pHdr->cpuTable),                                                   pSmDesc->base,                                                   SM_CPU_DESC *);    /* Determine test-and-set routine to use */    pSmDesc->tasClearRoutine = NULL;    if (ntohl (pHdr->tasType) == SM_TAS_HARD)   /* if using hardware tas */	{        pSmDesc->tasRoutine = smUtilTas;        pSmDesc->tasClearRoutine = (FUNCPTR) smUtilTasClear; 	}    else        pSmDesc->tasRoutine = smUtilSoftTas;    /* use software tas routine */    /* Init entry in cpu table */    if (cpuNum < 0  ||  cpuNum >= pSmDesc->maxCpus)        {        errno = S_smLib_INVALID_CPU_NUMBER;        return (ERROR);                         /* cpu number out of range */        }    /* calculate addr of cpu desc in global table.  */    pCpuDesc = (SM_CPU_DESC volatile *) &((pSmDesc->cpuTblLocalAdrs) [cpuNum]);    pCpuDesc->intType = htonl (pSmDesc->intType); /* interrupt method */    pCpuDesc->intArg1 = htonl (pSmDesc->intArg1); /* interrupt argument #1 */    pCpuDesc->intArg2 = htonl (pSmDesc->intArg2); /* interrupt argument #2 */    pCpuDesc->intArg3 = htonl (pSmDesc->intArg3); /* interrupt argument #3 */    pCpuDesc->status  = htonl (SM_CPU_ATTACHED);  /* mark cpu as attached */    pSmDesc->status = SM_CPU_ATTACHED;          /* also mark sh mem descr */    CACHE_PIPE_FLUSH ();			/* FLUSH BUFFER  [SPR 68334] */    cpuNum = pCpuDesc->intArg1;			/* BRIDGE FLUSH  [SPR 68334] */    return (OK);                                /* attach complete */    }/******************************************************************************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -