Skip to content

TinyBench Design Notes

Design Motivation

On embedded SHM nodes, data and algorithm modules are scattered across different functions and global variables. External Agents or users cannot discover at runtime:

  • What data is currently available? Where are the acquisition results stored?
  • What tools are available? What are the inputs and outputs of each tool?

TinyBench solves this — it is a runtime queryable named registry that maps memory addresses to names, making the invisible discoverable.

Core Design Decisions

Zero-Copy

tiny_bench_put() stores only a data pointer, not a copy of the data. The caller is responsible for managing the data's lifetime. This is critical for embedded systems — avoiding redundant copies along every acquisition → processing → analysis path.

Static Allocation

All tables are zeroed at tiny_bench_init() with zero heap allocation at runtime. Configuration macros (TINY_BENCH_MAX_DATA, etc.) determine table capacity and are fixed at compile time.

Type Safety

Every data slot and tool carries a tiny_type_t type tag. TinyOrch performs type validation at step() definition time (src.type == tool.in_type), exposing errors before execution.

Data Slots vs Tool Registry

Data Slots Tool Registry
Manages Data in process Callable processing functions
Lifecycle Dynamic (put / remove) Static (registered at init)
Query list_data() list_tools(), tool_info()
MQTT BENCH,DATA BENCH,TOOLS, BENCH,TOOL,name

Typical Usage Patterns

1. Initialization + Registration

Register all tools at system startup; these remain unchanged during subsequent operation:

tiny_bench_t bench;
tiny_bench_init(&bench);

tiny_bench_register_tool(&bench, "butterworth", fn_bw,
    TINY_TYPE_F32_ARR, TINY_TYPE_F32_ARR);
tiny_bench_register_tool(&bench, "fft", fn_fft,
    TINY_TYPE_F32_ARR, TINY_TYPE_CF32_ARR);

2. Runtime Data Flow

Acquisition tasks place data onto the bench; the flow engine reads and processes it:

// Acquisition thread
tiny_bench_put(&bench, "raw_0", adxl_buffer, N * sizeof(float), TINY_TYPE_F32_ARR);

// Flow execution
void *data; size_t len; tiny_type_t type;
tiny_bench_get(&bench, "raw_0", &data, &len, &type);
// → obtains adxl_buffer pointer, zero-copy

3. Agent Remote Query

→ /mqtt/server: BENCH,TOOLS
← /mqtt/node:   BENCH,TOOLS,4,butterworth:f32[]→f32[],fft:...

The Agent first queries which tools and data are available, then decides which workflow to orchestrate.

Design Constraints

  • Name length: TINY_BENCH_NAME_LEN (default 24), including \0
  • Table full rejection: Returns ERR_FULL when data slots or tool count exceeds limits; no silent dropping
  • Thread safety: Current version does not include built-in locks. Single-task scenarios (MQTT callback + acquisition tasks via message queue) do not require locks
  • No persistence: The bench is purely runtime; data must be re-put and tools re-registered after restart