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 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 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 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 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 void startup(void) { const char *algorithm = "sha256"; const char *key = NULL; char **argv = sol_argv(); int i, argc = sol_argc(); size_t chunk_size = -1; if (argc < 2) { fprintf(stderr, "Usage:\n\t%s [-a <algorithm>] [-c chunk_size] [-k key] <file1> .. <fileN>\n", argv[0]); sol_quit_with_code(EXIT_FAILURE); return; } for (i = 1; i < argc; i++) { struct feed_ctx *ctx; struct sol_message_digest_config cfg = { SOL_SET_API_VERSION(.api_version = SOL_MESSAGE_DIGEST_CONFIG_API_VERSION, ) .algorithm = algorithm, .on_feed_done = on_feed_done, .on_digest_ready = on_digest_ready, }; struct sol_file_reader *fr; struct sol_blob *blob; struct sol_message_digest *mdh; int r; if (argv[i][0] == '-') { if (argv[i][1] == 'a') { if (i + 1 < argc) { algorithm = argv[i + 1]; i++; continue; } else fputs("ERROR: argument -a missing value.\n", stderr); } else if (argv[i][1] == 'k') { if (i + 1 < argc) { key = argv[i + 1]; i++; continue; } else fputs("ERROR: argument -a missing value.\n", stderr); } else if (argv[i][1] == 'c') { if (i + 1 < argc) { chunk_size = atoi(argv[i + 1]); i++; continue; } else fputs("ERROR: argument -c missing value.\n", stderr); } else fprintf(stderr, "ERROR: unknown option %s\n", argv[i]); sol_quit_with_code(EXIT_FAILURE); return; } fr = sol_file_reader_open(argv[i]); if (!fr) { fprintf(stderr, "ERROR: could not open file '%s': %s\n", argv[i], sol_util_strerrora(errno)); continue; } blob = sol_file_reader_to_blob(fr); if (!blob) { fprintf(stderr, "ERROR: could not create blob for file '%s'\n", argv[i]); continue; } cfg.data = ctx = calloc(1, sizeof(struct feed_ctx)); if (!ctx) { fprintf(stderr, "ERROR: could not allocate context memory " "to process file '%s'\n", argv[i]); sol_blob_unref(blob); continue; } ctx->file = argv[i]; ctx->start = sol_util_timespec_get_current(); ctx->done = 0; ctx->chunk_size = chunk_size; if (key) cfg.key = sol_str_slice_from_str(key); mdh = sol_message_digest_new(&cfg); if (!mdh) { fprintf(stderr, "ERROR: could not create message digest for " " algorithm \"%s\": %s\n", algorithm, sol_util_strerrora(errno)); sol_blob_unref(blob); free(ctx); continue; } if (chunk_size <= 0) { r = sol_message_digest_feed(mdh, blob, true); if (r < 0) { fprintf(stderr, "ERROR: could not feed message for " " algorithm \"%s\": %s\n", algorithm, sol_util_strerrora(-r)); sol_blob_unref(blob); sol_message_digest_del(mdh); free(ctx); continue; } } else { size_t offset = 0; while (offset < blob->size) { size_t remaining = blob->size - offset; size_t clen = remaining > chunk_size ? chunk_size : remaining; uint8_t *cmem = (uint8_t *)blob->mem + offset; bool is_last = offset + clen == blob->size; struct sol_blob *chunk = sol_blob_new(&SOL_BLOB_TYPE_NO_FREE_DATA, blob, cmem, clen); if (!chunk) { fprintf(stderr, "ERROR: could not create chunk blob at " "mem %p, size=%zd\n", cmem, clen); sol_blob_unref(blob); sol_message_digest_del(mdh); free(ctx); continue; } r = sol_message_digest_feed(mdh, chunk, is_last); if (r < 0) { fprintf(stderr, "ERROR: could not feed chunk for " " algorithm \"%s\": %s\n", algorithm, sol_util_strerrora(-r)); sol_blob_unref(blob); sol_blob_unref(chunk); sol_message_digest_del(mdh); free(ctx); continue; } sol_blob_unref(chunk); offset += clen; } } sol_blob_unref(blob); pending++; }