Example #1
0
/*
 * ======== traceThrFxn ========
 */
static void *traceThrFxn(void *arg)
{
    String engineName = (String) arg;
    Server_Status status;
    FILE *f;
    IArg key;

    /* determine DSP line prefix: "[DSP] " if local and DSP trace end up at the same
     * file, otherwise ""
     */
    char *dspPrefix = (dsp0TraceFilePtr == localTraceFilePtr) ? "[DSP] " : "";

    DBG("Trace thread started\n");

    hEngine = Engine_open(engineName, NULL, NULL);

    if (hEngine == NULL) {
        ERR("Failed to open codec engine \"%s\"\n", engineName);
        threadCreateFailed = TRUE;
        return ((void *) -1);
    }

    /* for multi-process situations, make sure can acquire server trace */
    if (Global_useLinkArbiter) {

        /* get server handle */
        hServer = Engine_getServer(hEngine);

        /* cleanup and abort if can't get server handle */
        if (hServer == NULL) {
            Engine_close(hEngine);
            ERR("Failed to get server handle\n");
            threadCreateFailed = TRUE;
            return ((void *) -1);
        }

        /* request server trace token */
        status = Server_connectTrace(hServer, &traceToken);

        /* cleanup and abort if trace could not acquire trace token */
        if (status != Server_EOK) {
            Engine_close(hEngine);
            ERR("Failed to connect for server trace\n");
            threadCreateFailed = TRUE;
            return ((void *) -1);
        }
    }

    /* else: if single-process, don't need to explictly connect for trace */

    Engine_setTrace(hEngine, dsp0mask);

    /* create the pipe thread now */
    if (cmdPipeFile != NULL && cmdPipeFile[0] != '\0') {
        if (pthread_create(&pipeThread, NULL, pipeThrFxn, NULL)) {
            ERR("Failed to create pipe thread\n");
        } else {
            /* run the thread just created so it can immediately execute
             * pending cmdPipe trace commands -- in case there are any
             */
            while (pipeThreadCreated == FALSE) {
                sched_yield();
            }
        }
    }

    /* TODO: remove? will LogClient_connect be inside CE? */
    /*
     * Note, call LogClient_connect() before releasing the main thread to
     * avoid context switching away _during_ the connect() call - which could
     * result in a skewed timesynch log.
     */
    if (dsp0BiosFilePtr != NULL) {
//        LogClient_connect();
    }

    /* Release the spinning main thread to run */
    traceThreadCreated = TRUE;

    while (!quit) {

        if (refresh > 0) {

            DBG("Writing DSP logs\n");

            key = Gate_enterModule();

            Engine_fwriteTrace(hEngine, dspPrefix, dsp0TraceFilePtr);

            if (dsp0BiosFilePtr != NULL) {
//                LogClient_fwriteLogs(dsp0BiosFilePtr);
            }

            Gate_leaveModule(key);

            DBG("Sleeping for %d us\n", refresh);
            usleep(refresh);
        } else {
            DBG("Sleeping for %d us\n", SLEEPWHENNOREFRESH);
            usleep( SLEEPWHENNOREFRESH );
        }
    }

    if (refresh > 0) {

        DBG("Trace thread exiting, writing final DSP logs\n");

        /* try to collect anything that remained one more time */
        key = Gate_enterModule();

        Engine_fwriteTrace(hEngine, dspPrefix, dsp0TraceFilePtr);

        if (dsp0BiosFilePtr != NULL) {
//            LogClient_fwriteLogs(dsp0BiosFilePtr);
        }

        Gate_leaveModule(key);
    }

    if (dsp0BiosFilePtr != NULL) {
//        LogClient_disconnect();
    }

    /* for multi-process situations, release trace token back to RMS */
    if (Global_useLinkArbiter) {
        Server_disconnectTrace(hServer, traceToken);
    }

    Engine_close(hEngine);

    DBG("Quitting trace thread\n");

    /* and killing our offspring. */
    if (pipeThread != NULL) {
        DBG("Telling pipe thread to quit\n");
        f = fopen(cmdPipeFile, "w");
        if (f != NULL) {
            fputs(TRACECMD_QUIT, f);
            fclose(f);
            DBG("Wrote quit command, waiting for the pipe thread to join\n");
            if (pthread_join(pipeThread, NULL)) {
                ERR("Failed to join pipe thread\n");
            }
            DBG("Pipe thread joined.\n");
        }
    }

    return ((void *) 1);
}
Example #2
0
/*
 *  ======== smain ========
 */
