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

📄 smpktlib.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 4 页
字号:
* have to be freed.  A return code of ERROR combined with any other value* of errno indicates that <pPkt> was NOT sent and should be explicitly* freed using smPktFreePut(2).  (A return value of OK indicates that* <pPkt> was either sent or freed before this routine returned, and no* further action is required.)** RETURNS: OK, or ERROR.** ERRNO: S_smPktLib_NOT_ATTACHED, S_smPktLib_INVALID_PACKET,* S_smPktLib_PACKET_TOO_BIG, S_smPktLib_INVALID_CPU_NUMBER,* S_smPktLib_DEST_NOT_ATTACHED* */STATUS smPktSend    (    FAST SM_PKT_DESC	*pSmPktDesc,	/* ptr to shared memory descriptor */    FAST SM_PKT		*pPkt,		/* local addr of packet to be sent */    FAST int		destCpu		/* destination cpu number */    )    {    FAST STATUS			status;		/* return status */    FAST SM_PKT_CPU_DESC	*pPktCpuDesc;	/* destination cpu pkt descr*/    FAST SM_CPU_DESC		*pCpuDesc;	/* destination cpu descr*/    BOOL			listWasEmpty;	/* list empty */    FAST SM_DESC *		pSmDesc = &pSmPktDesc->smDesc;    /* Check that this cpu is connected to shared memory */    if (pSmPktDesc->status != SM_CPU_ATTACHED)	{	errno = S_smPktLib_NOT_ATTACHED;	return (ERROR);				/* local cpu is not attached */	}    /* Check for null pointer */    if (pPkt == NULL)	{	errno = S_smPktLib_INVALID_PACKET;	return (ERROR);				/* null packet address */	}    /* Enforce max data length */    if (pPkt->header.nBytes > pSmPktDesc->maxPktBytes)	{	errno = S_smPktLib_PACKET_TOO_BIG;	return (ERROR);				/* too much data ! */	}						/* byte swap info */    pPkt->header.nBytes = htonl (pPkt->header.nBytes);    /* Call special routine if doing broadcast */    if (destCpu == SM_BROADCAST)		/* if sending to all cpu's */	return (smPktBroadcast (pSmPktDesc, pPkt));    /* Make sure destination cpu is valid and attached */    if (destCpu < 0  ||  destCpu >= pSmDesc->maxCpus)        {        errno = S_smPktLib_INVALID_CPU_NUMBER;        return (ERROR);				/* cpu number out of range */        }    pPktCpuDesc = &((pSmPktDesc->cpuLocalAdrs) [destCpu]);    pCpuDesc    = &((pSmDesc->cpuTblLocalAdrs) [destCpu]);    						/* get addr of cpu descriptor */    if (ntohl (pPktCpuDesc->status) != SM_CPU_ATTACHED)        {        errno = S_smPktLib_DEST_NOT_ATTACHED;        return (ERROR);				/* dest cpu is not attached */        }    /* Complete packet header info */    pPkt->header.srcCpu   = htonl (pSmDesc->cpuNum);	/* source cpu */    /* Add this packet to destination cpu's input list */    status = smPktSllPut (&(pPktCpuDesc->inputList), pSmDesc->base,			  pSmDesc->tasRoutine, pSmDesc->tasClearRoutine, 			  &(pPkt->header.node), &listWasEmpty);    if ((listWasEmpty) && (destCpu != pSmDesc->cpuNum))        {					/* if list previously empty */	/* Interrupt destination cpu */	if (smUtilIntGen (pCpuDesc, destCpu) != OK)	    return (ERROR);			/* int gen routine error */        }    else if (status == ERROR)        {        return (ERROR);				/* error adding to list */        }    return (OK);    }/********************************************************************************* smPktBroadcast - send packet data to all attached CPU's via shared memory** This sends a copy of the packet specified by <pPkt> to all CPU's attached* to the specified shared memory area (except the sending CPU).** This routine attempts to obtain a new packet for each destination CPU,* copying the packet contents to each newly-acquired packet.  If no new* packets are available, this routine will go ahead and send the original* packet to the next destination CPU.  If there are still more destinations* after the original has been sent, an error (S_smPktLib_INCOMPLETE_BROADCAST)* is returned.  This same error is returned if one or more destinations did* not receive the broadcast due to other problems (e.g. the input queue for* a destination CPU was full).** RETURNS: OK, or ERROR.*/LOCAL STATUS smPktBroadcast    (    FAST SM_PKT_DESC *		pSmPktDesc,	/* sh mem pkt descriptor */    FAST SM_PKT *		pPktOrig	/* ptr to original packet */    )    {    FAST STATUS			status;		/* return status */    FAST SM_PKT	*		pPkt;		/* ptr to packet being sent */    SM_PKT *			pPktNew;	/* ptr to newly obtained pkt */    FAST int			destCpu;	/* destination cpu number */    FAST SM_CPU_DESC *		pCpuDesc;	/* destination cpu descriptor */    FAST SM_PKT_CPU_DESC *	pPktCpuDesc;	/* destination cpu descriptor */    BOOL			destMissed;	/* TRUE if a dest was missed */    BOOL			listWasEmpty;	/* list added to was empty */    FAST SM_DESC *		pSmDesc = &pSmPktDesc->smDesc;    pCpuDesc = pSmDesc->cpuTblLocalAdrs;    pPktCpuDesc = pSmPktDesc->cpuLocalAdrs;    destMissed = FALSE;				/* no destinations missed yet */    /* Send copy of packet to each attached cpu (except self) */    for (destCpu = 0;  destCpu < pSmDesc->maxCpus;  destCpu++)        {        if ((ntohl (pPktCpuDesc->status) == SM_CPU_ATTACHED)  &&	    (destCpu != pSmDesc->cpuNum))    	    {    	    if (pPktOrig == NULL)		/* if original already used */    	    	{    	    	destMissed = TRUE;		/* weren't enough free packets*/    	    	break;				/* can't do any more */    	    	}	    /* Get new packet */    	    if (smPktFreeGet (pSmPktDesc, &pPktNew) != OK)    	    	return (ERROR);			/* error getting packet */    	    if (pPktNew != NULL)		/* if a new pkt was obtained */    	    	{		pPkt = pPktNew;			/* it is the packet to send */    	    	pPkt->header.type   = pPktOrig->header.type;						/* copy packet type */    	    	pPkt->header.nBytes = pPktOrig->header.nBytes;						/* copy byte count */    	    	bcopy (pPktOrig->data, pPkt->data, ntohl (pPkt->header.nBytes));    						/* copy packet data */    	    	}    	    else				/* if could not get new pkt */    	    	{    	    	pPkt = pPktOrig;		/*  set up to send original */    	    	}    	    pPkt->header.srcCpu  = htonl (pSmDesc->cpuNum);						/* source cpu number */    	    /* Send packet */            status = smPktSllPut (&(pPktCpuDesc->inputList), pSmDesc->base, 				  pSmDesc->tasRoutine, pSmDesc->tasClearRoutine,    			          &(pPkt->header.node), &listWasEmpty);            if ((status == OK) && listWasEmpty)	/* if list previously empty */        	{		/* Interrupt destination CPU */        	if (smUtilIntGen (pCpuDesc, destCpu) != OK)		    {		    destMissed = TRUE;	/* a destination was missed */		    }        	}    	    else if (status == ERROR)		/* if error sending pkt */		{		/*  NOTE: We do not return just because an error occurred.		 *        The destination cpu's input list may simply have been		 *        full, or some other error may have occurred which		 *	  will not affect the remaining destinations.  When		 *	  this routine ultimately returns, the broadcast will		 *	  be reported as having been incomplete.		 */		destMissed = TRUE;		/* a destination was missed */		if (pPkt != pPktOrig)		/* if pkt was not the original*/        	    {    	    	    /* New packet not sent - return to free pool */        	    if (smPktFreePut (pSmPktDesc, pPkt) != OK)    		    	return (ERROR);		/* could not return packet */		    }    	    	}    	    if (pPkt == pPktOrig  &&  status != ERROR)    	    	{				/* if original actually sent */    	    	pPktOrig = NULL;		/*  clear pointer to orig pkt */    	    	}    	    }  /* end if (attached) */        pCpuDesc++;				/* next cpu descriptor */	pPktCpuDesc++;        }  /* end for */    /* Free original packet if it wasn't sent during broadcast */    if (pPktOrig != NULL)        {        if (smPktFreePut (pSmPktDesc, pPktOrig) != OK)    	    return (ERROR);			/* could not free packet */        }    if (destMissed)				/* if a destination was missed*/	{    	errno = S_smPktLib_INCOMPLETE_BROADCAST;    	return (ERROR);				/* broadcast not complete */    	}    else	{    	return (OK);	}    }/********************************************************************************* smPktFreePut - return a shared memory packet to free list** This routine frees a shared memory packet.  The packet is placed* on the global free packet list.  No modification of the packet* contents is performed.** The address of the packet to be returned is specified in <pPkt>.** RETURNS: OK, or ERROR.** ERRNO: S_smPktLib_NOT_ATTACHED, S_smPktLib_INVALID_PACKET*/STATUS smPktFreePut    (    FAST SM_PKT_DESC	*pSmPktDesc,	/* ptr to shared memory descriptor */    SM_PKT		*pPkt		/* addr of packet to be returned */    )    {    FAST SM_DESC *	pSmDesc = &pSmPktDesc->smDesc;    /* Check that this cpu is connected to shared memory */    if (pSmPktDesc->status != SM_CPU_ATTACHED)	{	errno = S_smPktLib_NOT_ATTACHED;	return (ERROR);				/* local cpu is not attached */	}    /* Check for null pointer */    if (pPkt == NULL)	{	errno = S_smPktLib_INVALID_PACKET;	return (ERROR);				/* null packet address */	}    /* Return packet to free list */    return (smPktSllPut (&(pSmPktDesc->hdrLocalAdrs->freeList), pSmDesc->base, 			 pSmDesc->tasRoutine, pSmDesc->tasClearRoutine, 			 &(pPkt->header.node), NULL));    }/********************************************************************************* smPktRecv - receive a packet sent via shared memory** This routine receives a shared memory packet which was queued to this CPU.* This routine should be called in response to an interrupt which notifies* this CPU of the packet, or it can be called repeatedly in a polling* fashion to check for input packets.  (NOTE: An interrupt will be generated* only if there previously was not a packet queued to this CPU.  Therefore,* after a packet is received, this routine should be called again to check* for more packets.)** Upon return, the location indicated by <ppPkt> will contain the address* of the received packet, or NULL if there was none.** RETURNS: OK, or ERROR.** ERRNO: S_smPktLib_NOT_ATTACHED*/STATUS smPktRecv    (    FAST SM_PKT_DESC	*pSmPktDesc,		/* shared memory descriptor */    SM_PKT		**ppPkt			/* location to put pkt addr */    )    {    FAST SM_PKT_CPU_DESC *	pPktCpuDesc;    STATUS			status;    FAST SM_DESC *		pSmDesc = &pSmPktDesc->smDesc;    /* Check that this cpu is connected to shared memory */    if (pSmPktDesc->status != SM_CPU_ATTACHED)	{	errno = S_smPktLib_NOT_ATTACHED;	return (ERROR);				/* local cpu is not attached */	}    /* Get packet (if any) from input list */    pPktCpuDesc = &((pSmPktDesc->cpuLocalAdrs) [pSmDesc->cpuNum]);    						/* get addr of cpu descriptor */    status = smPktSllGet (&(pPktCpuDesc->inputList), pSmDesc->base,    		      	  pSmDesc->tasRoutine, pSmDesc->tasClearRoutine, 			  (SM_SLL_NODE **) ppPkt);    if ((status == OK) && (*ppPkt != NULL))	{	(*ppPkt)->header.nBytes = ntohl ((*ppPkt)->header.nBytes);	(*ppPkt)->header.srcCpu = ntohl ((*ppPkt)->header.srcCpu);	}    return (status);    }/********************************************************************************* smPktSllGet - get a shared memory node from a singly-linked list** This routine attempts to obtain a shared memory node from the* specified singly-linked list of nodes.  If a node is available,* the local address (for this CPU) of the node is placed in the* location specified by <pNodeLocalAdrs>.  If no node was available* from the list, a NULL is placed in this location.*

⌨️ 快捷键说明

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