wegen/FrOSCon26/drawings/thread-handoff.dot

57 lines
2.3 KiB
Text
Raw Normal View History

// Cross-thread architecture and data-visibility handoff.
// Render: dot -Tsvg thread-handoff.dot -o thread-handoff.svg
//
// One direction of data flow: the Proactor thread reads file blocks into the
// ring of buffers and publishes a ready frame through the single atomic baton
// `toDisplay_`; the GUI thread picks it up, uploads it to the GPU, and hands
// the slot back. The release/acquire pairs on the baton carry buffer-content
// visibility in both directions.
digraph handoff {
rankdir=LR;
bgcolor="transparent";
compound=true;
fontname="sans-serif";
node [fontname="sans-serif", fontsize=11];
edge [fontname="sans-serif", fontsize=10];
file [shape=cylinder, fillcolor="#eeeeee", style=filled, label="demovideo.raw"];
subgraph cluster_proactor {
label=" »Proactor« thread — playVideo() loop ";
labeljust="l";
style="filled,rounded"; fillcolor="#eef4ff"; color="#7092c0"; fontsize=12;
wait [shape=box, style="rounded,filled", fillcolor="#ffffff",
label="io_uring_wait_cqe()\n(blocking)"];
timer [shape=box, style="rounded,filled", fillcolor="#ffedcc",
label="frame-beat timer\n20 ms · multishot"];
ring [shape=record, style=filled, fillcolor="#ffffff",
label="ring buffers\ (RING_SIZ)|<s0>slot|<s1>slot|<s2>slot|<s3>…"];
}
subgraph cluster_gui {
label=" GTK / GUI thread ";
labeljust="l";
style="filled,rounded"; fillcolor="#eefaee"; color="#6bab6b"; fontsize=12;
disp [shape=box, style="rounded,filled", fillcolor="#ffffff",
label="EglDisplay::displayFrame()\nretrieveFrame() / completedFrame()"];
gpu [shape=box, style="rounded,filled", fillcolor="#ffffff",
label="GPU texture\n(glTexImage2D → draw)"];
}
baton [shape=box, style="filled", fillcolor="#e7d8ff", penwidth=1.6,
label="toDisplay_\nstd::atomic<Buffer*>"];
file -> ring [label="io_uring read", lhead=cluster_proactor];
timer -> wait [style=dotted, label="CQE (TICK_TAG)"];
ring -> baton [label="publish\nstore(release)", color="#5a2ca0", fontcolor="#5a2ca0"];
baton -> disp [label="retrieveFrame\nload(acquire)", color="#5a2ca0", fontcolor="#5a2ca0"];
disp -> gpu [label="upload + draw"];
disp -> baton [label="completedFrame\nstore(nullptr, release)",
style=dashed, color="#3a7a3a", fontcolor="#3a7a3a"];
{ rank=same; baton; }
}