/* * ======== tsk0 ======== */ Void tsk0(UArg arg0, UArg arg1) { Int status; MessageQ_Msg msg; System_printf("tsk0 starting\n"); /* Register this heap with MessageQ */ MessageQ_registerHeap((IHeap_Handle)SharedRegion_getHeap(0), HEAP_ID); /* Open the 'next' remote message queue. Spin until it is ready. */ do { status = MessageQ_open(nextQueueName, &nextQueueId); } while (status < 0); if (selfId == 0) { msg = MessageQ_alloc(HEAP_ID, MSGSIZE); if (msg == NULL) { System_abort("MessageQ_alloc failed\n"); } /* Kick off the loop */ status = MessageQ_put(nextQueueId, msg); if (status < 0) { System_abort("MessageQ_put failed\n"); } } for (numReceived = 0; numReceived < NUMLOOPS; numReceived++) { /* Get a message */ status = MessageQ_get(messageQ, &msg, MessageQ_FOREVER); if (status < 0) { System_abort("MessageQ_get failed\n"); } if (selfId == 0) { rawtimestamps[numReceived] = Timestamp_get32(); if (numReceived == NUMLOOPS - 1) { printStatistics(); break; } } status = MessageQ_put(nextQueueId, msg); if (status < 0) { System_abort("MessageQ_put failed\n"); } } System_exit(0); }
/* * ======== serverTask ======== */ Void serverTask(UArg arg0, UArg arg1) { MessageQ_Handle serverMessageQ; MessageQ_QueueId replyQueue; MessageQ_Msg msg; UInt16 msgId; Int status; serverMessageQ = MessageQ_create(SERVERNAME, NULL); /* Loop forever processing requests */ System_printf("Server is ready to set processing requests\n"); while (TRUE) { /* Wait for a request. */ status = MessageQ_get(serverMessageQ, &msg, MessageQ_FOREVER); if (status < 0) { System_abort("Stopping test\n"); } /* Get the id and increment it to send back as validation */ msgId = MessageQ_getMsgId(msg); msgId += NUMCLIENTS; MessageQ_setMsgId(msg, msgId); /* Use the embedded reply destination */ replyQueue = MessageQ_getReplyQueue(msg); /* Send the response back */ status = MessageQ_put(replyQueue, msg); if (status < 0) { System_abort("MessageQ_put was not successful\n"); } } }
/* * ======== loopbackFxn======== * Receive and return messages. * Run at priority lower than tsk1Fxn above. * Inputs: * - arg0: number of the thread, appended to MessageQ host and slave names. */ Void loopbackFxn(UArg arg0, UArg arg1) { MessageQ_Msg getMsg; MessageQ_Handle messageQ; MessageQ_QueueId remoteQueueId; Int status; UInt16 msgId = 0; Char localQueueName[64]; Char hostQueueName[64]; System_printf("Thread loopbackFxn: %d\n", arg0); System_sprintf(localQueueName, "%s_%d", SLAVE_MESSAGEQNAME, arg0); System_sprintf(hostQueueName, "%s_%d", HOST_MESSAGEQNAME, arg0); /* Create a message queue. */ messageQ = MessageQ_create(localQueueName, NULL); if (messageQ == NULL) { System_abort("MessageQ_create failed\n"); } System_printf("loopbackFxn: created MessageQ: %s; QueueID: 0x%x\n", localQueueName, MessageQ_getQueueId(messageQ)); System_printf("Start the main loop: %d\n", arg0); while (msgId < NUMLOOPS) { /* Get a message */ status = MessageQ_get(messageQ, &getMsg, MessageQ_FOREVER); if (status != MessageQ_S_SUCCESS) { System_abort("This should not happen since timeout is forever\n"); } remoteQueueId = MessageQ_getReplyQueue(getMsg); #ifndef BENCHMARK System_printf("%d: Received message #%d from core %d\n", arg0, MessageQ_getMsgId(getMsg), MessageQ_getProcId(remoteQueueId)); #endif /* test id of message received */ if (MessageQ_getMsgId(getMsg) != msgId) { System_abort("The id received is incorrect!\n"); } #ifndef BENCHMARK /* Send it back */ System_printf("%d: Sending message Id #%d to core %d\n", arg0, msgId, MessageQ_getProcId(remoteQueueId)); #endif status = MessageQ_put(remoteQueueId, getMsg); if (status != MessageQ_S_SUCCESS) { System_abort("MessageQ_put had a failure/error\n"); } msgId++; } MessageQ_delete(&messageQ); numTests += NUMLOOPS; System_printf("Test thread %d complete!\n", arg0); }
Int RcmClient_execCmd(RcmClient_Object *obj, RcmClient_Message *msg) { RcmClient_Packet *packet; MessageQ_Msg msgqMsg; Int rval; Int status = RcmClient_S_SUCCESS; Log_print2(Diags_ENTRY | Diags_INFO, "--> "FXNN": (obj=0x%x, msg=0x%x)", (IArg)obj, (IArg)msg); /* classify this message */ packet = RcmClient_getPacketAddr_P(msg); packet->desc |= RcmClient_Desc_CMD << RcmClient_Desc_TYPE_SHIFT; /* set the return address to the error message queue */ msgqMsg = (MessageQ_Msg)packet; MessageQ_setReplyQueue(obj->errorMsgQue, msgqMsg); /* send the message to the server */ rval = MessageQ_put((MessageQ_QueueId)obj->serverMsgQ, msgqMsg); if (rval < 0) { Log_error0(FXNN": unable to send message to server"); status = RcmClient_E_IPCERROR; } Log_print1(Diags_EXIT | Diags_INFO, "<-- "FXNN": %d", (IArg)status); return(status); }
/* * ======== Server_delete ======== */ Int Server_delete() { Int status; GateMPApp_Msg * msg; MessageQ_QueueId queId; Log_print0(Diags_ENTRY, "--> Server_delete:"); /* wait for inbound message */ status = MessageQ_get(Module.slaveQue, (MessageQ_Msg *)&msg, MessageQ_FOREVER); if (status < 0) { goto leave; } Log_print0(Diags_ENTRY, "--> Server_delete: got msg"); if (msg->cmd != GATEMPAPP_CMD_SHUTDOWN) { status = GATEMPAPP_E_UNEXPECTEDMSG; goto leave; } /* send message back to say that GateMP has been cleaned up */ queId = MessageQ_getReplyQueue(msg); /* type-cast not needed */ msg->cmd = GATEMPAPP_CMD_SHUTDOWN_ACK; MessageQ_put(queId, (MessageQ_Msg)msg); /* delete the video message queue */ status = MessageQ_delete(&Module.slaveQue); if (status < 0) { Log_print0(Diags_ENTRY, "Server_delete: MessageQ_delete failed"); goto leave; } Log_print0(Diags_ENTRY, "Server_delete: MessageQ deleted"); /* delete slave GateMP */ status = GateMP_delete(&Module.slaveGateMPHandle); if (status < 0) { Log_print0(Diags_ENTRY, "Server_delete: GateMP_delete failed"); goto leave; } Log_print0(Diags_ENTRY, "Server_delete: slave GateMP deleted"); leave: if (status < 0) { Log_error1("Server_delete: error=0x%x", (IArg)status); } /* disable log events */ Log_print1(Diags_EXIT, "<-- Server_delete: %d", (IArg)status); Diags_setMask(MODULE_NAME"-EXF"); return(status); }
/** * Handler for messageq put API. * * \param ctp Thread's associated context information. * \param msg The actual devctl() message. * \param ocb OCB associated with client's session. * * \return POSIX errno value. * * \retval EOK Success. * \retval ENOTSUP Unsupported devctl(). */ int syslink_messageq_put(resmgr_context_t *ctp, io_devctl_t *msg, syslink_ocb_t *ocb) { MessageQDrv_CmdArgs * cargs = (MessageQDrv_CmdArgs *) (_DEVCTL_DATA (msg->i)); MessageQDrv_CmdArgs * out = (MessageQDrv_CmdArgs *) (_DEVCTL_DATA (msg->o)); MessageQ_Msg lmsg; lmsg = SharedRegion_getPtr (cargs->args.put.msgSrPtr); out->apiStatus = MessageQ_put (cargs->args.put.queueId, lmsg); return (_RESMGR_PTR (ctp, &msg->o, sizeof (msg->o) + sizeof(MessageQDrv_CmdArgs))); }
Int RcmClient_execDpc(RcmClient_Object *obj, RcmClient_Message *cmdMsg, RcmClient_Message **returnMsg) { RcmClient_Packet *packet; RcmClient_Message *rtnMsg; MessageQ_Msg msgqMsg; UInt16 msgId; Int rval; Int status = RcmClient_S_SUCCESS; Log_print3(Diags_ENTRY, "--> %s: 0x%x, 0x%x", (IArg)FXNN, (IArg)obj, (IArg)returnMsg); /* classify this message */ packet = RcmClient_getPacketAddr_P(cmdMsg); packet->desc |= RcmClient_Desc_DPC << RcmClient_Desc_TYPE_SHIFT; msgId = packet->msgId; /* set the return address to this instance's message queue */ msgqMsg = (MessageQ_Msg)packet; MessageQ_setReplyQueue(obj->msgQue, msgqMsg); /* send the message to the server */ rval = MessageQ_put((MessageQ_QueueId)obj->serverMsgQ, msgqMsg); if (rval < 0) { /* Log_error() */ Log_error0(FXNN": unable to the send message to the server"); status = RcmClient_E_EXECFAILED; goto leave; } /* get the return message from the server */ rval = RcmClient_getReturnMsg_P(obj, msgId, &rtnMsg); if (rval < 0) { *returnMsg = NULL; status = rval; goto leave; } *returnMsg = rtnMsg; leave: Log_print2(Diags_EXIT, "<-- %s: %d", (IArg)FXNN, (IArg)status); return(status); }
Int RcmClient_execAsync(RcmClient_Object *obj, RcmClient_Message *cmdMsg, RcmClient_CallbackFxn callback, Ptr appData) { RcmClient_Packet *packet; MessageQ_Msg msgqMsg; Int rval; Int status = RcmClient_S_SUCCESS; Log_print3(Diags_ENTRY, "--> %s: 0x%x, 0x%x", (IArg)FXNN, (IArg)obj, (IArg)cmdMsg); /* cannot use this function if callback notification is false */ if (!obj->cbNotify) { Log_error0(FXNN": asynchronous notification not enabled"); status = RcmClient_E_EXECASYNCNOTENABLED; goto leave; } /* classify this message */ packet = RcmClient_getPacketAddr_P(cmdMsg); packet->desc |= RcmClient_Desc_RCM_MSG << RcmClient_Desc_TYPE_SHIFT; /* set the return address to this instance's message queue */ msgqMsg = (MessageQ_Msg)packet; MessageQ_setReplyQueue(obj->msgQue, msgqMsg); /* send the message to the server */ rval = MessageQ_put((MessageQ_QueueId)obj->serverMsgQ, msgqMsg); if (rval < 0) { Log_error0(FXNN": unable to the send message to the server"); status = RcmClient_E_EXECFAILED; goto leave; } /* TODO finish this function */ leave: Log_print2(Diags_EXIT, "<-- %s: %d", (IArg)FXNN, (IArg)status); return(status); }
/* * ======== TransportShm_swiFxn ======== */ Void TransportShm_swiFxn(UArg arg) { UInt32 queueId; TransportShm_Object *obj = (TransportShm_Object *)arg; MessageQ_Msg msg = NULL; /* * While there are messages, get them out and send them to * their final destination. */ msg = (MessageQ_Msg)ListMP_getHead((ListMP_Handle)obj->localList); while (msg != NULL) { /* Get the destination message queue Id */ queueId = MessageQ_getDstQueue(msg); /* put the message to the destination queue */ MessageQ_put(queueId, msg); /* check to see if there are more messages */ msg = (MessageQ_Msg)ListMP_getHead((ListMP_Handle)obj->localList); } }
Int RcmClient_execNoWait(RcmClient_Object *obj, RcmClient_Message *cmdMsg, UInt16 *msgId) { RcmClient_Packet *packet; MessageQ_Msg msgqMsg; Int rval; Int status = RcmClient_S_SUCCESS; Log_print4(Diags_ENTRY, "--> %s: 0x%x, 0x%x, 0x%x", (IArg)FXNN, (IArg)obj, (IArg)cmdMsg, (IArg)msgId); /* classify this message */ packet = RcmClient_getPacketAddr_P(cmdMsg); packet->desc |= RcmClient_Desc_RCM_MSG << RcmClient_Desc_TYPE_SHIFT; *msgId = packet->msgId; /* set the return address to this instance's message queue */ msgqMsg = (MessageQ_Msg)packet; MessageQ_setReplyQueue(obj->msgQue, msgqMsg); /* send the message to the server */ Log_print1(Diags_ANALYSIS, "%s: >>> MessageQ_put", (IArg)FXNN); rval = MessageQ_put((MessageQ_QueueId)obj->serverMsgQ, msgqMsg); Log_print1(Diags_ANALYSIS, "%s: <<< MessageQ_put", (IArg)FXNN); if (rval < 0) { *msgId = RcmClient_INVALIDMSGID; Log_error0(FXNN": unable to the send message to the server"); status = RcmClient_E_EXECFAILED; goto leave; } leave: Log_print2(Diags_EXIT, "<-- %s: %d", (IArg)FXNN, (IArg)status); return(status); }
/* * ======== App_exec ======== */ Int App_exec(Void) { Int status; Int i; App_Msg * msg; printf("--> App_exec:\n"); /* fill process pipeline */ for (i = 1; i <= 3; i++) { printf("App_exec: sending message %d\n", i); /* allocate message */ msg = (App_Msg *)MessageQ_alloc(Module.heapId, Module.msgSize); if (msg == NULL) { status = -1; goto leave; } /* set the return address in the message header */ MessageQ_setReplyQueue(Module.hostQue, (MessageQ_Msg)msg); /* fill in message payload */ msg->cmd = App_CMD_NOP; /* send message */ MessageQ_put(Module.videoQue, (MessageQ_Msg)msg); } /* process steady state (keep pipeline full) */ for (i = 4; i <= 15; i++) { /* wait for return message */ status = MessageQ_get(Module.hostQue, (MessageQ_Msg *)&msg, MessageQ_FOREVER); if (status < 0) { goto leave; } /* extract message payload */ /* free the message */ MessageQ_free((MessageQ_Msg)msg); printf("App_exec: message received, sending message %d\n", i); /* allocate message */ msg = (App_Msg *)MessageQ_alloc(Module.heapId, Module.msgSize); if (msg == NULL) { status = -1; goto leave; } /* set the return address in the message header */ MessageQ_setReplyQueue(Module.hostQue, (MessageQ_Msg)msg); /* fill in message payload */ msg->cmd = App_CMD_NOP; /* send message */ MessageQ_put(Module.videoQue, (MessageQ_Msg)msg); } /* drain process pipeline */ for (i = 1; i <= 3; i++) { printf("App_exec: message received\n"); /* wait for return message */ status = MessageQ_get(Module.hostQue, (MessageQ_Msg *)&msg, MessageQ_FOREVER); if (status < 0) { goto leave; } /* extract message payload */ /* free the message */ MessageQ_free((MessageQ_Msg)msg); } leave: printf("<-- App_exec: %d\n", status); return(status); }
/* * ======== tsk1_func ======== * A local message queue is created and two remote message queues are opened. * Messages are sent to the remote message queues and retrieved from the * local message queue. */ Void tsk1_func(UArg arg0, UArg arg1) { MessageQ_Msg msg; MessageQ_Handle messageQ; MessageQ_QueueId core1QueueId, dspQueueId; Int status; UInt16 msgId = 0; /* Create a message queue */ messageQ = MessageQ_create(CORE0_MESSAGEQNAME, NULL); if (messageQ == NULL) { System_abort("MessageQ_create failed\n" ); } /* Open the DSP message queue. Spin until it is ready. */ do { status = MessageQ_open(DSP_MESSAGEQNAME, &dspQueueId); /* * Sleep for 1 clock tick to avoid inundating remote processor * with interrupts if open failed */ if (status < 0) { Task_sleep(1); } } while (status < 0); /* Open the CORE1 message queue. Spin until it is ready. */ do { status = MessageQ_open(CORE1_MESSAGEQNAME, &core1QueueId); /* * Sleep for 1 clock tick to avoid inundating remote processor * with interrupts if open failed */ if (status < 0) { Task_sleep(1); } } while (status < 0); /* Allocate a message to be ping-ponged around the processors */ msg = MessageQ_alloc(HEAPID, HEAP_MSGSIZE); if (msg == NULL) { System_abort("MessageQ_alloc failed\n" ); } /* Send the message to the DSP and wait for a response */ System_printf("Start the main loop\n"); while (msgId < NUMLOOPS) { /* Increment...the remote side will check this */ msgId++; MessageQ_setMsgId(msg, msgId); System_printf("Sending a message #%d to CORE1\n", msgId); /* send the message to the remote processor */ status = MessageQ_put(core1QueueId, msg); if (status < 0) { System_abort("MessageQ_put had an error\n"); } /* Get a message */ status = MessageQ_get(messageQ, &msg, MessageQ_FOREVER); if (status < 0) { System_abort("This should not happen since timeout is forever\n"); } System_printf("Sending a message #%d to DSP\n", msgId); status = MessageQ_put(dspQueueId, msg); if (status < 0) { System_abort("MessageQ_put had an error\n"); } /* Get another message */ status = MessageQ_get(messageQ, &msg, MessageQ_FOREVER); if (status < 0) { System_abort("This should not happen since timeout is forever\n"); } } System_printf("The test is complete\n"); BIOS_exit(0); }
/* * ======== tsk0_func ======== * Allocates a message and ping-pongs the message around the processors. * A local message queue is created and a remote message queue is opened. * Messages are sent to the remote message queue and retrieved from the * local MessageQ. */ Void tsk0_func(UArg arg0, UArg arg1) { MessageQ_Msg msg; MessageQ_Handle messageQ; MessageQ_QueueId remoteQueueId; Int status; UInt16 msgId = 0; Ptr buf; HeapBuf_Handle heapHandle; HeapBuf_Params hbparams; SizeT blockSize; UInt numBlocks; /* Compute the blockSize & numBlocks for the HeapBuf */ numBlocks = 2; blockSize = sizeof(MessageQ_MsgHeader); /* Alloc a buffer from the default heap */ buf = Memory_alloc(0, numBlocks * blockSize, 0, NULL); /* * Create the heap that is used for allocating MessageQ messages. */ HeapBuf_Params_init(&hbparams); hbparams.align = 0; hbparams.numBlocks = numBlocks; hbparams.blockSize = blockSize; hbparams.bufSize = numBlocks * blockSize; hbparams.buf = buf; heapHandle = HeapBuf_create(&hbparams, NULL); if (heapHandle == NULL) { System_abort("HeapBuf_create failed\n" ); } /* Register default system heap with MessageQ */ MessageQ_registerHeap((IHeap_Handle)(heapHandle), HEAPID); /* Create the local message queue */ messageQ = MessageQ_create(localQueueName, NULL); if (messageQ == NULL) { System_abort("MessageQ_create failed\n" ); } /* Open the remote message queue. Spin until it is ready. */ do { status = MessageQ_open(remoteQueueName, &remoteQueueId); /* * Sleep for 1 clock tick to avoid inundating remote processor * with interrupts if open failed */ if (status < 0) { Task_sleep(1); } } while (status < 0); if (MultiProc_self() == 0) { /* Allocate a message to be ping-ponged around the processors */ msg = MessageQ_alloc(HEAPID, sizeof(MessageQ_MsgHeader)); if (msg == NULL) { System_abort("MessageQ_alloc failed\n" ); } /* * Send the message to the remote processor and wait for a message * from the previous processor. */ System_printf("Start the main loop\n"); while (msgId < NUMLOOPS) { /* Increment...the remote side will check this */ msgId++; MessageQ_setMsgId(msg, msgId); System_printf("Sending a message #%d to %s\n", msgId, remoteQueueName); /* send the message to the remote processor */ status = MessageQ_put(remoteQueueId, msg); if (status < 0) { System_abort("MessageQ_put had a failure/error\n"); } /* Get a message */ status = MessageQ_get(messageQ, &msg, MessageQ_FOREVER); if (status < 0) { System_abort("This should not happen since timeout is forever\n"); } } } else { /* * Wait for a message from the previous processor and * send it to the remote processor */ System_printf("Start the main loop\n"); while (TRUE) { /* Get a message */ status = MessageQ_get(messageQ, &msg, MessageQ_FOREVER); if (status < 0) { System_abort("This should not happen since timeout is forever\n"); } System_printf("Sending a message #%d to %s\n", MessageQ_getMsgId(msg), remoteQueueName); /* Get the message id */ msgId = MessageQ_getMsgId(msg); /* send the message to the remote processor */ status = MessageQ_put(remoteQueueId, msg); if (status < 0) { System_abort("MessageQ_put had a failure/error\n"); } /* test done */ if (msgId >= NUMLOOPS) { break; } } } System_printf("The test is complete\n"); BIOS_exit(0); }
Int MessageQApp_execute(UInt32 numLoops, UInt32 payloadSize, UInt16 procId) { Int32 status = 0; MessageQ_Msg msg = NULL; MessageQ_Params msgParams; UInt32 i; MessageQ_QueueId queueId = MessageQ_INVALIDMESSAGEQ; MessageQ_Handle msgqHandle; char remoteQueueName[64]; struct timespec start, end; long elapsed; UInt32 msgId; printf("Entered MessageQApp_execute\n"); /* Create the local Message Queue for receiving. */ MessageQ_Params_init(&msgParams); msgqHandle = MessageQ_create(MPU_MESSAGEQNAME, &msgParams); if (msgqHandle == NULL) { printf("Error in MessageQ_create\n"); goto exit; } else { printf("Local MessageQId: 0x%x\n", MessageQ_getQueueId(msgqHandle)); } sprintf(remoteQueueName, "%s_%s", SLAVE_MESSAGEQNAME, MultiProc_getName(procId)); /* Poll until remote side has its messageQ created before we send: */ do { status = MessageQ_open(remoteQueueName, &queueId); sleep (1); } while (status == MessageQ_E_NOTFOUND); if (status < 0) { printf("Error in MessageQ_open [%d]\n", status); goto cleanup; } else { printf("Remote queueId [0x%x]\n", queueId); } msg = MessageQ_alloc(HEAPID, sizeof(SyncMsg) + payloadSize); if (msg == NULL) { printf("Error in MessageQ_alloc\n"); MessageQ_close(&queueId); goto cleanup; } /* handshake with remote to set the number of loops */ MessageQ_setReplyQueue(msgqHandle, msg); ((SyncMsg *)msg)->numLoops = numLoops; ((SyncMsg *)msg)->print = FALSE; MessageQ_put(queueId, msg); MessageQ_get(msgqHandle, &msg, MessageQ_FOREVER); printf("Exchanging %d messages with remote processor %s...\n", numLoops, MultiProc_getName(procId)); clock_gettime(CLOCK_REALTIME, &start); for (i = 1 ; i <= numLoops; i++) { ((SyncMsg *)msg)->numLoops = i; /* Have the remote proc reply to this message queue */ MessageQ_setReplyQueue(msgqHandle, msg); status = MessageQ_put(queueId, msg); if (status < 0) { printf("Error in MessageQ_put [%d]\n", status); break; } status = MessageQ_get(msgqHandle, &msg, MessageQ_FOREVER); if (status < 0) { printf("Error in MessageQ_get [%d]\n", status); break; } else { /* Validate the returned message */ msgId = ((SyncMsg *)msg)->numLoops; if ((msg != NULL) && (msgId != i)) { printf("Data integrity failure!\n" " Expected %d\n" " Received %d\n", i, msgId); break; } } } clock_gettime(CLOCK_REALTIME, &end); elapsed = diff(start, end); if (numLoops > 0) { printf("%s: Avg round trip time: %ld usecs\n", MultiProc_getName(procId), elapsed / numLoops); } MessageQ_free(msg); MessageQ_close(&queueId); cleanup: status = MessageQ_delete(&msgqHandle); if (status < 0) { printf ("Error in MessageQ_delete [%d]\n", status); } exit: printf("Leaving MessageQApp_execute\n\n"); return (status); }
Void *System_ipcMsgQTaskMain(Void *arg) { UInt32 prmSize; SystemIpcMsgQ_Msg *pMsgCommon; Void *pPrm; Int32 status; while(1) { status = MessageQ_get(gSystem_ipcObj.selfMsgQ, (MessageQ_Msg*)&pMsgCommon, OSA_TIMEOUT_FOREVER); if(status==MessageQ_E_UNBLOCKED) break; if(status!=MessageQ_S_SUCCESS) { printf(" %u: MSGQ: MsgQ get failed !!!\n", OSA_getCurTimeInMsec() ); continue; } #if 0 printf(" %u: MSGQ: Received command [0x%04x] (prmSize = %d) for [%s][%02d] (waitAck=%d)\n", OSA_getCurTimeInMsec(), pMsgCommon->cmd, pMsgCommon->prmSize, MultiProc_getName(SYSTEM_GET_PROC_ID(pMsgCommon->linkId)), SYSTEM_GET_LINK_ID(pMsgCommon->linkId), pMsgCommon->waitAck ); #endif prmSize = pMsgCommon->prmSize; pPrm = SYSTEM_IPC_MSGQ_MSG_PAYLOAD_PTR(pMsgCommon); if(pMsgCommon->cmd==SYSTEM_CMD_GET_INFO) { UTILS_assert(prmSize == sizeof(System_LinkInfo)); pMsgCommon->status = System_linkGetInfo_local(pMsgCommon->linkId, pPrm); } else { pMsgCommon->status = System_linkControl_local( pMsgCommon->linkId, pMsgCommon->cmd, pPrm, prmSize, pMsgCommon->waitAck ); } if(pMsgCommon->waitAck) { MessageQ_QueueId replyMsgQ; replyMsgQ = MessageQ_getReplyQueue(pMsgCommon); status = MessageQ_put(replyMsgQ, (MessageQ_Msg)pMsgCommon); if(status!=MessageQ_S_SUCCESS) { printf(" %u: MSGQ: MsgQ Ack put failed !!!\n", OSA_getCurTimeInMsec() ); MessageQ_free((MessageQ_Msg)pMsgCommon); } } else { MessageQ_free((MessageQ_Msg)pMsgCommon); } } return NULL; }
Int RcmClient_getSymbolIndex(RcmClient_Object *obj, String name, UInt32 *index) { SizeT len; RcmClient_Packet *packet; UInt16 msgId; MessageQ_Msg msgqMsg; Int rval; UInt16 serverStatus; RcmClient_Message *rcmMsg = NULL; Int status = RcmClient_S_SUCCESS; Log_print3(Diags_ENTRY, "--> "FXNN": (obj=0x%x, name=0x%x, index=0x%x", (IArg)obj, (IArg)name, (IArg)index); /* allocate a message */ len = _strlen(name) + 1; rval = RcmClient_alloc(obj, len, &rcmMsg); if (rval < 0) { status = rval; goto leave; } /* copy the function name into the message payload */ rcmMsg->dataSize = len; //TODO this is not proper! _strcpy((Char *)rcmMsg->data, name); /* classify this message */ packet = RcmClient_getPacketAddr_P(rcmMsg); packet->desc |= RcmClient_Desc_SYM_IDX << RcmClient_Desc_TYPE_SHIFT; msgId = packet->msgId; /* set the return address to this instance's message queue */ msgqMsg = (MessageQ_Msg)packet; MessageQ_setReplyQueue(obj->msgQue, msgqMsg); /* send the message to the server */ rval = MessageQ_put((MessageQ_QueueId)obj->serverMsgQ, msgqMsg); if (rval < 0) { Log_error0(FXNN": unable to the send message to the server"); status = RcmClient_E_EXECFAILED; goto leave; } /* get the return message from the server */ rval = RcmClient_getReturnMsg_P(obj, msgId, &rcmMsg); if (rval < 0) { status = rval; goto leave; } /* check message status for error */ packet = RcmClient_getPacketAddr_P(rcmMsg); serverStatus = (RcmClient_Desc_TYPE_MASK & packet->desc) >> RcmClient_Desc_TYPE_SHIFT; switch (serverStatus) { case RcmServer_Status_SUCCESS: break; case RcmServer_Status_SYMBOL_NOT_FOUND: Log_error1(FXNN": symbol not found, name=0x%x", (IArg)name); status = RcmClient_E_SYMBOLNOTFOUND; goto leave; default: Log_error1(FXNN": server returned error %d", (IArg)serverStatus); status = RcmClient_E_SERVERERROR; goto leave; } /* extract return value */ *index = rcmMsg->data[0]; leave: if (rcmMsg != NULL) { RcmClient_free(obj, rcmMsg); } Log_print1(Diags_EXIT, "<-- "FXNN": %d", (IArg)status); return(status); }
/****************************************************************************** * TASK FUNCTION *****************************************************************************/ void task_fxn(UArg arg0, UArg arg1){ Int status; Int coreCount; Int nextCore; MessageQ_Msg msg; MessageQ_QueueId msgQueueIds[MAX_NUM_CORES]; /* Register this heap with the Message Q */ MessageQ_registerHeap((IHeap_Handle)SharedRegion_getHeap(0), HEAP_ID); /* * In order to send messages to other cores, we must know that core's Queue * ID. So, we'll create an array on each core that associates the Queue ID * with the core number, and then we'll open each queue. Again, we spin * here until the queue is open, sleeping for one tick after every attempt. */ for (coreCount = 0; coreCount < MAX_NUM_CORES; coreCount++){ System_sprintf(remoteQueueName, "%s", MultiProc_getName(coreCount)); do { status = MessageQ_open(remoteQueueName, &msgQueueIds[coreCount]); if (status < 0){ Task_sleep(1); } }while (status < 0); } /* * At this point, our application is ready to begin sending messages using * Message Queue. The core with the number TOKEN_START_CORE has the * responsibility of sending the first message. So, we'll handle that in * this block. */ if (selfId == TOKEN_START_CORE){ /* * Allocate the initial message. If the message is not properly * allocated, we must abort */ /* * TODO: IPC #1 - Allocate Memory for Token Message * Add core below that ALLOCATES the memory for the token message. * We've already declared the variable msg to hold the pointer to * this message. The code to check if the pointer is NULL is * already included. */ msg = MessageQ_alloc(HEAP_ID, sizeof(myMsg)); if (msg == NULL){ System_abort("MessageQ_alloc failed\n"); } /* * Now randomly select the next processor to send the. This function * simply selects a random core number and ensures it's not the same as * the current core number. */ nextCore = findNextCore(selfId); /* * Set the Initial Token Count in the message, and specify that the * message type is MSG_TOKEN */ ((myMsg*)msg)->tokenCount = 1; ((myMsg*)msg)->messageType = MSG_TOKEN; /* * We can also set a reply queue so that the core can acknowledge this * message without having to know which core it came from. */ MessageQ_setReplyQueue(messageQ, msg); /* * Now we actually send the message to the next core that we've chosen. */ /* TODO: IPC #2 - Pass the token to the destination core * Add the code to send the message to the destination core. This is * done by putting the message in the destination core's queue. Don't * forget that the ID of the destination core's queue is stored at * element "nextCore" in the array msgQueueIds, and is NOT the same * as the core number. */ status = MessageQ_put(msgQueueIds[nextCore], msg); } while (TRUE){ msgType messageType; MessageQ_Msg ack; MessageQ_QueueId ackQueueId; Int currentTokenCount; /* TODO: IPC #3 - Get a Message from the local queue. * Take the message from the local queue and store it in the variable * message. The function call return value should be stored in the * variable status. Hint: The parameters passed to this function * specify a time out size. We want to configure this call to * never time out, and block eternally until a message is received. */ status = MessageQ_get(messageQ, &msg, MessageQ_FOREVER); if (status < 0){ System_abort("This should not occur since the timeout is forever\n"); } /* * Read the Message Type from the received message, along with the current * token count. */ messageType = ((myMsg*)msg)->messageType; currentTokenCount = ((myMsg*)msg)->tokenCount; /* * Now, check what type of message it is and take action. Here are the * actions to be taken. * * MSG_TOKEN * - Acknowledge that token is received to sending core. * - If token count is less than MAX_MESSAGES * - Increment the token count. * - Forward the token on to the next random core * - If token count is equal to MAX Messages * - Free the Token message. * - Send a Done Message to all other cores. * - Break out of the infinite loop. * * MSG_ACK * - Free the Ack message * MSG_DONE * - Free the Done Message * - Break Out of infinite loop */ switch (messageType){ case MSG_TOKEN: System_printf("Token Received - Count = %d\n", currentTokenCount); /* * TODO: IPC #4 - Get the Reply Queue for the token * Store the ID of the reply queue in the variable ackQueueId. * This function allows us to not have to figure out which core * sent this message. This is the analogous function to the * MessageQ_setReplyQueue() function that was set before the * message was sent. This data is stored in the MessageQ_MsgHeader * element that's included with the message */ ackQueueId = MessageQ_getReplyQueue(msg); /* * TODO: IPC #5 - Allocate the acknowledge message * Allocate the acknowledge message and store the pointer to it * in the variable ack. */ ack = MessageQ_alloc(HEAP_ID, sizeof(myMsg)); // Set the Message Type of the new Message to MSG_ACK if (ack==NULL){ System_abort("MessageQ Alloc Failed\n"); } // Set the Message Type of the new Message to MSG_ACK ((myMsg*)ack)->messageType = MSG_ACK; /* * TODO: IPC #6 - Send the Acknowledge message * Don't forget that we've already stored the reply queue ID in * ackQueueId above. */ status = MessageQ_put(ackQueueId, ack); /* * Now handle the actions required by the status of the message. First * we must check to see if we're at the Token Passing limit. So we'll * compare the current Token count with MAX_MESSAGES. */ /* * If the current token count is the max, then we must free the current * message and then allocate new DONE messages to be sent to the other * cores. */ if (currentTokenCount == NUM_MESSAGES){ /* * TODO: IPC #7 - Free the memory used by the token message * Don't forget that the pointer to this memory is in the * variable msg. */ MessageQ_free(msg); /* * Now allocate and send ALL cores a DONE message. We don't need to * worry about special handling of the current core. It will just * send itself a DONE message and handle it just as the other cores * do */ /* * TODO: IPC #8 - Note that this core will send itself a message. * There's nothing to be added here. just note that this * routine is blindly sending done messages to all of the cores * and not taking into account it's own core number. So, this * core will send one of these messages to itself. */ for (coreCount =0; coreCount < MAX_NUM_CORES; coreCount++){ msg = MessageQ_alloc(HEAP_ID, sizeof(myMsg)); if (msg == NULL){ System_abort("MessageQ Alloc Failed\n"); } // Set the Message Type to MSG_DONE ((myMsg*)msg)->messageType = MSG_DONE; // Now send it to the selected core status = MessageQ_put(msgQueueIds[coreCount], msg); } break; } /* * If we're not at the last message, then we must increment the * tokenCount and pass the message on to a random core. Don't * forget to set the reply queue so we can get an acknowledge. */ nextCore = findNextCore(selfId); ((myMsg*)msg)->tokenCount = currentTokenCount + 1; /* * TODO: IPC #9- Set the reply queue for the token message. * We need to be sure to set the reply queue each time. * Otherwise, the wrong core will receive the acknowledge. */ MessageQ_setReplyQueue(messageQ, msg); // Put the message on the proper queue status = MessageQ_put(msgQueueIds[nextCore], msg); break; case MSG_ACK: System_printf("Ack Received\n"); /* * All we need to do in this case is free the Ack message */ MessageQ_free(msg); break; case MSG_DONE: System_printf("Done Received\n"); /* * If we receive the Done message we just need to free the message, and * then exit SYS/BIOS because the application is complete. */ MessageQ_free(msg); BIOS_exit(0); break; default: System_printf("Invalid Message Type Received\n"); return; } } }
Int MessageQApp_execute(UInt32 numLoops, UInt16 procId) { Int32 status = 0; MessageQ_Msg msg = NULL; MessageQ_Params msgParams; UInt32 i; MessageQ_QueueId queueId = MessageQ_INVALIDMESSAGEQ; MessageQ_Handle msgqHandle; char remoteQueueName[64]; UInt32 msgId; printf("Entered MessageQApp_execute\n"); /* Create the local Message Queue for receiving. */ MessageQ_Params_init(&msgParams); msgqHandle = MessageQ_create(MPU_MESSAGEQNAME, &msgParams); if (msgqHandle == NULL) { printf("Error in MessageQ_create\n"); goto exit; } else { printf("Local MessageQId: 0x%x\n", MessageQ_getQueueId(msgqHandle)); } sprintf(remoteQueueName, "%s_%s", SLAVE_MESSAGEQNAME, MultiProc_getName(procId)); /* Poll until remote side has it's messageQ created before we send: */ do { status = MessageQ_open(remoteQueueName, &queueId); sleep (1); } while (status == MessageQ_E_NOTFOUND); if (status < 0) { printf("Error in MessageQ_open [%d]\n", status); goto cleanup; } else { printf("Remote queueId [0x%x]\n", queueId); } msg = MessageQ_alloc(HEAPID, sizeof(SyncMsg)); if (msg == NULL) { printf("Error in MessageQ_alloc\n"); MessageQ_close(&queueId); goto cleanup; } /* handshake with remote to set the number of loops */ MessageQ_setReplyQueue(msgqHandle, msg); ((SyncMsg *)msg)->numLoops = numLoops; ((SyncMsg *)msg)->print = FALSE; MessageQ_put(queueId, msg); MessageQ_get(msgqHandle, &msg, MessageQ_FOREVER); printf("Exchanging %d messages with remote processor %s...\n", numLoops, MultiProc_getName(procId)); for (i = 1 ; i <= numLoops; i++) { ((SyncMsg *)msg)->numLoops = i; /* Have the remote proc reply to this message queue */ MessageQ_setReplyQueue(msgqHandle, msg); status = MessageQ_put(queueId, msg); if (status < 0) { printf("Error in MessageQ_put [%d]\n", status); MessageQ_free(msg); break; } status = MessageQ_get(msgqHandle, &msg, MessageQ_FOREVER); if (status < 0) { printf("Error in MessageQ_get [%d]\n", status); break; } else { /* validate the returned message */ msgId = ((SyncMsg *)msg)->numLoops; if ((msg != NULL) && (msgId != i)) { printf("Data integrity failure!\n" " Expected %d\n" " Received %d\n", i, msgId); break; } } if (numLoops <= 200) { printf("MessageQ_get #%d Msg = 0x%x\n", i, (UInt)msg); } else if ((i % 1000) == 0) { printf("MessageQ_get #%d Msg = 0x%x\n", i, (UInt)msg); } } printf("Exchanged %d messages with remote processor %s\n", (i-1), MultiProc_getName(procId)); if (status >= 0) { printf("Sample application successfully completed!\n"); MessageQ_free(msg); } MessageQ_close(&queueId); cleanup: /* Clean-up */ status = MessageQ_delete(&msgqHandle); if (status < 0) { printf("Error in MessageQ_delete [%d]\n", status); } exit: printf("Leaving MessageQApp_execute\n\n"); return (status); }
/* * ======== NameServerMessageQ_get ======== */ Int NameServerMessageQ_get(NameServerMessageQ_Object *obj, String instanceName, String name, Ptr value, UInt32 *valueLen, ISync_Handle syncHandle, Error_Block *eb) { Int len; Int status; IArg key; MessageQ_QueueId queueId; NameServerMsg *msg; Semaphore_Handle semRemoteWait = NameServerMessageQ_module->semRemoteWait; GateMutex_Handle gateMutex = NameServerMessageQ_module->gateMutex; /* enter gate - prevent multiple threads from entering */ key = GateMutex_enter(gateMutex); /* alloc a message from specified heap */ msg = (NameServerMsg *)MessageQ_alloc(NameServerMessageQ_heapId, sizeof(NameServerMsg)); /* make sure message is not NULL */ if (msg == NULL) { Error_raise(eb, NameServerMessageQ_E_outOfMemory, NameServerMessageQ_heapId, 0); return (NameServer_E_OSFAILURE); } /* make sure this is a request message */ msg->request = NameServerMessageQ_REQUEST; msg->requestStatus = 0; /* get the length of instanceName */ len = strlen(instanceName); /* assert length is smaller than max (must have room for null character) */ Assert_isTrue(len < MAXNAMEINCHAR, NameServerMessageQ_A_nameIsTooLong); /* copy the name of instance into putMsg */ strncpy((Char *)msg->instanceName, instanceName, len); /* get the length of name */ len = strlen(name); /* assert length is smaller than max (must have room for null character) */ Assert_isTrue(len < MAXNAMEINCHAR, NameServerMessageQ_A_nameIsTooLong); /* copy the name of nameserver entry into putMsg */ strncpy((Char *)msg->name, name, len); /* determine the queueId based upon the processor */ queueId = MessageQ_openQueueId(MESSAGEQ_INDEX, obj->remoteProcId); /* set the reply procId */ MessageQ_setReplyQueue( (MessageQ_Handle)NameServerMessageQ_module->msgHandle, (MessageQ_Msg)msg); /* send message to remote processor. */ status = MessageQ_put(queueId, (MessageQ_Msg)msg); /* make sure message sent successfully */ if (status < 0) { /* free the message */ MessageQ_free((MessageQ_Msg)msg); return (NameServer_E_FAIL); } /* pend here until we get a response back from remote processor */ status = Semaphore_pend(semRemoteWait, NameServerMessageQ_timeout); if (status == FALSE) { /* return timeout failure */ return (NameServer_E_OSFAILURE); } /* get the message */ msg = NameServerMessageQ_module->msg; if (msg->requestStatus) { /* name is found */ /* set length to amount of data that was copied */ *valueLen = sizeof(Bits32); /* set the contents of value */ memcpy(value, &(msg->value), sizeof(Bits32)); /* set the status to success */ status = NameServer_S_SUCCESS; } else { /* name is not found */ /* set status to not found */ status = NameServer_E_NOTFOUND; } /* free the message */ MessageQ_free((MessageQ_Msg)msg); /* leave the gate */ GateMutex_leave(gateMutex, key); /* return success status */ return (status); }
Int RcmClient_exec(RcmClient_Object *obj, RcmClient_Message *cmdMsg, RcmClient_Message **returnMsg) { RcmClient_Packet *packet; RcmClient_Message *rtnMsg; MessageQ_Msg msgqMsg; UInt16 msgId; UInt16 serverStatus; Int rval; Int status = RcmClient_S_SUCCESS; Log_print2(Diags_ENTRY, "--> "FXNN": (cmdMsg=0x%x, rtnMsg=0x%x)", (IArg)obj, (IArg)returnMsg); /* classify this message */ packet = RcmClient_getPacketAddr_P(cmdMsg); packet->desc |= RcmClient_Desc_RCM_MSG << RcmClient_Desc_TYPE_SHIFT; msgId = packet->msgId; /* set the return address to this instance's message queue */ msgqMsg = (MessageQ_Msg)packet; MessageQ_setReplyQueue(obj->msgQue, msgqMsg); /* send the message to the server */ status = MessageQ_put((MessageQ_QueueId)obj->serverMsgQ, msgqMsg); if (status < 0) { Log_error0(FXNN": unable to the send message to the server"); status = RcmClient_E_EXECFAILED; goto leave; } /* get the return message from the server */ rval = RcmClient_getReturnMsg_P(obj, msgId, &rtnMsg); if (rval < 0) { *returnMsg = NULL; status = rval; goto leave; } *returnMsg = rtnMsg; /* check the server's status stored in the packet header */ packet = RcmClient_getPacketAddr_P(rtnMsg); serverStatus = (RcmClient_Desc_TYPE_MASK & packet->desc) >> RcmClient_Desc_TYPE_SHIFT; switch (serverStatus) { case RcmServer_Status_SUCCESS: break; case RcmServer_Status_INVALID_FXN: Log_error1(FXNN": invalid function index: 0x%x", (IArg)rtnMsg->fxnIdx); status = RcmClient_E_INVALIDFXNIDX; goto leave; case RcmServer_Status_MSG_FXN_ERR: Log_error1(FXNN": message function error %d", (IArg)rtnMsg->result); status = RcmClient_E_MSGFXNERROR; goto leave; default: Log_error1(FXNN": server returned error %d", (IArg)serverStatus); status = RcmClient_E_SERVERERROR; goto leave; } leave: Log_print1(Diags_EXIT, "<-- "FXNN": %d", (IArg)status); return(status); }
Int RcmClient_acquireJobId(RcmClient_Object *obj, UInt16 *jobIdPtr) { RcmClient_Message *msg; RcmClient_Packet *packet; MessageQ_Msg msgqMsg; UInt16 msgId; Int rval; UInt16 serverStatus; Int status = RcmClient_S_SUCCESS; Log_print2(Diags_ENTRY, "--> "FXNN": (obj=0x%x, jobIdPtr=0x%x)", (IArg)obj, (IArg)jobIdPtr); /* allocate a message */ status = RcmClient_alloc(obj, sizeof(UInt16), &msg); if (status < 0) { goto leave; } /* classify this message */ packet = RcmClient_getPacketAddr_P(msg); packet->desc |= RcmClient_Desc_JOB_ACQ << RcmClient_Desc_TYPE_SHIFT; msgId = packet->msgId; /* set the return address to this instance's message queue */ msgqMsg = (MessageQ_Msg)packet; MessageQ_setReplyQueue(obj->msgQue, msgqMsg); /* send the message to the server */ rval = MessageQ_put((MessageQ_QueueId)obj->serverMsgQ, msgqMsg); if (rval < 0) { Log_error0(FXNN": unable to the send message to the server"); status = RcmClient_E_FAIL; goto leave; } /* get the return message from the server */ status = RcmClient_getReturnMsg_P(obj, msgId, &msg); if (status < 0) { goto leave; } /* check message status for error */ packet = RcmClient_getPacketAddr_P(msg); serverStatus = (RcmClient_Desc_TYPE_MASK & packet->desc) >> RcmClient_Desc_TYPE_SHIFT; switch (serverStatus) { case RcmServer_Status_SUCCESS: break; default: Log_error1(FXNN": server returned error %d", (IArg)serverStatus); status = RcmClient_E_SERVERERROR; goto leave; } /* extract return value */ *jobIdPtr = (UInt16)(msg->data[0]); leave: if (msg != NULL) { RcmClient_free(obj, msg); } Log_print1(Diags_EXIT, "<-- "FXNN": %d", (IArg)status); return(status); }
static Void * pingThreadFxn(void *arg) { Int threadNum = *(int *)arg; Int32 status = 0; MessageQ_Msg msg = NULL; MessageQ_Params msgParams; UInt16 i; MessageQ_Handle handle; MessageQ_QueueId queueId = MessageQ_INVALIDMESSAGEQ; char remoteQueueName[64]; char hostQueueName[64]; printf ("Entered pingThreadFxn: %d\n", threadNum); sprintf(remoteQueueName, "%s_%d%d", SLAVE_MESSAGEQNAME, threadNum, (threadNum % (MultiProc_getNumProcessors() - 1)) + 1); sprintf(hostQueueName, "%s_%d", HOST_MESSAGEQNAME, threadNum ); /* Create the local Message Queue for receiving. */ MessageQ_Params_init (&msgParams); handle = MessageQ_create (hostQueueName, &msgParams); if (handle == NULL) { printf ("Error in MessageQ_create\n"); goto exit; } else { printf ("thread: %d, Local Message: %s, QId: 0x%x\n", threadNum, hostQueueName, MessageQ_getQueueId(handle)); } /* Poll until remote side has it's messageQ created before we send: */ do { status = MessageQ_open (remoteQueueName, &queueId); sleep (1); } while (status == MessageQ_E_NOTFOUND); if (status < 0) { printf ("Error in MessageQ_open [0x%x]\n", status); goto cleanup; } else { printf ("thread: %d, Remote queue: %s, QId: 0x%x\n", threadNum, remoteQueueName, queueId); } printf ("\nthread: %d: Exchanging messages with remote processor...\n", threadNum); for (i = 0 ; i < numLoops ; i++) { /* Allocate message. */ msg = MessageQ_alloc (HEAPID, MSGSIZE); if (msg == NULL) { printf ("Error in MessageQ_alloc\n"); break; } MessageQ_setMsgId (msg, i); /* Have the remote proc reply to this message queue */ MessageQ_setReplyQueue (handle, msg); status = MessageQ_put (queueId, msg); if (status < 0) { printf ("Error in MessageQ_put [0x%x]\n", status); break; } status = MessageQ_get(handle, &msg, MessageQ_FOREVER); if (status < 0) { printf ("Error in MessageQ_get [0x%x]\n", status); break; } else { /* Validate the returned message. */ if ((msg != NULL) && (MessageQ_getMsgId (msg) != i)) { printf ("Data integrity failure!\n" " Expected %d\n" " Received %d\n", i, MessageQ_getMsgId (msg)); break; } status = MessageQ_free (msg); } printf ("thread: %d: Exchanged %d msgs\n", threadNum, (i+1)); } printf ("thread: %d: pingThreadFxn successfully completed!\n", threadNum); MessageQ_close (&queueId); cleanup: /* Clean-up */ status = MessageQ_delete (&handle); if (status < 0) { printf ("Error in MessageQ_delete [0x%x]\n", status); } exit: return ((void *)status); }
/* * ======== clientTask ======== */ Void clientTask(UArg arg0, UArg arg1) { MessageQ_Handle messageQ; MessageQ_QueueId serverQueue; MessageQ_Msg msg; UInt16 msgId = arg0; Int status; Int i; /* * Create client's MessageQ. * * Use 'NULL' for name since no since this queueId is passed by * referene and no one opens it by name. * Use 'NULL' for params to get default parameters. */ messageQ = MessageQ_create(NULL, NULL); if (messageQ == NULL) { System_abort("Failed to create MessageQ\n"); } /* Open the server's MessageQ */ do { status = MessageQ_open(SERVERNAME, &serverQueue); if (status < 0) { Task_sleep(1); /* give server a chance to create queue */ } } while (status < 0); msg = MessageQ_alloc(HEAPID, sizeof(MessageQ_MsgHeader)); if (msg == NULL) { System_abort("MessageQ_alloc failed\n" ); } /* Have the remote processor reply to this message queue */ MessageQ_setReplyQueue(messageQ, msg); /* Loop requesting information from the server task */ System_printf("Client #%d is starting to send requests\n", arg0); for (i = 0; i < NUMMSGS; i++) { /* Server will increment and send back */ MessageQ_setMsgId(msg, msgId); msgId += NUMCLIENTS; /* Send the message off */ status = MessageQ_put(serverQueue, msg); if (status < 0) { MessageQ_free(msg); System_abort("MessageQ_put failed\n"); } /* Wait for the reply... */ status = MessageQ_get(messageQ, &msg, MessageQ_FOREVER); if (status < 0) { System_abort("MessageQ_get had an error\n"); } /* Validate the returned message. */ if (MessageQ_getMsgId(msg) != msgId) { System_abort("Unexpected value\n"); } System_printf("Client #%d received response #%d\n", arg0, i + 1); /* To make some variation in the execution order */ Task_sleep(500 * (arg0 + 1)); } System_printf("Client #%d is done sending requests\n", arg0); numCompleted++; if (numCompleted == 3) { /* All client tasks are done sending requests */ BIOS_exit(0); } }
Int32 System_ipcMsgQSendMsg(UInt32 linkId, UInt32 cmd, Void *pPrm, UInt32 prmSize, Bool waitAck, UInt32 timeout) { Int32 status=OSA_SOK; SystemIpcMsgQ_Msg *pMsgCommon; UInt32 procId; Void *pMsgPrm; UTILS_assert(prmSize<=SYSTEM_IPC_MSGQ_MSG_SIZE_MAX); procId = SYSTEM_GET_PROC_ID(linkId); #ifdef TI_8107_BUILD if(procId==SYSTEM_PROC_DSP) { printf(" %u: MSGQ: WARNING: Trying to send command [0x%04x] to link [%d] on processor [%s], BUT [%s] is NOT present on this platform !!!\n", OSA_getCurTimeInMsec(), cmd, SYSTEM_GET_LINK_ID(linkId), MultiProc_getName(procId), MultiProc_getName(procId) ); /* return SUCCESS so that calling API can continue */ return status; } #endif UTILS_assert( procId < SYSTEM_PROC_MAX); /*wuzc modify for malloc fail*/ OSA_mutexLock(&gSystem_ipcObj.msgQLock); pMsgCommon = (SystemIpcMsgQ_Msg *)MessageQ_alloc( SYSTEM_IPC_MSGQ_HEAP, sizeof(*pMsgCommon)+prmSize ); UTILS_assert(pMsgCommon!=NULL); if(prmSize && pPrm) { pMsgPrm = SYSTEM_IPC_MSGQ_MSG_PAYLOAD_PTR(pMsgCommon); memcpy(pMsgPrm, pPrm, prmSize); } pMsgCommon->linkId = linkId; pMsgCommon->cmd = cmd; pMsgCommon->prmSize = prmSize; pMsgCommon->waitAck = waitAck; pMsgCommon->status = OSA_SOK; MessageQ_setReplyQueue(gSystem_ipcObj.selfAckMsgQ, (MessageQ_Msg)pMsgCommon); MessageQ_setMsgId(pMsgCommon, linkId); //OSA_mutexLock(&gSystem_ipcObj.msgQLock); status = MessageQ_put(gSystem_ipcObj.remoteProcMsgQ[procId], (MessageQ_Msg)pMsgCommon); if(status!=MessageQ_S_SUCCESS) { printf(" %u: MSGQ: MsgQ put for [%s] failed !!!\n", OSA_getCurTimeInMsec(), MultiProc_getName(procId) ); MessageQ_free((MessageQ_Msg)pMsgCommon); OSA_mutexUnlock(&gSystem_ipcObj.msgQLock); return status; } if(waitAck) { SystemIpcMsgQ_Msg *pAckMsg; status = MessageQ_get(gSystem_ipcObj.selfAckMsgQ, (MessageQ_Msg*)&pAckMsg, timeout); if(status!=MessageQ_S_SUCCESS) { printf(" %u: MSGQ: MsgQ Ack get from [%s] failed !!!\n", OSA_getCurTimeInMsec(), MultiProc_getName(procId) ); MessageQ_free((MessageQ_Msg)pMsgCommon); OSA_mutexUnlock(&gSystem_ipcObj.msgQLock); return status; } if(prmSize && pPrm) { pMsgPrm = SYSTEM_IPC_MSGQ_MSG_PAYLOAD_PTR(pAckMsg); memcpy(pPrm, pMsgPrm, prmSize); } status = pAckMsg->status; MessageQ_free((MessageQ_Msg)pAckMsg); } OSA_mutexUnlock(&gSystem_ipcObj.msgQLock); return status; }
/* * ======== NameServerMessageQ_swiFxn ======== */ Void NameServerMessageQ_swiFxn(UArg arg0, UArg arg1) { NameServerMsg *msg; NameServer_Handle handle; MessageQ_QueueId queueId; Int status = NameServer_E_FAIL; Semaphore_Handle semRemoteWait = NameServerMessageQ_module->semRemoteWait; /* drain all messages in the messageQ */ while (1) { /* get a message, this never waits */ status = MessageQ_get( (MessageQ_Handle)NameServerMessageQ_module->msgHandle, (MessageQ_Msg *)&msg, 0); /* if no message then return */ if (status != MessageQ_S_SUCCESS) { break; } if (msg->request == NameServerMessageQ_REQUEST) { /* reset value of status */ status = NameServer_E_FAIL; /* * Message is a request. Lookup name in NameServer table. * Send a response message back to source processor. */ handle = NameServer_getHandle((String)msg->instanceName); if (handle != NULL) { /* Search for the NameServer entry */ status = NameServer_getLocalUInt32(handle, (String)msg->name, &msg->value); } /* set the request status */ if (status < 0) { msg->requestStatus = 0; } else { msg->requestStatus = 1; } /* specify message as a response */ msg->request = NameServerMessageQ_RESPONSE; /* get the remote processor from the msg header */ queueId = (UInt32)(msg->header.replyProc) << 16; /* send response message to remote processor */ MessageQ_put(queueId, (MessageQ_Msg)msg); } else { /* * This is a response message. At any given time, there is * only one of these outstanding because of semMultiBlock. * This allows us to safely set the Module state's msg pointer * and post semaphore. */ NameServerMessageQ_module->msg = msg; Semaphore_post(semRemoteWait); } } }
/** * Send all prepared IPC messages to all cores and return the calculation result (ssd/jac/hess) */ void send_to_cores(const processing_type_e ProcessingType, const uint32_T number_of_cores, real32_T *SSD, real32_T JD[3], real32_T JD2[9]) { process_message_t * p_msg = 0; uint16_t msgId = 0; int32_T ret_val=0; #ifdef _TRACE_MC_ Types_FreqHz freq; float processing_time=0; Int32 ts1, ts2; #endif int32_t j; int32_t i; #ifdef _TRACE_MC_ logout("[MAIN ] Execute Process (ProcessingType=%u)\n", ProcessingType); //trace Timestamp_getFreq(&freq); #endif #ifdef _DO_ERROR_CHECKS_ if(NULL == h_receive_queue) { logout("No master msg receive queue available.\n", max_core); } if ((number_of_cores <= 0) || (number_of_cores > max_core)) { logout("Invalid number_of_cores: It should be between 1 to %u\n", max_core); ret_val = -1; goto mcip_process_error; } #endif //CACHING NOTE: //The picture data was cache write backed after images have been received. More //data is not to be cache write backed as we pass all other data (also arrays //element by element) to the cores using the message queue. Results are passed //back also using the message interface as we don't receive bulk data results. #ifdef _TRACE_MC_ ts1 = (Int32) Timestamp_get32(); #endif /* Send messages to processing cores, start at the highest core */ for (i = CORE_AMOUNT-1; i >= (int)(CORE_AMOUNT-number_of_cores); i-- ) { p_msg = p_queue_msg[i]; MessageQ_setMsgId(p_msg, ++msgId); MessageQ_setReplyQueue(h_receive_queue, (MessageQ_Msg)p_msg); #ifdef _TRACE_MC_ logout("[MAIN ] Start process on core %u (ProcessingType=%u)\n", p_msg->core_id, ProcessingType, p_msg->info.NewImageDataArrived); //trace #endif /* send the message to the remote processor */ if (MessageQ_put(queue_id[p_msg->core_id], (MessageQ_Msg)p_msg) < 0) { logout("MessageQ_put had a failure error\n"); ret_val = -1; goto mcip_process_error; } } //All cores have invalidated their cache to read new image data. Next time cache invalidation is no more necessary (until new image data arrives). g_NewImageDataArrived = 0; #ifdef _TRACE_MC_ logout("[MAIN ] Reset g_NetImageDataArrived signal to %d.\n", g_NewImageDataArrived); #endif //Clear result buffers (will be summed up, have to start at 0) if(pt_ssd == ProcessingType || pt_ssdJacHess == ProcessingType) { (*SSD)=0; if(pt_ssdJacHess == ProcessingType) { memset(JD, 0, sizeof(real32_T) * 3); memset(JD2, 0, sizeof(real32_T) * 9); } } //ToDo: Once it looked like all other cores finished calculating before core 0 started. Why ? //One could think of having no mcip_core_task at the main core and call the calculation directly instead ... Use _TRACE_MC_ (only) to see this //ToDo: When adding a big sleep command to the processing functions one should see if there's something wrong /* Receive the result */ for (i = (CORE_AMOUNT-number_of_cores); i < CORE_AMOUNT; i++) { if (MessageQ_get(h_receive_queue, (MessageQ_Msg *)&p_msg, MessageQ_FOREVER) < 0) { logout("This should not happen since timeout is forever\n"); ret_val = -1; }/* else if (p_msg->info.flag != 0) { logout("Process image error received from core %d\n", p_msg->core_id); ret_val = -1; }*/ #ifdef _TRACE_MC_ if(pt_ssd == ProcessingType || pt_ssdJacHess == ProcessingType) { logout("[MAIN ] process answer received from core %u (SSD=%f, ProcessingType=%u)\n", p_msg->core_id, (double)p_msg->info.out_SSD, ProcessingType); //trace if(pt_ssdJacHess == ProcessingType) { logout("[MAIN ] JD = [%f %f %f], JD2 = [%f ... %f ... %f]\n", (double)p_msg->info.out_JD[0], (double)p_msg->info.out_JD[1], (double)p_msg->info.out_JD[2], (double)p_msg->info.out_JD2[0], (double)p_msg->info.out_JD2[4], (double)p_msg->info.out_JD2[8]); } } else { logout("[MAIN ] process answer received from core %u (ProcessingType=%u)\n", p_msg->core_id, ProcessingType); //trace } #endif //Sum up the results if(pt_ssd == ProcessingType || pt_ssdJacHess == ProcessingType) { (*SSD) += p_msg->info.out_SSD; if(pt_ssdJacHess == ProcessingType) { for(j=0; j<3; j++) { JD[j] += p_msg->info.out_JD[j]; } for(j=0; j<9; j++) { JD2[j] += p_msg->info.out_JD2[j]; } } } } if (ret_val == -1) { goto mcip_process_error; } #ifdef _TRACE_MC_ ts2 = (Int32) Timestamp_get32(); ts2 = ts2 - ts1; processing_time = ((float)ts2 / (float)freq.lo); if(pt_ssd == ProcessingType || pt_ssdJacHess == ProcessingType) { logout("[MAIN ] SSD calculated in: %f s. Result = %f\n", processing_time, (double)(*SSD)); //trace if(pt_ssdJacHess == ProcessingType) { logout("[MAIN ] JD = [%f %f %f], JD2 = [%f ... %f ... %f]\n", (double)JD[0], (double)JD[1], (double)JD[2], (double)JD2[0], (double)JD2[4], (double)JD2[8]); } } else { logout("[MAIN ] Image shrinked in: %f s.\n", processing_time); //trace } #endif return; mcip_process_error: logout("mcip_process_error !!! \n"); shutdown_message_q(); }
/* * ======== tsk1_func ======== * Send and receive messages */ Void tsk1_func(UArg arg0, UArg arg1) { MessageQ_Msg msg; MessageQ_Handle messageQ; MessageQ_QueueId remoteQueueId; HeapBufMP_Handle heapHandle; Int status; UInt16 msgId; /* * Open the heap that is created on the other processor. Loop until opened. * Not using the name since the interrupts are not enabled yet! */ do { status = HeapBufMP_open(HEAP_NAME, &heapHandle); /* * Sleep for 1 clock tick to avoid inundating remote processor * with interrupts if open failed */ if (status < 0) { Task_sleep(1); } } while (status < 0); /* Register this heap with MessageQ */ MessageQ_registerHeap((IHeap_Handle)heapHandle, HEAPID); /* Create a local message queue */ messageQ = MessageQ_create(DSP_MESSAGEQNAME, NULL); if (messageQ == NULL) { System_abort("MessageQ_create failed\n" ); } /* Open the core0 message queue. Spin until it is ready. */ do { status = MessageQ_open(CORE0_MESSAGEQNAME, &remoteQueueId); /* * Sleep for 1 clock tick to avoid inundating remote processor * with interrupts if open failed */ if (status < 0) { Task_sleep(1); } } while (status < 0); /* Wait for a message and send it to core0 */ System_printf("Start the main loop\n"); while (TRUE) { /* Get a message */ status = MessageQ_get(messageQ, &msg, MessageQ_FOREVER); if (status < 0) { System_abort("This should not happen since timeout is forever\n"); } System_printf("Sending a message #%d to CORE0\n", MessageQ_getMsgId(msg)); /* Get the message id */ msgId = MessageQ_getMsgId(msg); /* send the message to the remote processor */ status = MessageQ_put(remoteQueueId, msg); if (status < 0) { System_abort("MessageQ_put had a failure/error\n"); } /* test done */ if (msgId == NUMLOOPS) { System_printf("Test complete!\n"); BIOS_exit(0); } } }
/* * ======== Server_exec ======== */ Int Server_exec() { Int status; GateMPApp_Msg * msg; MessageQ_QueueId queId; UInt32 physAddr; volatile UInt32 * intPtr = 0; Int num = 0; Int prevNum = 0; UInt i = 0; IArg gateKey = 0; Log_print0(Diags_ENTRY | Diags_INFO, "--> Server_exec:"); /* wait for inbound message */ status = MessageQ_get(Module.slaveQue, (MessageQ_Msg *)&msg, MessageQ_FOREVER); if (status < 0) { goto leave; } if (msg->cmd != GATEMPAPP_CMD_SPTR_ADDR) { status = GATEMPAPP_E_UNEXPECTEDMSG; goto leave; } /* Get physical address of shared memory */ physAddr = msg->payload; /* translate the physical address to slave virtual addr */ if (Resource_physToVirt(physAddr, (UInt32 *)&intPtr)) { Log_error1("Server_exec: Failed to translate phys addr %p to virt addr", physAddr); goto leave; } /* send message back */ queId = MessageQ_getReplyQueue(msg); /* type-cast not needed */ msg->cmd = GATEMPAPP_CMD_SPTR_ADDR_ACK; MessageQ_put(queId, (MessageQ_Msg)msg); Log_print0(Diags_INFO,"Server_exec: Modifying shared variable " "value"); /* open host-created GateMP */ do { status = GateMP_open(GATEMP_HOST_NAME, &Module.hostGateMPHandle); } while (status == GateMP_E_NOTFOUND); if (status < 0) { Log_error0("Server_exec: Failed to open host-created GateMP"); status = GATEMPAPP_E_FAILURE; goto leave; } Log_print0(Diags_INFO,"Server_exec: Opened GateMP successfully"); Log_print0(Diags_INFO,"Server_exec: Using host-created gate"); for (i = 0;i < LOOP_ITR; i++) { /* modify the shared variable as long as no one else is currently * accessing it */ /* enter GateMP */ gateKey = GateMP_enter(Module.hostGateMPHandle); /* read shared variable value */ prevNum = *intPtr; /* randomly modify the shared variable */ if ( rand() % 2) { *intPtr -= 1; } else { *intPtr += 1; } /* read shared variable value again */ num = *intPtr; if ((prevNum != num + 1) && (prevNum != num - 1)) { Log_print0(Diags_INFO, "Server_exec: unexpected variable value." \ "Test failed."); Log_print2(Diags_INFO, "Server_exec: Previous shared variable " "value %d, current value=%d", prevNum, num); status = GATEMPAPP_E_FAILURE; goto leave; } /* leave Gate */ GateMP_leave(Module.hostGateMPHandle, gateKey); } /* wait for sync message before we switch gates */ status = MessageQ_get(Module.slaveQue, (MessageQ_Msg *)&msg, MessageQ_FOREVER); if (status < 0) { goto leave; } if (msg->cmd != GATEMPAPP_CMD_SYNC) { status = GATEMPAPP_E_UNEXPECTEDMSG; goto leave; } queId = MessageQ_getReplyQueue(msg); MessageQ_put(queId, (MessageQ_Msg)msg); Log_print0(Diags_INFO,"Server_exec: Using slave-created gate"); for (i = 0;i < LOOP_ITR; i++) { /* modify the shared variable as long as no one else is currently * accessing it */ /* enter GateMP */ gateKey = GateMP_enter(Module.slaveGateMPHandle); /* read shared variable value */ prevNum = *intPtr; /* randomly modify the shared variable */ if ( rand() % 2) { *intPtr -= 1; } else { *intPtr += 1; } /* read shared variable value again */ num = *intPtr; if ((prevNum != num - 1) && (prevNum != num + 1)) { Log_print0(Diags_INFO, "Server_exec: unexpected variable value." \ "Test failed."); Log_print2(Diags_INFO, "Server_exec: Previous " "value=%d, current value=%d", prevNum, num); status = GATEMPAPP_E_FAILURE; goto leave; } /* leave Gate */ GateMP_leave(Module.slaveGateMPHandle, gateKey); } leave: /* close host GateMP */ if (Module.hostGateMPHandle) { GateMP_close(&Module.hostGateMPHandle); } Log_print0(Diags_ENTRY, "Server_exec: host GateMP closed"); Log_print1(Diags_EXIT, "<-- Server_exec: %d", (IArg)status); return(status); }
/* * ======== tsk0_func ======== * Allocates a message and ping-pongs the message around the processors. * A local message queue is created and a remote message queue is opened. * Messages are sent to the remote message queue and retrieved from the * local MessageQ. */ Void tsk0_func(UArg arg0, UArg arg1) { MessageQ_Msg msg; MessageQ_Handle messageQ; MessageQ_QueueId remoteQueueId; Int status; UInt16 msgId = 0; HeapBufMP_Handle heapHandle; HeapBufMP_Params heapBufParams; if (MultiProc_self() == 0) { /* * Create the heap that will be used to allocate messages. */ HeapBufMP_Params_init(&heapBufParams); heapBufParams.regionId = 0; heapBufParams.name = HEAP_NAME; heapBufParams.numBlocks = 1; heapBufParams.blockSize = sizeof(MessageQ_MsgHeader); heapHandle = HeapBufMP_create(&heapBufParams); if (heapHandle == NULL) { System_abort("HeapBufMP_create failed\n" ); } } else { /* Open the heap created by the other processor. Loop until opened. */ do { status = HeapBufMP_open(HEAP_NAME, &heapHandle); /* * Sleep for 1 clock tick to avoid inundating remote processor * with interrupts if open failed */ if (status < 0) { Task_sleep(1); } } while (status < 0); } /* Register this heap with MessageQ */ MessageQ_registerHeap((IHeap_Handle)heapHandle, HEAPID); /* Create the local message queue */ messageQ = MessageQ_create(localQueueName, NULL); if (messageQ == NULL) { System_abort("MessageQ_create failed\n" ); } /* Open the remote message queue. Spin until it is ready. */ do { status = MessageQ_open(nextQueueName, &remoteQueueId); /* * Sleep for 1 clock tick to avoid inundating remote processor * with interrupts if open failed */ if (status < 0) { Task_sleep(1); } } while (status < 0); if (MultiProc_self() == 0) { /* Allocate a message to be ping-ponged around the processors */ msg = MessageQ_alloc(HEAPID, sizeof(MessageQ_MsgHeader)); if (msg == NULL) { System_abort("MessageQ_alloc failed\n" ); } /* * Send the message to the next processor and wait for a message * from the previous processor. */ System_printf("Start the main loop\n"); while (msgId < NUMLOOPS) { /* Increment...the remote side will check this */ msgId++; MessageQ_setMsgId(msg, msgId); System_printf("Sending a message #%d to %s\n", msgId, nextQueueName); /* send the message to the remote processor */ status = MessageQ_put(remoteQueueId, msg); if (status < 0) { System_abort("MessageQ_put had a failure/error\n"); } /* Get a message */ status = MessageQ_get(messageQ, &msg, MessageQ_FOREVER); if (status < 0) { System_abort("This should not happen since timeout is forever\n"); } } } else { /* * Wait for a message from the previous processor and * send it to the next processor */ System_printf("Start the main loop\n"); while (TRUE) { /* Get a message */ status = MessageQ_get(messageQ, &msg, MessageQ_FOREVER); if (status < 0) { System_abort("This should not happen since timeout is forever\n"); } System_printf("Sending a message #%d to %s\n", MessageQ_getMsgId(msg), nextQueueName); /* Get the message id */ msgId = MessageQ_getMsgId(msg); /* send the message to the remote processor */ status = MessageQ_put(remoteQueueId, msg); if (status < 0) { System_abort("MessageQ_put had a failure/error\n"); } /* test done */ if (msgId >= NUMLOOPS) { break; } } } System_printf("The test is complete\n"); BIOS_exit(0); }
void slave_main(void) { process_message_t * p_msg = 0; MessageQ_Handle h_receive_queue = 0; MessageQ_QueueId reply_queue_id = 0; HeapBufMP_Handle heapHandle; Int status; char receive_queue_name[16]; GET_SLAVE_QUEUE_NAME(receive_queue_name, DNUM); /* Open the heap created by the other processor. Loop until opened. */ do { status = HeapBufMP_open(IMAGE_PROCESSING_HEAP_NAME, &heapHandle); if (status < 0) { Task_sleep(1); } } while (status < 0); /* Register this heap with MessageQ */ MessageQ_registerHeap((IHeap_Handle)heapHandle, IMAGE_PROCESSING_HEAPID); /* Create the local message queue */ h_receive_queue = MessageQ_create(receive_queue_name, NULL); if (h_receive_queue == NULL) { logout("MessageQ_create failed\n" ); goto close_n_exit; } for (;;) { if (MessageQ_get(h_receive_queue, (MessageQ_Msg *)&p_msg, MessageQ_FOREVER) < 0) { logout("%s: This should not happen since timeout is forever\n", receive_queue_name); goto close_n_exit; } reply_queue_id = MessageQ_getReplyQueue(p_msg); if (reply_queue_id == MessageQ_INVALIDMESSAGEQ) { logout("receive_queue_name: Ignoring the message as reply queue is not set.\n", receive_queue_name); continue; } //Execute calculation #ifdef _TRACE_MC_ logout("[core_%u] Execute process (processing_type=%u)\n", p_msg->core_id, p_msg->info.processing_type); //trace #endif switch(p_msg->info.processing_type) { case pt_ssd: //Call calculation code exec_ssd(p_msg); break; case pt_ssdJacHess: //Call calculation code exec_ssdJacHess(p_msg); break; case pt_cacheinval: CacheInvalTotalMemory(p_msg); break; case pt_shrink: //Call image shrink code exec_shrinkImage(p_msg); break; default: logout("Invalid IPC processing type: %u", p_msg->info.processing_type); } /* send the message to the remote processor */ #ifdef _TRACE_MC_ logout("[core_%u] Putting slave response to the MessageQ, then going idle again ...\n", p_msg->core_id); #endif if (MessageQ_put(reply_queue_id, (MessageQ_Msg)p_msg) < 0) { logout("%s: MessageQ_put had a failure error\n", receive_queue_name); } } close_n_exit: if(h_receive_queue) MessageQ_delete(&h_receive_queue); }