/*
 *  ======== MemMgr_createDaemon ========
 */
MemMgr_Daemon_Handle MemMgr_createDaemon(String name)
{
    Error_Block ebObj;
    Error_Block *eb = &ebObj;
    RcmServer_Params rcmServer_Params;
    MemMgr_Daemon_Object *obj = NULL;
    UInt32 unused;
    Int status = 0;

    Error_init(eb);

    /* allocate the daemon object */
    obj = (MemMgr_Daemon_Object *)Memory_alloc(NULL,
        sizeof(MemMgr_Daemon_Object), sizeof(Int), eb);

    if (Error_check(eb)) {
        goto leave;
    }
    obj->hRcmServer = NULL;

    /* create the RcmServer instance */
    RcmServer_Params_init(&rcmServer_Params);
    status = RcmServer_create(name, &rcmServer_Params, &obj->hRcmServer);

    if (status < 0) {
        goto leave;
    }

    /* install the function pointers */
    status = RcmServer_addSymbol(obj->hRcmServer,
        "MemMgr_PageSize_skel", MemMgr_PageSize_skel, &unused);
    if (status < 0) goto leave;

    status = RcmServer_addSymbol(obj->hRcmServer,
        "MemMgr_Alloc_skel", MemMgr_Alloc_skel, &unused);
    if (status < 0) goto leave;

    status = RcmServer_addSymbol(obj->hRcmServer,
        "MemMgr_Free_skel", MemMgr_Free_skel, &unused);
    if (status < 0) goto leave;

    status = RcmServer_addSymbol(obj->hRcmServer,
        "MemMgr_Map_skel", MemMgr_Map_skel, &unused);
    if (status < 0) goto leave;

    status = RcmServer_addSymbol(obj->hRcmServer,
        "MemMgr_UnMap_skel", MemMgr_UnMap_skel, &unused);
    if (status < 0) goto leave;

    status = RcmServer_addSymbol(obj->hRcmServer,
        "MemMgr_Is1DBlock_skel", MemMgr_Is1DBlock_skel, &unused);
    if (status < 0) goto leave;

    status = RcmServer_addSymbol(obj->hRcmServer,
        "MemMgr_Is2DBlock_skel", MemMgr_Is2DBlock_skel, &unused);
    if (status < 0) goto leave;

    status = RcmServer_addSymbol(obj->hRcmServer,
        "MemMgr_IsMapped_skel", MemMgr_IsMapped_skel, &unused);
    if (status < 0) goto leave;

    status = RcmServer_addSymbol(obj->hRcmServer,
        "MemMgr_GetStride_skel", MemMgr_GetStride_skel, &unused);
    if (status < 0) goto leave;

    status = RcmServer_addSymbol(obj->hRcmServer,
        "TilerMem_GetStride_skel", TilerMem_GetStride_skel, &unused);
    if (status < 0) goto leave;

    status = RcmServer_addSymbol(obj->hRcmServer,
        "TilerMem_VirtToPhys_skel", TilerMem_VirtToPhys_skel, &unused);
    if (status < 0) goto leave;

    /* start the server */
    RcmServer_start(obj->hRcmServer);

    /* pause to let server thread get going */
    usleep(20000);  /* 0.02 sec */

leave:
    if (Error_check(eb)) {
        Error_raise(eb, Error_E_generic, "MemMgr_createDeamon failed", 0);

        if (obj != NULL) {
            Memory_free(NULL, (Ptr)obj, sizeof(MemMgr_Daemon_Object));
            obj = NULL;
        }
    }

    return((MemMgr_Daemon_Handle)obj);
}
/*
 *  ======== RcmServerThreadFxn ========
 *     RCM server test thread function
 */
Void RcmServerThreadFxn (Void *arg)
{
    RcmServer_Params    rcmServerParams;
    UInt                fxnIdx;
    Char *              rcmServerName       = RCMSERVER_NAME;
    Int                 status              = 0;

    /* Rcm server module init */
    Osal_printf ("RcmServerThreadFxn: RCM Server module init.\n");
    RcmServer_init ();

    /* Rcm server module params init*/
    Osal_printf ("RcmServerThreadFxn: RCM Server module params init.\n");
    status = RcmServer_Params_init (&rcmServerParams);
    if (status < 0) {
        Osal_printf ("RcmServerThreadFxn: Error in RCM Server instance params "
                        "init \n");
        goto exit;
    }
    Osal_printf ("RcmServerThreadFxn: RCM Server instance params init "
                   "passed \n");

    /* Create the RcmServer instance */
    Osal_printf ("RcmServerThreadFxn: Creating RcmServer instance %s.\n",
        rcmServerName);
    status = RcmServer_create (rcmServerName, &rcmServerParams,
                                &rcmServerHandle);
    if (status < 0) {
        Osal_printf ("RcmServerThreadFxn: Error in RCM Server create.\n");
        goto exit;
    }
    Osal_printf ("RcmServerThreadFxn: RCM Server Create passed \n");

    sem_init (&serverThreadSync, 0, 0);

    /* Register the remote functions */
    Osal_printf ("RcmServerThreadFxn: Registering remote function - "
                "fxnDouble\n");
    status = RcmServer_addSymbol (rcmServerHandle, "fxnDouble", fxnDouble,
                                    &fxnIdx);
    if ((status < 0) || (fxnIdx == 0xFFFFFFFF)) {
        Osal_printf ("RcmServerThreadFxn: Add symbol failed.\n");
        goto exit;
    }

    Osal_printf ("RcmServerThreadFxn: Registering remote function - "
                "fxnExit\n");
    status = RcmServer_addSymbol (rcmServerHandle, "fxnExit", fxnExit, &fxnIdx);
    if ((status < 0) || (fxnIdx == 0xFFFFFFFF)) {
        Osal_printf ("RcmServerThreadFxn: Add symbol failed.\n");
        goto exit;
    }

    Osal_printf ("RcmServerThreadFxn: Start RCM server thread \n");
    RcmServer_start (rcmServerHandle);
    Osal_printf ("RcmServerThreadFxn: RCM Server start passed \n");

    sem_wait (&serverThreadSync);

    sem_post (&mainThreadWait);

exit:
    Osal_printf ("RcmServerThreadFxn: Leaving RCM server test thread "
                    "function \n");
    return;
}