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

📄 smlib.c

📁 VxWorks操作系统内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
** smDetach - detach CPU from shared memory** This routine ends the "attachment" between the calling CPU and* the shared memory area specified by <pSmDesc>.  No further shared* memory operations may be performed until a subsequent smAttach()* is completed.** RETURNS: OK, or ERROR.** ERRNO: S_smLib_NOT_ATTACHED*/STATUS smDetach    (    SM_DESC *	pSmDesc       /* ptr to shared mem descriptor */    )    {    SM_CPU_DESC volatile * pCpuDesc;  /* ptr to cpu descriptor in sh mem hdr*/    int			   temp;      /* temp value */    /* Check that this cpu is connected to shared memory */    if (pSmDesc->status != SM_CPU_ATTACHED)        {        errno = S_smLib_NOT_ATTACHED;        return (ERROR);                         /* local cpu is not attached */        }    /* get addr of cpu descriptor */    pCpuDesc = (SM_CPU_DESC volatile *) &((pSmDesc->cpuTblLocalAdrs) \                                           [pSmDesc->cpuNum]);    pCpuDesc->status = htonl (SM_CPU_NOT_ATTACHED);/* mark as not attached */    pSmDesc->status  = SM_CPU_NOT_ATTACHED;       /* also mark sh mem descr */    CACHE_PIPE_FLUSH ();			/* FLUSH BUFFER  [SPR 68334] */    temp = pCpuDesc->status;			/* BRIDGE FLUSH  [SPR 68334] */    return (OK);    }/******************************************************************************** smInfoGet - get current status information about shared memory** This routine obtains various pieces of information which describe the* current state of the shared memory area specified by <pSmDesc>.  The* current information is returned in a special data structure, SM_INFO,* whose address is specified by <pInfo>.  The structure must have been* allocated before this routine is called.** RETURNS: OK, or ERROR if this CPU is not attached to shared memory area.** ERRNO: S_smLib_NOT_ATTACHED*/STATUS smInfoGet    (    SM_DESC *	pSmDesc,	/* ptr to shared memory descriptor */    SM_INFO *	pInfo		/* ptr to info structure to fill */    )    {    SM_HDR volatile *	   pHdr;	/* ptr to shared memory header */    SM_CPU_DESC volatile * pCpuDesc;	/* ptr to cpu descriptor */    int			   ix;		/* index variable */    int			   temp;        /* temp value */    /* Check that this cpu is connected to shared memory */    if (pSmDesc->status != SM_CPU_ATTACHED)	{	errno = S_smLib_NOT_ATTACHED;	return (ERROR);				/* local cpu is not attached */	}    /* Get protocol version number */    CACHE_PIPE_FLUSH ();			/* FLUSH BUFFER  [SPR 68334] */    temp = pSmDesc->anchorLocalAdrs->version;	/* PCI bridge bug [SPR 68844]*/    pInfo->version = ntohl (pSmDesc->anchorLocalAdrs->version);    /* Get info from shared memory header */    pHdr = (SM_HDR volatile *) pSmDesc->headerLocalAdrs;    pInfo->tasType     = ntohl (pHdr->tasType);	   /* test-and-set method */    pInfo->maxCpus     = ntohl (pHdr->maxCpus);	   /* max number of cpu's */    /* Get count of attached cpu's starting with first cpu table entry */    pCpuDesc = (SM_CPU_DESC volatile *) pSmDesc->cpuTblLocalAdrs;    pInfo->attachedCpus = 0;    for (ix = 0;  ix < pInfo->maxCpus;  ix++)	{	if (ntohl (pCpuDesc->status) == SM_CPU_ATTACHED)	    pInfo->attachedCpus++;	pCpuDesc++;				/* next entry */	}    return (OK);    }/******************************************************************************** smCpuInfoGet - get information about a single CPU using shared memory** This routine obtains a variety of information describing the CPU specified* by <cpuNum>.  If <cpuNum> is NONE (-1), this routine returns information* about the local (calling) CPU.  The information is returned in a special* structure, SM_CPU_INFO, whose address is specified by <pCpuInfo>.  (The* structure must have been allocated before this routine is called.)** RETURNS: OK, or ERROR.** ERRNO: S_smLib_NOT_ATTACHED, S_smLib_INVALID_CPU_NUMBER*/STATUS smCpuInfoGet    (    SM_DESC *		pSmDesc,	/* ptr to shared memory descriptor */    int			cpuNum,		/* number of cpu to get info about */    SM_CPU_INFO *	pCpuInfo	/* cpu info structure to fill */    )    {    SM_CPU_DESC volatile * pCpuDesc;	/* ptr to cpu descriptor */    int			   temp;        /* temp value */    /* Check that the local cpu is connected to shared memory */    if (pSmDesc->status != SM_CPU_ATTACHED)	{	errno = S_smLib_NOT_ATTACHED;	return (ERROR);				/* local cpu is not attached */	}    /* Report on local cpu if NONE specified */    if (cpuNum == NONE)        {	cpuNum = pSmDesc->cpuNum;        }    /* Get info from cpu descriptor */    if (cpuNum < 0  ||  cpuNum >= pSmDesc->maxCpus)	{	errno = S_smLib_INVALID_CPU_NUMBER;	return (ERROR);				/* cpu number out of range */	}    /* get address of cpu descr */    pCpuDesc = (SM_CPU_DESC volatile *) &(pSmDesc->cpuTblLocalAdrs [cpuNum]);    pCpuInfo->cpuNum  = cpuNum;			   /* actual cpu number */    CACHE_PIPE_FLUSH ();			/* FLUSH BUFFER  [SPR 68334] */    temp = pCpuDesc->status;			/* PCI bridge bug [SPR 68844]*/    pCpuInfo->status  = ntohl (pCpuDesc->status);  /* attached/not attached */    pCpuInfo->intType = ntohl (pCpuDesc->intType); /* interrupt type */    pCpuInfo->intArg1 = ntohl (pCpuDesc->intArg1); /* interrupt argument #1 */    pCpuInfo->intArg2 = ntohl (pCpuDesc->intArg2); /* interrupt argument #2 */    pCpuInfo->intArg3 = ntohl (pCpuDesc->intArg3); /* interrupt argument #3 */    return (OK);    }/******************************************************************************** smLockTake - take a mutual exclusion lock** This routine repeatedly attempts to obtain a mutual exclusion lock* by using the specified test-and-set routine.  If the lock is not* obtained within the specified number of attempts, an error is returned.** If the lock was successfully taken, interrupts will be disabled when* this routine returns and the old interrupt mask level will be copied* to the location pointed to by <pOldLvl>.** If the lock was not taken, interrupts will be enabled upon return (at* the interrupt level which was in effect prior to calling this routine).** This routine does not set errno.** INTERNAL ** RETURNS: OK, or ERROR if lock not taken.*/STATUS smLockTake    (    int *	lockLocalAdrs,	/* local addr of lock */    FUNCPTR	tasRoutine,	/* test-and-set routine to use */    int		numTries,	/* number of times to try to take lock */    int	*	pOldLvl		/* where to put old int lvl if success */    )    {    int         oldLvl;         /* previous interrupt level */    int         delay;          /* time between tries to get lock */    int         ix;		/* index */    int		dummy = 0;	/* dummy counter for delay */    volatile int dummy2;	/* dummy to avoid warning in delay */    int         curNumTries;    /* current number of tries */     /* First try to get lock. */     oldLvl = intLock ();                /* lock out interrupts */    if ((*tasRoutine) (lockLocalAdrs) == TRUE)        {        *pOldLvl = oldLvl;              /* pass back old int level */	/*	 * XXXdat These PIPE_FLUSH operations should not be needed.	 * The tasRoutine should be taking care of the cache issues	 * related to tas activity.	 */	CACHE_PIPE_FLUSH ();		/* flush write buffer */        dummy2 = *(int *)lockLocalAdrs; /* BRIDGE FLUSH  [SPR 68334] */        return (OK);            	/* done! */        }    intUnlock (oldLvl);         /* unlock interrupts before retry */     /*      * The first try has failed so now we insert a decrementing     * delay between each tries to reduce bus contention and deadlock.     *     * Set maximum delay to a different value for each processor.      * Note that this scheme gives a lowest priority to CPUs with     * high processor number. A better version would implement     * a random delay.     */     delay = smLockTakeDelayMin;    curNumTries = 1;     do        {        for (ix = 0; ix <= delay; ix++) /* delay loop */	    dummy2 = dummy++;           /* volatile!! */         oldLvl = intLock ();            /* lock out interrupts */         if ((*tasRoutine) (lockLocalAdrs) == TRUE)            {            *pOldLvl = oldLvl;          /* pass back old int level */	    CACHE_PIPE_FLUSH ();	/* flush write buffer */            dummy2 = *(int *)lockLocalAdrs; /* BRIDGE FLUSH  [SPR 68334] */            return (OK);                /* done! */            }         intUnlock (oldLvl);             /* unlock interrupts before retry */ 	/* Exponential delay, with a limit */	delay <<= 1;	if (delay > smLockTakeDelayMax)	    {	    delay = smLockTakeDelayMin;	    }        curNumTries++;         /* keep track of maximum number of attempts */        if (curNumTries > smCurMaxTries)            {            smCurMaxTries = curNumTries;            }         } while (--numTries > 0);       /* do for spec'd number of tries */     return (ERROR);                     /* cannot take lock */    }/******************************************************************************** smLockGive - give a mutual exclusion lock** This routine gives up a mutual exclusion lock taken previously by smLockTake.** RETURNS: N/A*/void smLockGive    (    int *	lockLocalAdrs,		/* local address of lock */    FUNCPTR	tasClearRoutine,	/* test and set clear routine to use */    int		oldLvl			/* old interrupt level */    )    {    int volatile * pLockv = (int volatile *) lockLocalAdrs;    int            temp;			/* temp value */    if (tasClearRoutine != NULL)	/* hardware test-and-set */        {	(*tasClearRoutine) (lockLocalAdrs);        }    else        {    	*pLockv = 0;        }    CACHE_PIPE_FLUSH ();		/* FLUSH BUFFER  [SPR 68334] */    temp = *pLockv;			/* BRIDGE FLUSH  [SPR 68334] */    intUnlock (oldLvl);    }/******************************************************************************** smRegionFind - find a shared memory region.** This routine finds the shared memory region associated with* <anchorLocalAdrs>.** RETURNS:  index of the region, or ERROR if not found*/LOCAL int smRegionFind    (    SM_ANCHOR *	anchorLocalAdrs		/* local address of anchor */    )    {    int		ix;			/* index */    for (ix = 0; (smRegions [ix].anchor != NULL) && (ix < smRegionsMax); ix++)	{	if (smRegions [ix].anchor == anchorLocalAdrs)	    {	    return (ix);			/* region already initialized*/	    }	}    return (ERROR);    }/******************************************************************************** smRegionGet - get a shared memory region** smRegionGet reserves a space in the smRegion table for a shared memory* region specified by <anchorLocalAdrs>.** RETURNS: the index of the region, or ERROR if out of space.*/LOCAL int smRegionGet    (    SM_ANCHOR *	anchorLocalAdrs		/* anchor address */    )    {    int		ix;			/* index */    for (ix = 0; (smRegions [ix].anchor != NULL) && (ix < smRegionsMax); ix++)	;    if (ix == smRegionsMax)	{	printf ("Out of shared memory regions!!\n");	errno = S_smLib_NO_REGIONS;	return (ERROR);				/* no space in table */	}    smRegions [ix].anchor = anchorLocalAdrs;    return (ix);    }

⌨️ 快捷键说明

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