/* * ======== SystemCfg_openResources ======== */ Int SystemCfg_openResources(SystemCfg_Object *obj) { Int status; /* open rcm heap created on host processor */ status = HeapBufMP_open(SystemCfg_RcmMsgHeapName_CompDev, &(obj->rcmHeapH)); if (status < 0) { Log_error1("HeapBufMP_open() error %d", (IArg)status); goto leave; } /* register this heap with MessageQ */ MessageQ_registerHeap((Ptr)(obj->rcmHeapH), SystemCfg_RcmMsgHeapId_CompDev); leave: return(status); }
/** * Handler for heapbuf mp open 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_heapbufmp_open(resmgr_context_t *ctp, io_devctl_t *msg, syslink_ocb_t *ocb) { HeapBufMPDrv_CmdArgs * cargs = (HeapBufMPDrv_CmdArgs *) (_DEVCTL_DATA (msg->i)); HeapBufMPDrv_CmdArgs * out = (HeapBufMPDrv_CmdArgs *) (_DEVCTL_DATA (msg->o)); String name = (String)(cargs+1); HeapBufMP_Handle handle; out->apiStatus = HeapBufMP_open (name, &handle); /* HeapBufMP_open can fail at run-time, so don't assert on its * failure. */ out->args.open.handle = handle; if (out->apiStatus >= 0 && out->args.open.handle) { /* Add this call to the list to be cleaned-up */ add_ocb_res(ocb, DCMD_HEAPBUFMP_CLOSE, (int)out->args.open.handle, NULL); } return (_RESMGR_PTR (ctp, &msg->o, sizeof (msg->o) + sizeof(HeapBufMPDrv_CmdArgs))); }
/* * ======== 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); }
/* * ======== 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_setup ======== * * 1. create semaphore object * 2. register notify callback * 3. wait until remote core has also registered notify callback * 4. create local & shared resources * 5. send resource ready event * 6. wait for remote resource ready event * 7. open remote resources * 8. handshake the ready event */ Int Server_setup(Void) { Int status; UInt32 event; Semaphore_Params semParams; RcmServer_Params rcmServerP; Log_print0(Diags_ENTRY | Diags_INFO, "--> Server_setup:"); /* * 1. create semaphore object */ Semaphore_Params_init(&semParams); semParams.mode = Semaphore_Mode_COUNTING; Semaphore_construct(&Module.semS, 0, &semParams); Module.semH = Semaphore_handle(&Module.semS); /* * 2. register notify callback */ status = Notify_registerEventSingle(Module.hostProcId, Module.lineId, Module.eventId, Server_notifyCB, (UArg)&Module); if (status < 0) { goto leave; } /* * 3. wait until remote core has also registered notify callback */ do { status = Notify_sendEvent(Module.hostProcId, Module.lineId, Module.eventId, App_CMD_NOP, TRUE); if (status == Notify_E_EVTNOTREGISTERED) { Task_sleep(200); /* ticks */ } } while (status == Notify_E_EVTNOTREGISTERED); if (status < 0) { goto leave; } /* * 4. create local & shared resources (to be opened by remote processor) */ /* * 5. send resource ready event */ status = Notify_sendEvent(Module.hostProcId, Module.lineId, Module.eventId, App_CMD_RESRDY, TRUE); if (status < 0) { goto leave; } /* * 6. wait for remote resource ready event */ do { event = Server_waitForEvent(); if (event >= App_E_FAILURE) { status = -1; goto leave; } } while (event != App_CMD_RESRDY); /* * 7. open remote resources */ /* open the rcm heap */ status = HeapBufMP_open(Global_RcmClientHeapName, &Module.heapH); if (status < 0) { Log_error1("Server_setup: HeapBufMP_open() returned error %d", (IArg)status); goto leave; } /* register the rcm heap with MessageQ */ status = MessageQ_registerHeap((Ptr)(Module.heapH), Global_RcmClientHeapId); if (status < 0) { Log_error1("Server_setup: MessageQ_restierHeap() returned error %d", (IArg)status); goto leave; } /* initialize RcmServer create params */ RcmServer_Params_init(&rcmServerP); rcmServerP.fxns.length = Server_fxnTab.length; rcmServerP.fxns.elem = Server_fxnTab.elem; /* create the RcmServer instance */ status = RcmServer_create(Global_RcmServerName, &rcmServerP, &Module.rcmServerH); if (status < 0) { Log_error1("Server_setup: RcmServer_create() returned error %d", (IArg)status); goto leave; } /* start the server */ RcmServer_start(Module.rcmServerH); /* * 8. handshake the ready event */ status = Notify_sendEvent(Module.hostProcId, Module.lineId, Module.eventId, App_CMD_READY, TRUE); if (status < 0) { goto leave; } do { event = Server_waitForEvent(); if (event >= App_E_FAILURE) { status = -1; goto leave; } } while (event != App_CMD_READY); leave: Log_print1(Diags_EXIT, "<-- Server_setup: %d", (IArg)status); return(status); }
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); }