Ejemplo n.º 1
0
int harmony_best(hdesc_t *hdesc)
{
    int retval = 0;

    if (hdesc->state >= HARMONY_STATE_CONNECTED) {
        /* Prepare a Harmony message. */
        hmesg_scrub(&hdesc->mesg);

        if (send_request(hdesc, HMESG_BEST) != 0)
            return -1;

        if (hdesc->mesg.status != HMESG_STATUS_OK) {
            hdesc->errstr = "Invalid message received from server.";
            errno = EINVAL;
            return -1;
        }

        if (hdesc->best.id < hdesc->mesg.data.point.id) {
            if (update_best(hdesc, &hdesc->mesg.data.point) != 0)
                return -1;
            retval = 1;
        }
    }

    /* Make sure our best known point is valid. */
    if (hdesc->best.id < 0) {
        errno = EINVAL;
        return -1;
    }

    if (set_values(hdesc, &hdesc->best) != 0)
        return -1;

    return retval;
}
Ejemplo n.º 2
0
int harmony_fetch(hdesc_t *hdesc)
{
    int i;

    if (hdesc->state < HARMONY_STATE_CONNECTED) {
        hdesc->errstr = "Descriptor not currently joined to any session.";
        errno = EINVAL;
        return -1;
    }

    /* Prepare a Harmony message. */
    hmesg_scrub(&hdesc->mesg);

    if (send_request(hdesc, HMESG_FETCH) != 0)
        return -1;

    if (hdesc->mesg.status == HMESG_STATUS_BUSY) {
        if (update_best(hdesc, &hdesc->mesg.data.point) != 0)
            return -1;

        if (hdesc->best.id == -1) {
            /* No best point is available. Inform the user by returning 0. */
            return 0;
        }

        /* Set current point to best point. */
        if (hpoint_copy(&hdesc->curr, &hdesc->best) != 0) {
            hdesc->errstr = "Internal error copying point data.";
            errno = EINVAL;
            return -1;
        }
    }
    else if (hdesc->mesg.status == HMESG_STATUS_OK) {
        if (hpoint_copy(&hdesc->curr, &hdesc->mesg.data.point) != 0) {
            hdesc->errstr = "Internal error copying point data.";
            errno = EINVAL;
            return -1;
        }
    }
    else {
        hdesc->errstr = "Invalid message received from server.";
        errno = EINVAL;
        return -1;
    }

    /* Update the variables from the content of the message. */
    if (set_values(hdesc, &hdesc->curr) != 0)
        return -1;

    /* Initialize our internal performance array. */
    for (i = 0; i < hdesc->perf->n; ++i)
        hdesc->perf->p[i] = NAN;

    /* Client variables were changed.  Inform the user by returning 1. */
    hdesc->state = HARMONY_STATE_TESTING;
    return 1;
}
Ejemplo n.º 3
0
int harmony_report(hdesc_t *hdesc, double *perf)
{
    int i;

    if (hdesc->state < HARMONY_STATE_CONNECTED) {
        hdesc->errstr = "Descriptor not currently joined to any session.";
        errno = EINVAL;
        return -1;
    }

    if (hdesc->state < HARMONY_STATE_TESTING)
        return 0;

    if (perf)
        memcpy(hdesc->perf->p, perf, sizeof(double) * hdesc->perf->n);

    for (i = 0; i < hdesc->perf->n; ++i) {
        if (isnan(hdesc->perf->p[i])) {
            hdesc->errstr = "Error: Performance report incomplete.";
            errno = EINVAL;
            return -1;
        }
    }

    /* Prepare a Harmony message. */
    hmesg_scrub(&hdesc->mesg);
    hdesc->mesg.data.report.cand_id = hdesc->curr.id;
    hdesc->mesg.data.report.perf = hperf_clone(hdesc->perf);
    if (!hdesc->mesg.data.report.perf) {
        hdesc->errstr = "Error allocating performance array for message.";
        return -1;
    }

    if (send_request(hdesc, HMESG_REPORT) != 0)
        return -1;

    if (hdesc->mesg.status != HMESG_STATUS_OK) {
        hdesc->errstr = "Invalid message received from server.";
        errno = EINVAL;
        return -1;
    }

    hdesc->state = HARMONY_STATE_READY;
    return 0;
}
Ejemplo n.º 4
0
char *harmony_setcfg(hdesc_t *hdesc, const char *key, const char *val)
{
    char *buf;
    int retval;

    if (hdesc->state < HARMONY_STATE_CONNECTED) {
        /* User must be preparing for a new session since we're not
         * connected yet.  Store the key/value pair in a local cache.
         */
        buf = stralloc( hcfg_get(hdesc->sess.cfg, key) );
        hcfg_set(hdesc->sess.cfg, key, val);
        return buf;
    }

    if (!key) {
        hdesc->errstr = "Invalid key string.";
        errno = EINVAL;
        return NULL;
    }

    buf = sprintf_alloc("%s=%s", key, val ? val : "");
    if (!buf) {
        hdesc->errstr = "Internal memory allocation error.";
        return NULL;
    }

    /* Prepare a Harmony message. */
    hmesg_scrub(&hdesc->mesg);
    hdesc->mesg.data.string = buf;

    retval = send_request(hdesc, HMESG_SETCFG);
    free(buf);

    if (retval < 0)
        return NULL;

    if (hdesc->mesg.status != HMESG_STATUS_OK) {
        hdesc->errstr = "Invalid message received from server.";
        errno = EINVAL;
        return NULL;
    }

    /* It is the user's responsibility to free this memory. */
    return stralloc(hdesc->mesg.data.string);
}
Ejemplo n.º 5
0
char *harmony_getcfg(hdesc_t *hdesc, const char *key)
{
    if (hdesc->state < HARMONY_STATE_CONNECTED) {
        hdesc->errstr = "Descriptor not currently joined to any session.";
        errno = EINVAL;
        return NULL;
    }

    /* Prepare a Harmony message. */
    hmesg_scrub(&hdesc->mesg);
    hdesc->mesg.data.string = key;

    if (send_request(hdesc, HMESG_GETCFG) != 0)
        return NULL;

    if (hdesc->mesg.status != HMESG_STATUS_OK) {
        hdesc->errstr = "Invalid message received from server.";
        errno = EINVAL;
        return NULL;
    }

    /* It is the user's responsibility to free this memory. */
    return stralloc(hdesc->mesg.data.string);
}
Ejemplo n.º 6
0
int harmony_join(hdesc_t *hdesc, const char *host, int port, const char *name)
{
    int i, perf_len;
    int apply_argv = (hdesc->state < HARMONY_STATE_CONNECTED);
    char *cfgval;

    /* Verify that we have *at least* one variable bound, and that
     * this descriptor isn't already associated with a tuning
     * session.
     */
    if (hdesc->ptr_len == 0) {
        hdesc->errstr = "No variables bound to Harmony session";
        errno = EINVAL;
        return -1;
    }

    if (hdesc->state >= HARMONY_STATE_READY) {
        hdesc->errstr = "Descriptor already joined with an existing session";
        errno = EINVAL;
        return -1;
    }

    if (hdesc->state == HARMONY_STATE_INIT) {
        hdesc->socket = tcp_connect(host, port);
        if (hdesc->socket < 0) {
            hdesc->errstr = "Error establishing TCP connection with server";
            return -1;
        }

        if (hdesc->id == NULL)
            hdesc->id = default_id(hdesc->socket);
        hdesc->state = HARMONY_STATE_CONNECTED;

        hdesc->sess.sig.name = stralloc(name);
        if (!hdesc->sess.sig.name) {
            hdesc->errstr = "Error allocating memory for signature name";
            return -1;
        }
    }

    /* Prepare a Harmony message. */
    hmesg_scrub(&hdesc->mesg);
    hdesc->mesg.data.join = HSIGNATURE_INITIALIZER;
    if (hsignature_copy(&hdesc->mesg.data.join, &hdesc->sess.sig) < 0) {
        hdesc->errstr = "Internal error copying signature data";
        return -1;
    }

    /* send the client registration message */
    if (send_request(hdesc, HMESG_JOIN) != 0)
        return -1;

    if (hdesc->mesg.status != HMESG_STATUS_OK) {
        hdesc->errstr = "Invalid message received";
        errno = EINVAL;
        return -1;
    }

    hsignature_fini(&hdesc->sess.sig);
    if (hsignature_copy(&hdesc->sess.sig, &hdesc->mesg.data.join) < 0) {
        hdesc->errstr = "Error copying received signature structure";
        return -1;
    }

    /* Apply argv configuration directives now, if necessary. */
    if (apply_argv) {
        for (i = 0; i < hdesc->cmd_len; ++i) {
            char *key, *val, *cpy;
            cpy = stralloc(hdesc->cmd[i]);
            if (hcfg_parse(cpy, &key, &val)) {
                /* This should never fail, but just in case. */
                hdesc->errstr = "Error parsing argv config directive.";
                return -1;
            }
            if (hcfg_set(hdesc->sess.cfg, key, val)) {
                hdesc->errstr = "Error applying argv config directive.";
                return -1;
            }
            free(cpy);
        }
    }

    cfgval = harmony_getcfg(hdesc, CFGKEY_PERF_COUNT);
    if (cfgval) {
        perf_len = atoi(cfgval);
        if (perf_len < 1) {
            hdesc->errstr = "Invalid value for " CFGKEY_PERF_COUNT;
            return -1;
        }
        free(cfgval);
    }
    else {
        perf_len = DEFAULT_PERF_COUNT;
    }

    hdesc->perf = hperf_alloc(perf_len);
    if (!hdesc->perf) {
        hdesc->errstr = "Error allocating performance array.";
        return -1;
    }

    hdesc->state = HARMONY_STATE_READY;
    return 0;
}
Ejemplo n.º 7
0
int harmony_launch(hdesc_t *hdesc, const char *host, int port)
{
    int i;

    /* Sanity check input */
    if (hdesc->sess.sig.range_len < 1) {
        hdesc->errstr = "No tuning variables defined";
        errno = EINVAL;
        return -1;
    }

    if (!host && !getenv("HARMONY_S_HOST")) {
        char *path;
        const char *home;

        /* Provide a default name, if one isn't defined. */
        if (!hdesc->sess.sig.name) {
            if (hsignature_name(&hdesc->sess.sig, "NONAME"))
                return -1;
        }

        /* Find the Active Harmony installation. */
        home = getenv("HARMONY_HOME");
        if (!home) {
            hdesc->errstr = "No host or HARMONY_HOME specified";
            return -1;
        }

        if (hcfg_set(hdesc->sess.cfg, CFGKEY_HARMONY_HOME, home) != 0) {
            hdesc->errstr = "Could not set " CFGKEY_HARMONY_HOME;
            return -1;
        }

        /* Fork a local tuning session. */
        path = sprintf_alloc("%s/libexec/session-core", home);
        hdesc->socket = socket_launch(path, NULL, NULL);
        free(path);
    }
    else {
        hdesc->socket = tcp_connect(host, port);
    }

    if (hdesc->socket < 0) {
        hdesc->errstr = strerror(errno);
        return -1;
    }

    /* Prepare a default client id, if necessary. */
    if (hdesc->id == NULL)
        hdesc->id = default_id(hdesc->socket);
    hdesc->state = HARMONY_STATE_CONNECTED;

    /* Apply argv configuration directives now, if necessary. */
    for (i = 0; i < hdesc->cmd_len; ++i) {
        char *key, *val, *cpy;
        cpy = stralloc(hdesc->cmd[i]);
        if (hcfg_parse(cpy, &key, &val) == NULL) {
            /* This should never fail, but just in case. */
            hdesc->errstr = "Internal error parsing argv config directive.";
            return -1;
        }
        if (hcfg_set(hdesc->sess.cfg, key, val) != 0) {
            hdesc->errstr = "Internal error applying argv config directive.";
            return -1;
        }
        free(cpy);
    }

    /* Prepare a Harmony message. */
    hmesg_scrub(&hdesc->mesg);
    hsession_init(&hdesc->mesg.data.session);
    hsession_copy(&hdesc->mesg.data.session, &hdesc->sess);

    return send_request(hdesc, HMESG_SESSION);
}
Ejemplo n.º 8
0
void hmesg_fini(hmesg_t *mesg)
{
    hmesg_scrub(mesg);
    free(mesg->buf);
}