📄 msgqsmlib.c
字号:
/* msgQSmLib.c - shared memory message queue library (VxMP Option) *//* Copyright 1990-2002 Wind River Systems, Inc. *//*modification history--------------------01q,06may02,mas cache flush and volatile fix (SPR 68334); bridge flush fix (SPR 68844)01p,24oct01,mas doc update (SPR 71149)01o,13sep01,tcr Fix SPR 29673 - Windview event logging macro01n,14mar99,jdi doc: removed refs to config.h and/or configAll.h (SPR 25663).01m,22feb99,wsl doc: correct typo in name of errno code01l,05oct98,jmp doc: cleanup.01k,17apr98,rlp canceled msgQSmInit and msgQSmSend modifications for backward compatibility.01j,04nov97,rlp modified msgQSmInit and msgQSmSend for tracking messages sent.01i,16oct95,jdi doc: added msgQSmLib.h to list of include files (SPR 4353).01h,22mar94,pme added WindView level 2 event logging.01g,23feb93,jdi more documentation cleanup for 5.1 manual.01f,14feb93,jdi documentation cleanup 5.1.01e,29jan93,pme added little endian support. added #include "private/smObjLibP.h"01d,23nov92,jdi documentation cleanup.01c,02oct92,pme added SPARC support. documentation cleanup.01b,29sep92,pme changed calls to smFree and smMalloc to smMemFree and smMemMalloc. 01a,19jul92,pme added msgQSmLibInit() to reduce coupling. changed function name to msgQSm... cleaned up after code review. written from 01k of msgQLib*//*DESCRIPTIONThis library provides the interface to shared memory message queues.Shared memory message queues allow a variable number of messages (varyingin length) to be queued in first-in-first-out order. Any task running onany CPU in the system can send messages to or receive messages from ashared message queue. Tasks can also send to and receive from thesame shared message queue. Full-duplex communication between twotasks generally requires two shared message queues, one for eachdirection.Shared memory message queues are created with msgQSmCreate(). Oncecreated, they can be manipulated using the generic routines for localmessage queues; for more information on the use of these routines, see themanual entry for msgQLib.MEMORY REQUIREMENTSThe shared memory message queue structure is allocated from a dedicated shared memory partition. This shared memory partition is initialized bythe shared memory objects master CPU. The size of this partition isdefined by the maximum number of shared message queues, SM_OBJ_MAX_MSG_Q.The message queue buffers are allocated from the shared memory system partition. RESTRICTIONSShared memory message queues differ from local message queues in thefollowing ways:\is\i `Interrupt Use:'Shared memory message queues may not be used (sent to or received from) atinterrupt level.\i `Deletion:'There is no way to delete a shared memory message queue and free its associatedshared memory. Attempts to delete a shared message queue return ERROR andset `errno' to S_smObjLib_NO_OBJECT_DESTROY.\i `Queuing Style:'The shared message queue task queueing order specified when a message queue iscreated must be FIFO.\ieCONFIGURATIONBefore routines in this library can be called, the shared memory objectsfacility must be initialized by calling usrSmObjInit(). This is doneautomatically during VxWorks initialization if the component INCLUDE_SM_OBJis included.AVAILABILITY: This module is distributed as a component of the unbundled sharedobjects memory support option, VxMP.INCLUDE FILES: msgQSmLib.h, msgQLib.h, smMemLib.h, smObjLib.hSEE ALSO: msgQLib, smObjLib, msgQShow, usrSmObjInit(),\tb VxWorks Programmer's Guide: Shared Memory Objects*//* LINTLIBRARY */#include "vxWorks.h"#include "errnoLib.h"#include "objLib.h"#include "intLib.h"#include "taskLib.h"#include "cacheLib.h"#include "semLib.h"#include "smMemLib.h"#include "smObjLib.h"#include "msgQLib.h"#include "stdarg.h"#include "string.h"#include "netinet/in.h"#include "private/msgQSmLibP.h"#include "private/msgQLibP.h"#include "private/semSmLibP.h"#include "private/smMemLibP.h"#include "private/smObjLibP.h"#include "private/eventP.h"/******************************************************************************* msgSmLibInit - initialize the shared memory message queue package** SEE ALSO: smObjLibInit().** RETURNS: OK** NOMANUAL*/void msgQSmLibInit (void) { msgQSmSendRtn = (FUNCPTR) msgQSmSend; msgQSmReceiveRtn = (FUNCPTR) msgQSmReceive; msgQSmNumMsgsRtn = (FUNCPTR) msgQSmNumMsgs; }/******************************************************************************* msgQSmCreate - create and initialize a shared memory message queue (VxMP Option)** This routine creates a shared memory message queue capable of holding up* to <maxMsgs> messages, each up to <maxMsgLength> bytes long. It returns a* message queue ID used to identify the created message queue. The queue* can only be created with the option MSG_Q_FIFO (0), thus queuing pended* tasks in FIFO order.** The global message queue identifier returned can be used directly by generic* message queue handling routines in msgQLib -- msgQSend(), msgQReceive(), * and msgQNumMsgs() -- and by the show routines show() and msgQShow().** If there is insufficient memory to store the message queue structure* in the shared memory message queue partition or if the shared memory system* pool cannot handle the requested message queue size, shared memory message * queue creation will fail with `errno' set to S_memLib_NOT_ENOUGH_MEMORY.* This problem can be solved by incrementing the value of SM_OBJ_MAX_MSG_Q* and/or the shared memory objects dedicated memory size SM_OBJ_MEM_SIZE .** Before this routine can be called, the shared memory objects facility must* be initialized (see msgQSmLib).** AVAILABILITY:* This routine is distributed as a component of the unbundled shared memory* objects support option, VxMP.** RETURNS: MSG_Q_ID, or NULL if error.** ERRNO: S_memLib_NOT_ENOUGH_MEMORY, S_intLib_NOT_ISR_CALLABLE,* S_msgQLib_INVALID_QUEUE_TYPE, S_smObjLib_LOCK_TIMEOUT** SEE ALSO: smObjLib, msgQLib, msgQShow*/MSG_Q_ID msgQSmCreate ( int maxMsgs, /* max messages that can be queued */ int maxMsgLength, /* max bytes in a message */ int options /* message queue options */ ) { SM_MSG_Q_ID smMsgQId; void * pSmMsgPool; /* pointer to memory for messages */ int nodeSize = SM_MSG_NODE_SIZE (maxMsgLength); int temp; /* temp storage */ if (INT_RESTRICT () != OK) /* restrict ISR from calling */ { return (NULL); } /* * allocate shared memory message queue descriptor from * dedicated shared memory pool. */ smMsgQId = (SM_MSG_Q_ID) smMemPartAlloc ((SM_PART_ID) smMsgQPartId, sizeof (SM_MSG_Q)); if (smMsgQId == NULL) { return (NULL); } /* * allocate shared memory message queue data buffers from * shared memory system pool. */ pSmMsgPool = smMemMalloc (nodeSize * maxMsgs); if (pSmMsgPool == NULL) { smMemPartFree ((SM_PART_ID) smMsgQPartId, (char *) smMsgQId); return (NULL); } /* Initialize shared memory message queue structure */ if (msgQSmInit (smMsgQId, maxMsgs, maxMsgLength, options, pSmMsgPool) !=OK) { smMemPartFree ((SM_PART_ID) smMsgQPartId, (char *) smMsgQId); smMemFree ((char *) pSmMsgPool); return (NULL); } /* update shared infos data */ CACHE_PIPE_FLUSH (); /* CACHE FLUSH [SPR 68334] */ temp = pSmObjHdr->curNumMsgQ; /* PCI bridge bug [SPR 68844]*/ pSmObjHdr->curNumMsgQ = htonl (ntohl (pSmObjHdr->curNumMsgQ) + 1); CACHE_PIPE_FLUSH (); /* CACHE FLUSH [SPR 68334] */ temp = pSmObjHdr->curNumMsgQ; /* BRIDGE FLUSH [SPR 68334] */ return ((MSG_Q_ID) (SM_OBJ_ADRS_TO_ID (smMsgQId))); }/******************************************************************************* msgQSmInit - initialize a shared memory message queue** This routine initializes a shared memory message queue data structure. Like* msgQSmCreate() the resulting message queue is capable of holding up to* <maxMsgs> messages, each of up to <maxMsgLength> bytes long. However,* instead of dynamically allocating the SM_MSG_Q data structure, this* routine takes a pointer <pSmMsgQ> to the SM_MSG_Q data structure to be* initialized, and a local pointer <pSmMsgPool> to the buffer to be use to* hold queued messages. <pSmMsgPool> must point to a 4-byte aligned buffer* that is (<maxMsgs> * SM_MSG_NODE_SIZE (<maxMsgLength>)).** The queue can be created with the following option:** MSG_Q_FIFO queue pended tasks in FIFO order ** RETURNS: OK or ERROR.** ERRNO: S_msgQLib_INVALID_QUEUE_TYPE** SEE ALSO: msgQSmCreate()** NOMANUAL*/STATUS msgQSmInit ( SM_MSG_Q * pSmMsgQ, /* local pointer to msg queue to initialize */ int maxMsgs, /* max messages that can be queued */ int maxMsgLength, /* max bytes in a message */ int options, /* message queue options */ void * pSmMsgPool /* local pointer to memory for messages */ ) { int ix; int nodeSize = SM_MSG_NODE_SIZE (maxMsgLength); SM_MSG_Q volatile * pSmMsgQv = (SM_MSG_Q volatile *) pSmMsgQ; int temp; /* temp storage */ bzero ((char *) pSmMsgQ, sizeof (*pSmMsgQ));/* clear out msg q structure */ /* initialize msgQ semaphores */ switch (options & MSG_Q_TYPE_MASK) { case MSG_Q_FIFO: { semSmCInit (&pSmMsgQ->msgQSem, SEM_Q_FIFO, 0); semSmCInit (&pSmMsgQ->freeQSem, SEM_Q_FIFO, maxMsgs); break; } default: errno = S_msgQLib_INVALID_QUEUE_TYPE; return (ERROR); } /* put msg nodes on free list */ for (ix = 0; ix < maxMsgs; ix++) { smDllAdd (&pSmMsgQ->freeQ, (SM_DL_NODE *) pSmMsgPool); pSmMsgPool = (void *) (((char *) pSmMsgPool) + nodeSize); } /* initialize rest of message queue */ pSmMsgQv->options = htonl (options); pSmMsgQv->maxMsgs = htonl (maxMsgs); pSmMsgQv->maxMsgLength = htonl (maxMsgLength); pSmMsgQv->objType = htonl (MSG_Q_TYPE_SM); pSmMsgQv->verify = (UINT32) htonl (LOC_TO_GLOB_ADRS (pSmMsgQ)); CACHE_PIPE_FLUSH (); /* CACHE FLUSH [SPR 68334] */ temp = pSmMsgQv->objType; /* BRIDGE FLUSH [SPR 68334] */ return (OK); }/******************************************************************************* msgQSmSend - send a message to a shared memory message queue
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -