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

📄 smlib.c

📁 vxworks源码源码解读是学习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(2)* is completed.** RETURNS: OK, or ERROR.** ERRNO: S_smLib_NOT_ATTACHED*/STATUS smDetach    (    FAST SM_DESC        *pSmDesc       /* ptr to shared mem descriptor */    )    {    FAST SM_CPU_DESC    *pCpuDesc;     /* ptr to cpu descriptor in sh mem hdr*/    /* 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 */        }    pCpuDesc = &((pSmDesc->cpuTblLocalAdrs) [pSmDesc->cpuNum]);                                                /* get addr of cpu descriptor */    pCpuDesc->status = htonl (SM_CPU_NOT_ATTACHED);/* mark as not attached */    pSmDesc->status  = SM_CPU_NOT_ATTACHED;       /* also mark sh mem descr */    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    (    FAST SM_DESC *	pSmDesc,	/* ptr to shared memory descriptor */    FAST SM_INFO *	pInfo		/* ptr to info structure to fill */    )    {    FAST SM_HDR	*	pHdr;		/* ptr to shared memory header */    FAST SM_CPU_DESC *	pCpuDesc;	/* ptr to cpu descriptor */    FAST int		ix;		/* index variable */    /* 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 */    pInfo->version = ntohl (pSmDesc->anchorLocalAdrs->version);    /* Get info from shared memory header */    pHdr = pSmDesc->headerLocalAdrs;		/* get local address of hdr */    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 */    pCpuDesc = pSmDesc->cpuTblLocalAdrs;	/* first entry in cpu table */    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 */    FAST int		cpuNum,		/* number of cpu to get info about */    FAST SM_CPU_INFO *	pCpuInfo	/* cpu info structure to fill */    )    {    FAST SM_CPU_DESC *	pCpuDesc;	/* ptr to cpu descriptor */    /* 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 */	}    pCpuDesc = &(pSmDesc->cpuTblLocalAdrs [cpuNum]);						/* get address of cpu descr */    pCpuInfo->cpuNum  = cpuNum;			  /* actual cpu number */    pCpuInfo->status  = ntohl (pCpuDesc->status);/* attached or 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*/    )    {    FAST 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 */        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.     */     if (numTries < smLockTakeTriesMin)	numTries = smLockTakeTriesMin;    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 */            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 */    )    {    if (tasClearRoutine != NULL)	/* hardware test-and-set */	(*tasClearRoutine) (lockLocalAdrs);    else    	*lockLocalAdrs = 0;    CACHE_PIPE_FLUSH ();		/* flush write buffer */    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 + -