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_deleteLocalResources(Void) { Error_Block eb; Int status = 0; struct SystemCfg *stateObj = &SystemCfg_State; Log_print1(Diags_ENTRY, "--> %s: ()", (IArg)FXNN); Error_init(&eb); /* unregister heap with MessageQ */ MessageQ_unregisterHeap(Global_TilerHeapId); /* delete heap used for rcm message queue */ HeapBufMP_delete(&stateObj->heapH); /* send done event to remote core */ Log_print0(Diags_USER1, FXNN": send done event to remote core"); status = Notify_sendEvent(stateObj->hostProcId, Global_NotifyLineId, Global_HostDspEvtNum, Global_EvtDone, TRUE); if (status < 0) { /* Log_error() */ Log_print4(Diags_USER8, "Error: %s, line %d: %s: Notify_sendEvent() returned error %d", (IArg)__FILE__, (IArg)__LINE__, (IArg)FXNN, (IArg)status); goto leave; } /* wait for done event from remote core */ Log_print0(Diags_USER1, FXNN": waiting for done 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 done event"); /* unregister notify callback */ status = Notify_unregisterEvent(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_unregisterEventSingle() returned error %d", (IArg)__FILE__, (IArg)__LINE__, (IArg)FXNN, (IArg)status); goto leave; } /* delete sync object */ if (stateObj->semH != NULL) { SemThread_destruct(&stateObj->semObj); stateObj->semH = NULL; } leave: Log_print2(Diags_EXIT, "<-- %s: %d", (IArg)FXNN, (IArg)status); return(status); }
/* * ======== Hello_stop ======== * * 1. send shutdown event * 2. wait for shutdown acknowledgement * 3. close remote resources * 4. handshake close event * 5. delete shared resoures * 6. send disconnect event (last event sent) * 7. wait for disconnect event * 8. unregister notify callback * 9. delete semaphore object */ Int Hello_stop(Void) { Int status; UInt32 event; /* * 1. send shutdown command (out-of-band) */ status = Notify_sendEvent(Module.remoteProcId, Module.lineId, Module.eventId, App_CMD_SHUTDOWN, TRUE); if (status < 0) { goto leave; } /* * 2. wait for shutdown acknowledgement */ do { event = Hello_waitForEvent(); if (event >= App_E_FAILURE) { status = -1; goto leave; } } while (event != App_CMD_SDACK); /* * 3. close remote resources */ /* * 4. handshake close event */ status = Notify_sendEvent(Module.remoteProcId, Module.lineId, Module.eventId, App_CMD_CLOSED, TRUE); if (status < 0) { goto leave; } do { event = Hello_waitForEvent(); if (event >= App_E_FAILURE) { status = -1; goto leave; } } while (event != App_CMD_CLOSED); /* * 5. delete shared resoures */ /* unregister heap with MessageQ */ status = MessageQ_unregisterHeap(Global_RcmClientHeapId); if (status < 0) { goto leave; } /* delete the message heap */ status = HeapBufMP_delete(&Module.msgHeap); if (status < 0) { goto leave; } /* * 6. send disconnect event (last event sent) */ status = Notify_sendEvent(Module.remoteProcId, Module.lineId, Module.eventId, App_CMD_DONE, TRUE); if (status < 0) { goto leave; } /* * 7. wait for disconnect event (last event received) */ do { event = Hello_waitForEvent(); if (event >= App_E_FAILURE) { status = -1; goto leave; } } while (event != App_CMD_DONE); /* * 8. unregister notify callback */ status = Notify_unregisterEventSingle(Module.remoteProcId, Module.lineId, Module.eventId); if (status < 0) { goto leave; } /* * 9. delete semaphore object */ SemThread_destruct(&Module.semS); leave: return(status); }