/* * ======== 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"); } } }
/* * ======== 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); }
/* * ======== 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); } }
/* * ======== 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); }
/** * 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(); }
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; }
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); }