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

📄 msgqsmlib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
** This routine sends the message in <buffer> of length <nBytes> to the* shared memory message queue <smMsgQId>.  If any tasks are already waiting to* receive messages on the queue, the message will immediately be delivered* to the first waiting task.  If no task is waiting to receive messages, the* message is saved in the message queue.** The <timeout> parameter specifies the number of ticks to wait for free* space if the message queue is full.  <timeout> can have the special value* NO_WAIT that indicates msgQSend() will return immediately even if the* message has not been sent.  Another value for <timeout> is WAIT_FOREVER* that indicates that msgQSend() will never timeout.** The <priority> parameter specifies the priority of the message being sent.* Normal priority messages (MSG_PRI_NORMAL) are added to the tail* of the list of queued messages.  Urgent priority messages* (MSG_PRI_URGENT) are added to the head of the list.** This routine is normally called by the generic msgQSend() system call. * The lower bit of the identifier passed to msgQSend() is used to * differentiate local and shared memory message queues.** This routine not callable at interrupt level.** RETURNS: OK or ERROR.** ERRNO: S_objLib_OBJ_ID_ERROR, S_objLib_OBJ_UNAVAILABLE,*        S_objLib_OBJ_TIMEOUT, S_msgQLib_INVALID_MSG_LENGTH,*        S_smObjLib_LOCK_TIMEOUT** NOMANUAL*/STATUS msgQSmSend     (    SM_MSG_Q_ID    smMsgQId,       /* message queue on which to send */    char *         buffer,         /* message to send */    UINT           nBytes,         /* length of message */    int            timeout,        /* ticks to wait */    int            priority        /* MSG_PRI_NORMAL or MSG_PRI_URGENT */    )    {    SM_MSG_NODE volatile * pMsg;    SM_DL_NODE *           prevNode;    int                    level;    SM_MSG_Q_ID volatile   smMsgQIdv = (SM_MSG_Q_ID volatile) smMsgQId;    int                    temp;   /* temp storage */    if (INT_RESTRICT () != OK)          /* not ISR callable */        {        return (ERROR);        }    CACHE_PIPE_FLUSH ();                        /* CACHE FLUSH   [SPR 68334] */    temp = smMsgQIdv->verify;                   /* PCI bridge bug [SPR 68844]*/    if (SM_OBJ_VERIFY (smMsgQIdv) != OK)        {	return (ERROR);        }    if (nBytes > ntohl (smMsgQId->maxMsgLength))	{	errno = S_msgQLib_INVALID_MSG_LENGTH;	return (ERROR);	}    TASK_LOCK ();    /* windview level 2 event logging, uses the OSE logging routine */    EVT_OBJ_SM_MSGQ (EVENT_MSGQSEND, smMsgQId, buffer, nBytes, timeout, 		     priority,5);    /* get a free message by taking free msg Q shared counting semaphore */    if (semSmTake (&smMsgQId->freeQSem, timeout) != OK)	{	smMsgQId->sendTimeouts = htonl (ntohl (smMsgQId->sendTimeouts) + 1);	TASK_UNLOCK ();	return (ERROR);	}    /* a free message was available before timeout, get it */    if (SM_OBJ_LOCK_TAKE (&smMsgQId->freeQLock, &level) != OK)        {	smObjTimeoutLogMsg ("msgQSend", (char *) &smMsgQId->freeQLock);        TASK_UNLOCK ();        return (ERROR);                         /* can't take lock */	}    pMsg = (SM_MSG_NODE volatile *) smDllGet (&smMsgQId->freeQ);    SM_OBJ_LOCK_GIVE (&smMsgQId->freeQLock, level);/* release lock */    pMsg->msgLength = htonl (nBytes);    bcopy (buffer, SM_MSG_NODE_DATA (pMsg), (int) nBytes);    CACHE_PIPE_FLUSH ();                        /* CACHE FLUSH   [SPR 68334] */    temp = pMsg->msgLength;                     /* BRIDGE FLUSH  [SPR 68334] */    /* now send message */    if (SM_OBJ_LOCK_TAKE (&smMsgQId->msgQLock, &level) != OK)        {	smObjTimeoutLogMsg ("msgQSend", (char *) &smMsgQId->msgQLock);        TASK_UNLOCK ();        return (ERROR);                         /* can't take lock */	}    /* insert message in message list according to its priority */    if (priority == MSG_PRI_NORMAL) 	{	prevNode = (SM_DL_NODE *) SM_DL_LAST (&smMsgQId->msgQ);	}    else prevNode = NULL;     smDllInsert (&smMsgQId->msgQ, prevNode, (SM_DL_NODE *) pMsg);    SM_OBJ_LOCK_GIVE (&smMsgQId->msgQLock, level);/* release lock */          /*       * If another CPU is currently doing a msgQ send       * we can have a case where the other CPU has put a message and       * is delayed by an interrupt before Giving the shared       * semaphore. In that case, this CPU can put its message and Give       * the shared semaphore, the receiver will be unblocked by       * the Give done by this CPU but the message obtained will       * be the one put by the other CPU (FIFO order of messages will be kept).       */    /* unblock receiver */    if (semSmGive (&smMsgQId->msgQSem) != OK)        {        TASK_UNLOCK (); 	return (ERROR);	}	    TASK_UNLOCK ();    return (OK);    }/******************************************************************************* msgQSmReceive - receive a message from a shared memory message queue** This routine receives a message from the shared memory message queue* <smMsgQId>.  The received message is copied into the specified <buffer>,* which is <maxNBytes> in length.  If the message is longer than <maxNBytes>,* the remainder of the message is discarded (no error indication is returned).** The <timeout> parameter specifies the number of ticks to wait for a* message to be sent to the queue, if no message is available when* msgQSmReceive() is called. <timeout> can have the special value NO_WAIT* that indicates msgQSmReceive() will return immediately even if a message* is available.  Another value for <timeout> is WAIT_FOREVER that indicates* that msgQSmReceive() will never timeout.** This routine is normally called by the generic msgQReceive() system call. * The lower bit of the identifier passed to msgQReceive() is used to * differentiate local and shared memory message queues.** This routine cannot be called by interrupt service routines.** RETURNS:* The number of bytes copied to <buffer>, or ERROR.** ERRNO: S_smObjLib_OBJ_ID_ERROR, S_objLib_OBJ_UNAVAILABLE,*        S_objLib_OBJ_TIMEOUT, S_msgQLib_INVALID_MSG_LENGTH,*        S_smObjLib_LOCK_TIMEOUT** NOMANUAL*/int msgQSmReceive     (    SM_MSG_Q_ID    smMsgQId,       /* message queue from which to receive*/    char *         buffer,         /* buffer to receive message */    UINT           maxNBytes,      /* length of buffer */    int            timeout         /* ticks to wait */    )    {    SM_MSG_NODE volatile * pMsg;    int	                   bytesReturned;    int                    level;    SM_MSG_Q_ID volatile   smMsgQIdv = (SM_MSG_Q_ID volatile) smMsgQId;    int                    temp;   /* temp storage */    /*      * even though maxNBytes is unsigned, check for < 0 to catch      * possible caller errors     */    if ((int) maxNBytes < 0)	{	errno = S_msgQLib_INVALID_MSG_LENGTH;	return (ERROR);	}    TASK_LOCK ();    /* windview level 2 event logging, uses the OSE logging routine */    EVT_OBJ_SM_MSGQ (EVENT_MSGQRECEIVE, smMsgQId, buffer, maxNBytes, 		     timeout, 0,4);    CACHE_PIPE_FLUSH ();                        /* CACHE FLUSH   [SPR 68334] */    temp = smMsgQIdv->verify;                   /* PCI bridge bug [SPR 68844]*/    if (SM_OBJ_VERIFY (smMsgQIdv) != OK)	{	TASK_UNLOCK ();	return (ERROR);	}    /* block until a message is available */    if (semSmTake (&smMsgQId->msgQSem, timeout) != OK)        {        smMsgQId->recvTimeouts = htonl (ntohl (smMsgQId->recvTimeouts) + 1);        TASK_UNLOCK ();        return (ERROR);        }    /* a message was available before timeout, get it */    if (SM_OBJ_LOCK_TAKE (&smMsgQId->msgQLock, &level) != OK)        {	smObjTimeoutLogMsg ("msgQReceive", (char *) &smMsgQId->msgQLock);        TASK_UNLOCK ();        return (ERROR);                         /* can't take lock */        }    pMsg = (SM_MSG_NODE volatile *) smDllGet (&smMsgQId->msgQ);    SM_OBJ_LOCK_GIVE (&smMsgQId->msgQLock, level);/* release lock */    CACHE_PIPE_FLUSH ();                        /* CACHE FLUSH   [SPR 68334] */    temp = pMsg->msgLength;                     /* PCI bridge bug [SPR 68844]*/    bytesReturned = min (ntohl (pMsg->msgLength), maxNBytes);    bcopy (SM_MSG_NODE_DATA (pMsg), buffer, bytesReturned);    /* now give back message to free queue */    if (SM_OBJ_LOCK_TAKE (&smMsgQId->freeQLock, &level) != OK)        {	smObjTimeoutLogMsg ("msgQReceive", (char *) &smMsgQId->freeQLock);        TASK_UNLOCK ();        return (ERROR);                         /* can't take lock */        }    smDllAdd (&smMsgQId->freeQ, (SM_DL_NODE *) pMsg);    SM_OBJ_LOCK_GIVE (&smMsgQId->freeQLock, level);/* release lock */    /* now give free queue semaphore */    if (semSmGive (&smMsgQId->freeQSem) != OK)        {        TASK_UNLOCK ();        return (ERROR);        }    TASK_UNLOCK ();    return (bytesReturned);    }/******************************************************************************* msgQSmNumMsgs - get number of messages queued to shared memory message queue** This routine returns the number of messages currently queued to a specified* message queue <smMsgQId>.** This routine is normally called by the generic msgQNumMsgs() system call. * The lower bit of the identifier passed to msgQNumMsgs() is used to * differentiate local and shared memory message queues.** RETURNS:* The number of messages queued, or ERROR.** ERRNO: S_objLib_OBJ_ID_ERROR** NOMANUAL*/int msgQSmNumMsgs     (    SM_MSG_Q_ID       smMsgQId          /* message queue to examine */    )    {    SM_MSG_Q_ID volatile smMsgQIdv = (SM_MSG_Q_ID volatile) smMsgQId;    int                  temp;         /* temp storage */    CACHE_PIPE_FLUSH ();                        /* CACHE FLUSH   [SPR 68334] */    temp = smMsgQIdv->verify;                   /* PCI bridge bug [SPR 68844]*/    if (SM_OBJ_VERIFY (smMsgQIdv) != OK)        {	return (ERROR);        }    temp = smMsgQIdv->msgQSem.state.count;      /* PCI bridge bug [SPR 68844]*/    temp = smMsgQIdv->msgQSem.state.count;    return (ntohl (temp));    }

⌨️ 快捷键说明

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