Пример #1
0
static void
echo_event_cb(void *data, struct sol_gpio *gpio, bool value)
{
    struct hc_sr04_data *mdata = data;
    struct timespec t2, delta;
    int usec, centimeters;

    /* started the pulse */
    if (value != mdata->low) {
        mdata->t1 = sol_util_timespec_get_current();
        return;
    }

    /* pulse ended */
    t2 = sol_util_timespec_get_current();
    sol_util_timespec_sub(&t2, &mdata->t1, &delta);
    usec = sol_util_usec_from_timespec(&delta);
    /* distance = time * velocity (340 m/s) / 2 */
    centimeters = usec / 58;

    mdata->busy = false;

    sol_flow_send_irange_value_packet(mdata->node,
        SOL_FLOW_NODE_TYPE_HC_SR04_DISTANCE__OUT__CENTIMETERS, centimeters);
}
Пример #2
0
static void
inspector_prefix(const char *prefix, const struct sol_flow_node *node)
{
    struct timespec now = sol_util_timespec_get_current();
    struct timespec diff;

    sol_util_timespec_sub(&now, &start, &diff);
    fprintf(stdout, "DEBUG:%ld.%010ld:%s:", diff.tv_sec, diff.tv_nsec, prefix);
    while ((node = sol_flow_node_get_parent(node)) != NULL)
        fputc('~', stdout);
    fputc(' ', stdout);
}
Пример #3
0
static int
child_read(struct sol_blob **p_blob, bool *eof, int fd)
{
    struct sol_buffer buf = SOL_BUFFER_INIT_EMPTY;
    struct timespec start = sol_util_timespec_get_current();
    size_t size;
    void *v;
    int ret = 0;

    *eof = false;
    do {
        struct timespec now = sol_util_timespec_get_current();
        struct timespec elapsed;
        ssize_t r;

        sol_util_timespec_sub(&now, &start, &elapsed);
        if (elapsed.tv_sec > 0 ||
            elapsed.tv_nsec > (time_t)CHUNK_MAX_TIME_NS)
            break;

        r = sol_util_fill_buffer(fd, &buf, CHUNK_READ_SIZE);
        if (r == 0) {
            *eof = true;
            break;
        } else if (r < 0) {
            /* Not a problem if failed because buffer could not be increased */
            if (r != -ENOMEM)
                ret = -errno;
            break;
        }
    } while (1);

    if (ret < 0 && ret != -EAGAIN) {
        sol_buffer_fini(&buf);
        return ret;
    }

    v = sol_buffer_steal(&buf, &size);
    *p_blob = sol_blob_new(&SOL_BLOB_TYPE_DEFAULT, NULL, v, size);
    SOL_NULL_CHECK_GOTO(*p_blob, blob_error);
    return 0;

blob_error:
    sol_buffer_fini(&buf);
    return -ENOMEM;
}
Пример #4
0
static void
print_time(const struct feed_ctx *ctx, size_t amount, const char *prefix)
{
    struct timespec now = sol_util_timespec_get_current();
    struct timespec elapsed;
    double size, rate, seconds;
    const char *s_unit, *r_unit;

    sol_util_timespec_sub(&now, &ctx->start, &elapsed);
    seconds = elapsed.tv_sec + (double)elapsed.tv_nsec / SOL_UTIL_NSEC_PER_SEC;

    size = amount;
    if (size >= 1.0e9) {
        s_unit = "Gb";
        size /= 1.0e9;
    } else if (size > 1.0e6) {
        s_unit = "Mb";
        size /= 1.0e6;
    } else if (size > 1.0e3) {
        s_unit = "Kb";
        size /= 1.0e3;
    } else {
        s_unit = "b";
    }

    rate = amount / seconds;
    if (rate >= 1.0e9) {
        r_unit = "Gb";
        rate /= 1.0e9;
    } else if (rate > 1.0e6) {
        r_unit = "Mb";
        rate /= 1.0e6;
    } else if (rate > 1.0e3) {
        r_unit = "Kb";
        rate /= 1.0e3;
    } else {
        r_unit = "b";
    }

    printf("%s chunk{#%" PRIu32 ", %zdb] %0.1f%s done in %0.3fseconds: %0.1f%s/s\n",
        prefix, ctx->idx, ctx->chunk_size, size, s_unit, seconds, rate, r_unit);
}
Пример #5
0
static int
out_write(struct subprocess_data *mdata)
{
    int ret = 0;
    struct timespec start = sol_util_timespec_get_current();

    while (mdata->write_data.len) {
        struct timespec now = sol_util_timespec_get_current();
        struct timespec elapsed;
        struct write_data *w = sol_vector_get(&mdata->write_data, 0);
        ssize_t r;

        sol_util_timespec_sub(&now, &start, &elapsed);
        if (elapsed.tv_sec > 0 ||
            elapsed.tv_nsec > (time_t)CHUNK_MAX_TIME_NS)
            break;

        r = write(mdata->pipes.out[1], (uint8_t *)w->blob->mem + w->offset, w->blob->size - w->offset);
        if (r > 0) {
            w->offset += r;
        } else if (r < 0) {
            if (errno == EINTR)
                continue;
            else if (errno == EAGAIN)
                break;
            else {
                ret = -errno;
                break;
            }
        }

        if (w->blob->size <= w->offset) {
            sol_blob_unref(w->blob);
            sol_vector_del(&mdata->write_data, 0);
        }
    }

    return ret;
}
Пример #6
0
static int
delta_process(struct sol_flow_node *node, void *data, uint16_t port, uint16_t conn_id, const struct sol_flow_packet *packet)
{
    struct timestamp_comparison_data *mdata = data;
    struct timespec sub_result;
    time_t result;
    int r;
    int32_t output;

    if (!two_vars_get_value(mdata, port, packet))
        return 0;

    result = mdata->val[1].tv_sec - mdata->val[0].tv_sec;
    if (result > INT32_MAX) {
        sol_flow_send_error_packet(node, ERANGE,
            "Delta is too big for seconds: %s", sol_util_strerrora(ERANGE));
        return 0;
    }
    output = result;

    r = sol_flow_send_irange_value_packet(node,
        SOL_FLOW_NODE_TYPE_TIMESTAMP_DELTA__OUT__SECONDS, output);
    SOL_INT_CHECK(r, < 0, r);

    sol_util_timespec_sub(&mdata->val[0], &mdata->val[1], &sub_result);
    result = sub_result.tv_sec * NSEC_PER_SEC + sub_result.tv_nsec;

    if (result > INT32_MAX) {
        SOL_DBG("Delta is too big for nanoseconds: %s",
            sol_util_strerrora(ERANGE));
        return 0;
    }
    output = result;

    return sol_flow_send_irange_value_packet(node,
        SOL_FLOW_NODE_TYPE_TIMESTAMP_DELTA__OUT__NANO_SECONDS, output);
}