示例#1
0
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);
}