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); }
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); }
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; }
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); }
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; }
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); }