Int RcmClient_getReturnMsg_P(RcmClient_Object *obj, const UInt16 msgId, RcmClient_Message **returnMsg) { List_Elem *elem; Recipient *recipient; RcmClient_Packet *packet; Bool messageDelivered; MessageQ_Msg msgqMsg = NULL; Bool messageFound = FALSE; Int queueLockAcquired = 0; Error_Block eb; Int rval; Int status = RcmClient_S_SUCCESS; Log_print3(Diags_ENTRY, "--> "FXNN": (obj=0x%x, msgId=%d, returnMsgPtr=0x%x", (IArg)obj, (IArg)msgId, (IArg)returnMsg); Error_init(&eb); *returnMsg = NULL; /* keep trying until message found */ while (!messageFound) { /* acquire the mailbox lock */ Semaphore_pend(obj->mbxLock, Semaphore_FOREVER, &eb); if (Error_check(&eb)) { /* TODO */ goto leave; } /* search new mail list for message */ elem = NULL; while ((elem = List_next(obj->newMail, elem)) != NULL) { packet = getPacketAddrElem(elem); if (msgId == packet->msgId) { List_remove(obj->newMail, elem); *returnMsg = &packet->message; messageFound = TRUE; break; } } if (messageFound) { /* release the mailbox lock */ Semaphore_post(obj->mbxLock, &eb); if (Error_check(&eb)) { /* TODO */ } } else { /* attempt the message queue lock */ queueLockAcquired = Semaphore_pend(obj->queueLock, 0, &eb); if (Error_check(&eb)) { /* TODO */ goto leave; } if (1 == queueLockAcquired) { /* * mailman role */ /* deliver new mail until message found */ while (!messageFound) { /* get message from queue if available (non-blocking) */ if (NULL == msgqMsg) { rval = MessageQ_get(obj->msgQue, &msgqMsg, 0); if ((MessageQ_E_TIMEOUT != rval) && (rval < 0)) { Log_error0(FXNN": lost return message"); status = RcmClient_E_LOSTMSG; goto leave; } Log_print0(Diags_INFO, FXNN": return message received"); } while (NULL != msgqMsg) { /* check if message found */ packet = getPacketAddrMsgqMsg(msgqMsg); messageFound = (msgId == packet->msgId); if (messageFound) { *returnMsg = &packet->message; /* search wait list for new mailman */ elem = NULL; while ((elem = List_next(obj->recipients, elem)) != NULL) { recipient = (Recipient *)elem; if (NULL == recipient->msg) { /* signal recipient's event */ SemThread_post(SemThread_handle( &recipient->event), &eb); break; } } /* release the message queue lock */ Semaphore_post(obj->queueLock, &eb); if (Error_check(&eb)) { /* TODO */ } /* release the mailbox lock */ Semaphore_post(obj->mbxLock, &eb); if (Error_check(&eb)) { /* TODO */ } break; } else { /* * deliver message to mailbox */ /* search recipient list for message owner */ elem = NULL; messageDelivered = FALSE; while ((elem = List_next(obj->recipients, elem)) != NULL) { recipient = (Recipient *)elem; if (recipient->msgId == packet->msgId) { recipient->msg = &packet->message; /* signal the recipient's event */ SemThread_post(SemThread_handle( &recipient->event), &eb); messageDelivered = TRUE; break; } } /* add undelivered message to new mail list */ if (!messageDelivered) { /* use the elem in the MessageQ header */ elem = (List_Elem *)&packet->msgqHeader; List_put(obj->newMail, elem); } } /* get next message from queue if available */ rval = MessageQ_get(obj->msgQue, &msgqMsg, 0); if ((MessageQ_E_TIMEOUT != rval) && (rval < 0)) { Log_error0(FXNN": lost return message"); status = RcmClient_E_LOSTMSG; goto leave; } Log_print0(Diags_INFO, FXNN": return message received"); } if (!messageFound) { /* * message queue empty */ /* release the mailbox lock */ Semaphore_post(obj->mbxLock, &eb); if (Error_check(&eb)) { /* TODO */ } /* get next message, this blocks the thread */ rval = MessageQ_get(obj->msgQue, &msgqMsg, MessageQ_FOREVER); if (rval < 0) { Log_error0(FXNN": lost return message"); status = RcmClient_E_LOSTMSG; goto leave; } Log_print0(Diags_INFO, FXNN": return message received"); if (msgqMsg == NULL) { Log_error0(FXNN": reply message has been lost"); status = RcmClient_E_LOSTMSG; goto leave; } /* acquire the mailbox lock */ Semaphore_pend(obj->mbxLock, Semaphore_FOREVER, &eb); if (Error_check(&eb)) { goto leave; /* TODO */ } } } } else { /* construct recipient on local stack */ Recipient self; self.msgId = msgId; self.msg = NULL; SemThread_construct(&self.event, 0, NULL, &eb); if (Error_check(&eb)) { /* TODO */ } /* add recipient to wait list */ elem = &self.elem; List_put(obj->recipients, elem); /* release the mailbox lock */ Semaphore_post(obj->mbxLock, &eb); if (Error_check(&eb)) { /* TODO */ } /* wait on event */ SemThread_pend(SemThread_handle(&self.event), Semaphore_FOREVER, &eb); if (Error_check(&eb)) { /* TODO */ } /* acquire the mailbox lock */ Semaphore_pend(obj->mbxLock, Semaphore_FOREVER, &eb); if (Error_check(&eb)) { goto leave; /* TODO */ } if (NULL != self.msg) { /* pickup message */ *returnMsg = self.msg; messageFound = TRUE; } /* remove recipient from wait list */ List_remove(obj->recipients, elem); SemThread_destruct(&self.event); /* release the mailbox lock */ Semaphore_post(obj->mbxLock, &eb); if (Error_check(&eb)) { /* TODO */ } } } } /* while (!messageFound) */ leave: Log_print2(Diags_EXIT, "<-- %s: %d", (IArg)FXNN, (IArg)status); return(status); }
Int SystemCfg_createLocalResources(Void) { Error_Block eb; SemThread_Params semThreadP; HeapBufMP_Params heapBufMPP; Int count; Char heapName[32]; Int status = 0; struct SystemCfg *stateObj = &SystemCfg_State; static Int heapId = 1; Log_print1(Diags_ENTRY, "--> %s: ()", (IArg)FXNN); Error_init(&eb); /* create sync object used to wait on remote core startup */ SemThread_Params_init(&semThreadP); semThreadP.mode = SemThread_Mode_COUNTING; SemThread_construct(&stateObj->semObj, 0, &semThreadP, &eb); if (Error_check(&eb)) { /* Log_error() */ Log_print3(Diags_USER8, "Error: %s, line %d: %s: SemThread_construct() failed", (IArg)__FILE__, (IArg)__LINE__, (IArg)FXNN); status = -1; goto leave; } stateObj->semH = SemThread_handle(&stateObj->semObj); /* register notify callback for ready event from remote core */ status = Notify_registerEvent(stateObj->hostProcId, Global_NotifyLineId, Global_HostDspEvtNum, SystemCfg_notifyCB__P, (UArg)stateObj); if (status < 0) { /* Log_error() */ Log_print4(Diags_USER8, "Error: %s, line %d: %s: " "Notify_registerEventSingle() returned error %d", (IArg)__FILE__, (IArg)__LINE__, (IArg)FXNN, (IArg)status); goto leave; } /* create a heap for tiler usage */ Log_print0(Diags_USER2, FXNN": HeapBufMP_create for tiler"); HeapBufMP_Params_init(&heapBufMPP); heapBufMPP.regionId = 0; heapBufMPP.blockSize = 0x200; /* 512 B */ heapBufMPP.numBlocks = 8; /* hack: make a unique heap name */ System_sprintf(heapName, "rcmHeap-%d", heapId); heapBufMPP.name = heapName; stateObj->heapH = HeapBufMP_create(&heapBufMPP); if (stateObj->heapH == NULL) { /* Log_error() */ Log_print3(Diags_USER8, "Error: %s, line %d: %s: HeapBuf_create() failed", (IArg)FXNN, (IArg)__FILE__, (IArg)__LINE__); status = -1; goto leave; } /* register this heap with MessageQ */ Log_print2(Diags_USER2, FXNN": MessageQ_registerHeap: (heapH: 0x%x, heapId: %d)", (IArg)(stateObj->heapH), (IArg)Global_TilerHeapId); MessageQ_registerHeap((Ptr)(stateObj->heapH), Global_TilerHeapId); /* Send create done event to remote core. Need to loop in case * the remote core has not yet registered with notify to receive * this event. */ Log_print0(Diags_USER1, FXNN": send EvtCreateDone to remote core"); count = 0; do { status = Notify_sendEvent(stateObj->hostProcId, Global_NotifyLineId, Global_HostDspEvtNum, Global_EvtCreateDone, TRUE); if (status == Notify_E_EVTNOTREGISTERED) { Thread_sleep(500, &eb); /* 0.5 ms */ } } while ((++count < 10) && (status == Notify_E_EVTNOTREGISTERED)); if (status < 0) { /* Log_error() */ Log_print5(Diags_USER8, "Error: %s, line %d: %s: Notify_sendEvent() returned error %d," "giving up after %d tries", (IArg)__FILE__, (IArg)__LINE__, (IArg)FXNN, (IArg)status, (IArg)count); goto leave; } /* wait for create done event from remote core */ Log_print0(Diags_USER1, FXNN": waiting for EvtCreateDone event..."); SemThread_pend(stateObj->semH, SemThread_FOREVER, &eb); if (Error_check(&eb)) { /* Log_error() */ Log_print3(Diags_USER8, "Error: %s, line %d: %s: SemThread_pend() returned with error", (IArg)__FILE__, (IArg)__LINE__, (IArg)FXNN); status = -1; goto leave; } Log_print0(Diags_USER1, FXNN": ...received EvtCreatDone event"); leave: Log_print2(Diags_EXIT, "<-- %s: %d", (IArg)FXNN, (IArg)status); return(status); }
/* * ======== Hello_start ======== * * 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 Hello_start(UInt16 remoteProcId) { Int status; UInt32 event; SemThread_Params semParams; HeapBufMP_Params heapParams; Error_Block eb; Error_init(&eb); Module.remoteProcId = remoteProcId; /* * 1. create semaphore object */ SemThread_Params_init(&semParams); semParams.mode = SemThread_Mode_COUNTING; SemThread_construct(&Module.semS, 0, &semParams, &eb); if (Error_check(&eb)) { status = -15; goto leave; } Module.semH = SemThread_handle(&Module.semS); /* * 2. register notify callback */ status = Notify_registerEventSingle(Module.remoteProcId, Module.lineId, Module.eventId, Hello_notifyCB, (UArg)&Module); if (status < 0) { goto leave; } /* * 3. wait until remote core has also registered notify callback */ do { status = Notify_sendEvent(Module.remoteProcId, Module.lineId, Module.eventId, App_CMD_NOP, TRUE); if (status == Notify_E_EVTNOTREGISTERED) { Thread_sleep(1000, &eb); /* microseconds */ } } while (status == Notify_E_EVTNOTREGISTERED); if (status < 0) { goto leave; } /* * 4. create local & shared resources (to be opened by remote processor) */ /* create heap for rcm messages */ HeapBufMP_Params_init(&heapParams); heapParams.name = Global_RcmClientHeapName; heapParams.regionId = 0; heapParams.blockSize = 0x200; /* 512 B */ heapParams.numBlocks = 8; Module.msgHeap = HeapBufMP_create(&heapParams); if (Module.msgHeap == NULL) { Log_error0("Hello_start: HeapBuf_create() failed"); status = -1; goto leave; } /* register heap with MessageQ */ status = MessageQ_registerHeap((Ptr)(Module.msgHeap), Global_RcmClientHeapId); if (status < 0) { goto leave; } /* * 5. send resource ready event */ status = Notify_sendEvent(Module.remoteProcId, Module.lineId, Module.eventId, App_CMD_RESRDY, TRUE); if (status < 0) { goto leave; } /* * 6. wait for remote resource ready event */ do { event = Hello_waitForEvent(); if (event >= App_E_FAILURE) { status = -1; goto leave; } } while (event != App_CMD_RESRDY); /* * 7. open remote resources */ /* * 8. handshake the ready event */ status = Notify_sendEvent(Module.remoteProcId, Module.lineId, Module.eventId, App_CMD_READY, TRUE); if (status < 0) { goto leave; } do { event = Hello_waitForEvent(); if (event >= App_E_FAILURE) { status = -1; goto leave; } } while (event != App_CMD_READY); leave: return(status); }