Software

Tools

A toolchain that lets students watch what their concurrent programs actually do, without rewriting them.

Across every supported environment the wrappers emit one common event schema, and an on-device agent exports it to the visualization backend. Decoupling capture from display lets the same interface serve desktops, microcontrollers, and robots, and supports remote visualization, so instruction can stay on concurrency concepts instead of platform details.

Wrappers and libraries

Engineers observe the real dynamic behavior of their own code without changing its logic or inserting instrumentation by hand. Instrumentation is lightweight and nearly invisible to the learner.

POSIX threads

Instrumented standard APIs on Linux and macOS: mutexes, semaphores, reader–writer locks, spin locks, barriers, and thread lifecycle operations, plus a monitor interface providing Hoare and Mesa semantics. The interface matches the standard API, with an optional naming facility so resources appear in the visualizer as “Worker 1” rather than an address.

FreeRTOS

Many engineering applications run on microcontrollers with no POSIX support. The FreeRTOS wrappers instrument task lifecycle events, mutexes including priority inheritance, binary and counting semaphores, event groups, queue send and receive with blocking and timeouts, explicit delays, and timer callbacks, staying on the user-space API rather than kernel internals.

ROS 2

Concurrency in ROS 2 comes from callback-driven executors rather than explicit threads. Instrumentation targets the executor path in rclcpp and rclpy, capturing callback dispatch, message receipt, timer expiration, service and action invocation, and intra-node communication. Executors and node factories are instrumented, not callback bodies, so user logic and message types are untouched.

Fuzzing

Every library can insert controlled, randomized delays at synchronization points, message boundaries, and callback dispatch sites. Perturbing the schedule exposes alternative interleavings and raises the odds of revealing races and atomicity violations, with no change to program logic.

Bounded overhead

Each wrapper writes into a small fixed-size ring buffer that a lightweight agent drains to the backend over a local socket or network connection. If the backend stalls, the agent spills to a trace file or drops events with explicit markers rather than growing memory, keeping behavior predictable even on microcontrollers.

Validation. Instrumentation preserves causal structure rather than cycle-level timing. Benchmark programs with known characteristics, including intentional races and deadlock-prone configurations, confirm those behaviors still appear under instrumentation; happens-before relationships are checked for preservation; and stress testing on constrained platforms confirms that buffering and export introduce no artificial blocking, priority inversion, or memory exhaustion. The tools are meant for instruction, not profiling or hard real-time deployment, at a scale of tens of threads, tasks, or nodes.

Visualization system

ROS 2, FreeRTOS, and POSIX threads expose different abstractions but produce the same pathologies, because races, deadlocks, and inconsistent snapshots all come from execution contexts interleaving nondeterministically over shared state. The visualizer presents them in one model, as a web-based and desktop-capable interface.

Timeline view

Each thread, callback, ROS node, or FreeRTOS task gets a horizontal timeline. Lock acquisitions, semaphore waits, callback start and completion, and message sends and receives appear as icons or color-coded intervals that can be zoomed, panned, and filtered by category.

Happens-before view

Vector clocks and logical timestamps from the wrappers become directed edges showing message flow, synchronization dependencies, and ordering constraints, which is how learners spot races, misplaced synchronization, and deadlock cycles.

Object-centric view

Views centered on a single semaphore, mutex, monitor, or channel show how one object behaves over time, isolating contention patterns, blocking behavior, and incorrect use of synchronization operations.

Component grouping

For ROS 2 and multi-component embedded systems, timelines group by node or subsystem, with topics, queues, and pipes drawn as edges so timing jitter, queue backlog, and dropped messages become visible.

Replay and exploration

Play, pause, single-step, scrub, or reverse the event sequence. All views stay coordinated on the same event prefix, so switching perspective never loses your place.

Accessible by design

High-contrast, color-blind-safe palettes, redundant cues that pair color with shape and position, scalable text, keyboard navigation for every control, and browser-native zoom, aimed at learners with no computer science background.

The prototype is being tested in CS 3331 Concurrent Computing, a required junior-level course at Michigan Tech. Clicking an event opens the source file and highlights the line that produced it. Current views include Timeline, Resources, Thread Status, Thread Tree, and History, along with relative measures such as per-thread blocking time and average wait per acquisition. A causality view is under development.

CEDL

The Concurrent Event Description Language lets instructors script an exact interleaving instead of hoping a live run reproduces the one they want to teach. An instructor writes straight-line code that states the happens-before relation among a set of events; the compiler and interpreter then generate those events for the visualization system.

A CEDL program is a set of processes or threads, each with its own logical clock. Events are message sends and receives or synchronization operations, naming the protected item and a time appropriate to that thread's context. The resulting visualization mirrors the timeline view used for real programs, and the instructor can step through it or back up mid-demonstration.

Because the schedule lives in the program itself, demonstrations of race conditions and their fixes no longer depend on nondeterministic ordering happening to cooperate during class.

// Thread A          // Thread B
shared A;            shared A;
mutex_lock(lock,2)   mutex_lock(lock,1)
write(A,5)           read(A,3)
mutex_unlock(lock,6) mutex_unlock(lock,4)

A short CEDL program: each operation carries the logical time at which it occurs, so the interleaving is fixed by construction.

Tool deliverables

  1. Thread visualization
  2. Distributed system visualization
  3. Language tools for concurrent animation
  4. Compiler and interpreter support for pattern detection and assertions

All of it targets the operating environments common to cyber-physical systems: pthreads, ROS 2, and FreeRTOS.