Int smain(Int argc, String argv[])
{
    Char newTraceMask[MAXTRACESTRING];
    Server_Handle server = NULL;
    Bool finished = FALSE;
    Uns mode = PULLTRACE;
    Server_Status status;
    Int traceToken;
    String mask;
    Uns rate;

    /* interpret PULLTRACE mode args */
    if (argc == 3) {
        rate = atoi(argv[1]);
        mask = argv[2];
    }

    /* else, if no args, set mode to TRACEUTIL */
    else if (argc == 1) {
        mode = TRACEUTIL;
    }
    /* else, show usage */
    else {
        fprintf(stderr, usage, argv[0]);
        goto done;
    }

    /* reset, load, and start DSP Engine */
    if ((engine = Engine_open(engineName, NULL, NULL)) == NULL) {
        fprintf(stderr, "Error: can't open engine %s!\n", engineName);
        goto done;
    }

    /* setup file descriptor mask for checking for user key input */
    FD_ZERO(&fdMask);
    FD_SET(STDIN_FILENO, &fdMask);

    /* if standard output mode... */
    if (mode == PULLTRACE) {

        printf("Trace polling rate: %d msec\n", rate);
        rate *= 1000;
        printf("DSP trace mask: %s\n", mask);

        /* get server handle */
        server = Engine_getServer(engine);
        if (server == NULL) {
            fprintf(stderr, "Error: can't get server handle!\n");
            goto closeEngine;
        }

        /* connect for server trace data */
        status = Server_connectTrace(server, &traceToken);
        if (status == Server_EINUSE) {
            fprintf(stderr,
                "Error: server trace already in use by another process!\n");
            goto closeEngine;
        }
        else if (status != Server_EOK) {
            fprintf(stderr, "Error: server connect failed, status = 0x%x!\n",
                status);
            goto closeEngine;
        }

        /* server trace mask */
        status = Server_setTrace(server, mask);
        if (status != (Int) Engine_EOK) {
            fprintf(stderr, "Error: unable to set trace mask, status = 0x%x!\n",
                status);
            goto closeEngine;
        }

        printf("Hit <Enter> to exit, or, new trace mask and then <Enter>...\n");

        while (finished == FALSE) {

            dumpTrace(server);

            usleep(rate);

            if (checkInput(newTraceMask) == TRUE) {
                if (strlen(newTraceMask) == 0) {
                    finished = TRUE;
                }
                else {
                    printf("setting new trace mask: %s\n", newTraceMask);
                    status = Server_setTrace(server, newTraceMask);
                    if (status != (Int) Engine_EOK) {
                        fprintf(stderr,
                           "Error updating trace mask, status = 0x%x!\n",
                           status);
                    }
                }
            }
        };

        /* discconnect from server trace data */
        status = Server_disconnectTrace(server, traceToken);
        if (status != Server_EOK) {
            fprintf(stderr,
              "Error: unable to disconnect from server trace, status = 0x%x!\n",
                status);
        }
    }

    /* else, startup TraceUtil to retrieve trace/LOG data and write to files */
    else {

        TraceUtil_start(engineName);

        printf("Started TraceUtil thread\nHit <Enter> to exit...\n");

        getchar();

        TraceUtil_stop();
    }

    printf("Done.\n");

closeEngine:

    /* close the engine */
    if (engine) {
        Engine_close(engine);
    }

done:
    return (0);
}