{ "$schema": "../../../tools/card-layouts/schemas/card-source.schema.json", "schema": "esc-card-source.v1", "card": { "id": "mpabi-freertos-c-09-event-groups", "series": "freertos-c", "series_title": "FreeRTOS C", "number": "09", "count": "15", "slug": "event-groups", "title": "Event Groups: ALL-ready i bariera", "topic": "bit masks, wait semantics, automatic clear i xEventGroupSync", "project": "Freestanding C nad FreeRTOS", "subject": "Informatyka", "level": "Rok 2 · L09 · RV32I/Hazard3", "revision_date": "2026-07-19T00:00:00+02:00", "status": "Gotowa", "version": "v00.01", "uuid": "e5c4c0f3-3dd0-5168-9945-14d48744ec6f", "author": "M. Pabiszczak", "year": "2026" }, "generated": { "tex": "doc/generated/main.tex", "html": "web/index.html", "html_css": "web/style.css", "html_tree_inspector": false, "react_app": true }, "render_dictionary": false, "viewpoints": [ { "id": "A1", "label": "CONTEXT", "subtitle": "Granice", "status": "unavailable", "reason": "Bez nowej granicy sprzętowej lub callbacku." }, { "id": "A2", "label": "STRUCTURE", "subtitle": "EventGroup, masks i participants", "status": "enabled", "target_label": "fig:a2-structure" }, { "id": "A3", "label": "DISPATCH", "subtitle": "Binding", "status": "unavailable", "reason": "Task-context EventGroup nie wprowadza callbacku." }, { "id": "A4", "label": "APPLICATION", "subtitle": "Coordinator, A, B, verifier", "status": "enabled", "target_label": "fig:a4-application" }, { "id": "A5", "label": "FLOW", "subtitle": "E01–E11", "status": "enabled", "target_label": "fig:a5-flow" }, { "id": "A6", "label": "STATE", "subtitle": "Bit value i blocked tasks", "status": "enabled", "target_label": "fig:a6-state" }, { "id": "A7", "label": "RUNTIME", "subtitle": "Handle, wait lists, stacks, digest", "status": "enabled", "target_label": "fig:a7-runtime" }, { "id": "A8", "label": "PATTERNS", "subtitle": "ANY, ALL, clear i barrier", "status": "enabled", "target_label": "fig:a8-patterns" } ], "debug_strategies": { "code.protocol": { "id": "code.protocol", "kind": "code", "action": "open", "expected_observations": [ "disjoint low-bit masks", "finite waits" ], "assertions": [ "READY_ALL=0x03", "SYNC_ALL=0x70" ], "evidence_fields": [ "mask", "API", "code_ref" ], "prerequisites": [ "źródło FC09" ], "layout": [ "mask table", "EventGroupExperiment", "kernel config" ], "commands": [ "rg -n 'READY_|SYNC_|xEventGroup' include src" ] }, "run.ready": { "id": "run.ready", "kind": "run", "action": "replay", "expected_observations": [ "partial=0x11", "A Blocked", "coordinator still Blocked" ], "assertions": [ "ALL not satisfied by READY_A", "reserved bits unused" ], "evidence_fields": [ "bits", "state", "PC", "SP", "timestamp" ], "prerequisites": [ "clean Hazard3 RAM" ], "layout": [ "group bits", "coordinator/A states", "event log" ], "commands": [ "print g_fc09.partial_bits", "print g_fc09.worker_a_state_at_partial" ] }, "run.barrier": { "id": "run.barrier", "kind": "run", "action": "replay", "expected_observations": [ "all contain 0x70", "final=0" ], "assertions": [ "each participant syncs once", "auto clear" ], "evidence_fields": [ "result masks", "final bits", "order" ], "prerequisites": [ "READY_ALL consumed" ], "layout": [ "three sync results", "final group bits" ], "commands": [ "print/x g_fc09.sync_a_result", "print/x g_fc09.sync_b_result", "print/x g_fc09.sync_c_result" ] }, "run.pass": { "id": "run.pass", "kind": "run", "action": "replay", "expected_observations": [ "PASS=1", "11 committed records" ], "assertions": [ "three-run deterministic", "distinct stacks" ], "evidence_fields": [ "PASS", "digest", "hashes", "timestamp" ], "prerequisites": [ "all participants done" ], "layout": [ "PASS", "bounded log", "digest" ], "commands": [ "print g_fc09_pass", "print g_fc09.evidence_digest" ] } }, "template": "templates/karta-klasyczna.json", "title_block": { "category": "KARTA PRACY · INFORMATYKA", "prepared_by": "M. Pabiszczak", "prepared_on": "2026-07-19T00:00:00+02:00", "title": "Event Groups: ALL-ready i bariera", "url": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/3f4c1b8b-d54b-58d5-b92d-87a7233cbd9f", "repository_url": "https://zsl-gitea.mpabi.pl/edu-freertos-c/lab-rv32i-freertos-c-event-groups", "url_host_uuid": "dce7fb9d-7b2f-5d49-96a2-3a30d3070b84", "url_domain": "mpabi.pl", "doc_uuid": "3f4c1b8b-d54b-58d5-b92d-87a7233cbd9f", "revision": "v00.01", "issued_on": "2026-07-19T00:00:00+02:00", "series": "FREERTOS-C-09", "document_type": "karta pracy", "tool": "card-layouts", "show_qr": true, "show_repository_qr": true, "height_cm": 2.6, "repeat_on_every_page": true, "replace_front_matter": true }, "front_page_scope": { "title": "Cel karty", "content_tex": "Uczeń projektuje rozłączne maski EventGroup i dowodzi różnicy między oczekiwaniem ALL a trzyosobową barierą.", "scope_title": "Zakres karty", "scope_content_tex": "Koordynator p3 blokuje się na READY_ALL. Worker A ustawia READY_A i blokuje się w xEventGroupSync. Worker B potwierdza maskę częściową, ustawia READY_B, po czym koordynator wnosi SYNC_C. Ostatni SYNC_B zwalnia wszystkich; każdy wynik zawiera 0x70, a automatycznie wyczyszczona grupa kończy z 0.", "scope_table": { "headers": [ "Lekcja", "Task", "Najważniejsza idea", "Priorytet", "Status", "Version" ], "rows": [ { "chapter": "FC09", "task": "Task01", "idea_tex": "bit masks, wait semantics, automatic clear i xEventGroupSync", "priority": "główny", "status": "ready", "version": "v00.01", "key": true } ] } }, "side_margin_tree_layout": { "columns": [ { "id": "zawodowe", "label": "TECH", "side": "left", "tree": "WE -> EK -> KW", "description": "Dowody runtime." }, { "id": "ogolne", "label": "OG", "side": "right", "tree": "WE -> EN -> KW", "description": "Model FreeRTOS C." } ] }, "learning_effects": { "FC09.EN01": { "bloom_level": "Analiza", "label": "Model bit protocol", "text": "Uczeń przypisuje właściciela i znaczenie każdemu bitowi oraz rozdziela wait ALL od barrier sync.", "assessment_criteria": [ "FC09.KW01" ] }, "FC09.EK01": { "bloom_level": "Zastosowanie", "label": "Replay E01–E11", "text": "Uczeń pokazuje maskę częściową, dwa Blocked states, trzy wyniki 0x70, final zero, trzy SP i digest.", "assessment_criteria": [ "FC09.KW01" ] } }, "assessment_criteria": { "FC09.KW01": { "text": "PASS; partial=0x11; READY result contains 0x03; all SYNC results contain 0x70; final=0; deterministic digest.", "learning_effects": [ "FC09.EN01", "FC09.EK01" ] } }, "educational_requirements": { "FC09.WE01": { "text": "Zaprojektowanie i zbadanie wielozdarzeniowej synchronizacji FreeRTOS.", "label": "bit masks, wait semantics, automatic clear i xEventGroupSync", "learning_effects": [ "FC09.EN01", "FC09.EK01" ], "learning_tree": { "schema": "we-learning-tree.v1", "policy": "Każda aktywna kotwica wskazuje kod lub checkpoint.", "ogolne": [ { "effect_ref": "FC09.EN01", "display": "EN LOCAL RTOS.09", "source": "LOCAL", "official": "RTOS", "local": "09", "kind": "EN", "tree_id": "FC09.WE01.OG.LOCAL.RTOS.09", "text": "Uczeń przypisuje właściciela i znaczenie każdemu bitowi oraz rozdziela wait ALL od barrier sync.", "kw": [ { "criterion_ref": "FC09.KW01", "display": "KW LOCAL RTOS.09", "source": "LOCAL", "kind": "KW", "official": "RTOS", "local": "09", "text": "Łączy kod, diagram i zweryfikowany dowód." } ] } ], "zawodowe": [ { "effect_ref": "FC09.EK01", "display": "EK LOCAL RTOS.09", "source": "LOCAL", "official": "RTOS", "local": "09", "kind": "EK", "tree_id": "FC09.WE01.TECH.LOCAL.RTOS.09", "text": "Uczeń pokazuje maskę częściową, dwa Blocked states, trzy wyniki 0x70, final zero, trzy SP i digest.", "kw": [ { "criterion_ref": "FC09.KW01", "display": "KW LOCAL RTOS.09", "source": "LOCAL", "kind": "KW", "official": "RTOS", "local": "09", "text": "Łączy kod, diagram i zweryfikowany dowód." } ] } ] } } }, "debug_checkpoints": { "schema": "stem-debug-checkpoints.v1", "semantics": "deterministic-replay", "artifact": { "source": "src/tasks/task01_event_groups.c", "source_git_blob": "a3902fd6f17b5d9e9c4fbda5a62f4aca74a7a379", "elf": "build/task01_event_groups/prog.elf", "hazard3_elf_sha256": "9b19890d7a1f58ffea884a948ddb6c5486fec898cca7a9c13edbb645acfd15e7", "hazard3_image": "build/task01_event_groups/prog.bin", "hazard3_image_sha256": "3571ca16c4139e38f9bae5c4db00f9e8595497ceb0d4537e84d08745fd1e2529" }, "targets": { "hazard3-sim": { "adapter": "hazard3-reset-load-replay.v1", "baseline": "restart-backend", "clean_ram": true } }, "items": { "task01.config": { "event_id": "E01", "stop": { "symbol": "fc09_checkpoint_committed", "offset": 0, "condition": "$a0 == 1" }, "verify": { "expressions": [ { "expr": "g_fc09_event_count", "equals": 1 }, { "expr": "g_fc09.group != 0", "equals": 1 } ] } }, "task01.coordinator-wait": { "event_id": "E02", "stop": { "symbol": "fc09_checkpoint_committed", "offset": 0, "condition": "$a0 == 2" }, "verify": { "expressions": [ { "expr": "g_fc09.coordinator_sp != 0", "equals": 1 } ] } }, "task01.ready-a": { "event_id": "E03", "stop": { "symbol": "fc09_checkpoint_committed", "offset": 0, "condition": "$a0 == 3" }, "verify": { "expressions": [ { "expr": "g_fc09_events[2].value", "equals": 1 } ] } }, "task01.sync-a": { "event_id": "E04", "stop": { "symbol": "fc09_checkpoint_committed", "offset": 0, "condition": "$a0 == 4" }, "verify": { "expressions": [ { "expr": "g_fc09_events[3].value", "equals": 16 } ] } }, "task01.partial": { "event_id": "E05", "stop": { "symbol": "fc09_checkpoint_committed", "offset": 0, "condition": "$a0 == 5" }, "verify": { "expressions": [ { "expr": "g_fc09.partial_bits", "equals": 17 }, { "expr": "g_fc09.worker_a_state_at_partial", "equals": 2 } ] } }, "task01.ready-all": { "event_id": "E06", "stop": { "symbol": "fc09_checkpoint_committed", "offset": 0, "condition": "$a0 == 6" }, "verify": { "expressions": [ { "expr": "g_fc09.ready_result & 3", "equals": 3 } ] } }, "task01.before-final": { "event_id": "E07", "stop": { "symbol": "fc09_checkpoint_committed", "offset": 0, "condition": "$a0 == 7" }, "verify": { "expressions": [ { "expr": "g_fc09.coordinator_state_before_final_sync", "equals": 2 } ] } }, "task01.coordinator-release": { "event_id": "E08", "stop": { "symbol": "fc09_checkpoint_committed", "offset": 0, "condition": "$a0 == 8" }, "verify": { "expressions": [ { "expr": "g_fc09.sync_c_result & 112", "equals": 112 } ] } }, "task01.a-release": { "event_id": "E09", "stop": { "symbol": "fc09_checkpoint_committed", "offset": 0, "condition": "$a0 == 9" }, "verify": { "expressions": [ { "expr": "g_fc09.sync_a_result & 112", "equals": 112 } ] } }, "task01.b-release": { "event_id": "E10", "stop": { "symbol": "fc09_checkpoint_committed", "offset": 0, "condition": "$a0 == 10" }, "verify": { "expressions": [ { "expr": "g_fc09.sync_b_result & 112", "equals": 112 } ] } }, "task01.pass": { "event_id": "E11", "stop": { "symbol": "fc09_checkpoint_committed", "offset": 0, "condition": "$a0 == 11" }, "verify": { "expressions": [ { "expr": "g_fc09_pass", "equals": 1 }, { "expr": "g_fc09.final_bits", "equals": 0 }, { "expr": "g_fc09_event_count", "equals": 11 } ] } } } }, "sections": [ { "title": "A2 — Structure", "order": 20, "content_kind": "prose", "asset_page_mode": "one-per-page", "page_orientation": "landscape", "content_tex": "EventBits_t jest wspólną wartością bitową. Znaczenie każdego bitu wynika wyłącznie z jawnego kontraktu aplikacji.", "assets": [ { "path": "assets/a2-structure.png", "html_path": "assets/a2-structure.svg", "source_path": "assets/a2-structure.puml", "caption": "A2 STRUCTURE — READY and SYNC masks.", "label": "fig:a2-structure", "alt": "Struktura EventGroup.", "kind": "diagram", "width": 1.0, "page_grid": { "columns": 1, "rows": 1, "page_width": 940, "page_height": 560, "overview": true, "step_tiles": { "group": 1, "ready": 1, "sync": 1, "coordinator": 1, "a": 1, "b": 1 } }, "interactive": { "kind": "uml-class", "storage_key": "fc09-a2-structure", "title": "A2 · masks and participants", "task": { "id": "task01", "label": "Task01 · EventGroup" }, "block": { "id": "a2", "label": "A2 STRUCTURE", "description": "One group, two disjoint protocols and three participants." }, "phases": [ { "id": "structure", "label": "GROUP / MASKS / PARTICIPANTS", "steps": [ { "id": "group", "number": 1, "label": "one real EventGroup", "mode": "CODE", "strategy_ref": "code.protocol", "svg_label": "01", "code_ref": "src/tasks/task01_event_groups.c:261", "description": "Kernel object holds bits and wait lists.", "evidence": "xEventGroupCreate symbol." }, { "id": "ready", "number": 2, "label": "READY bits are disjoint", "mode": "CODE", "strategy_ref": "code.protocol", "svg_label": "02", "code_ref": "include/task01_event_groups.h:11", "description": "A and B own one bit each.", "evidence": "ALL=0x03." }, { "id": "sync", "number": 3, "label": "SYNC is a separate mask", "mode": "CODE", "strategy_ref": "code.protocol", "svg_label": "03", "code_ref": "include/task01_event_groups.h:14", "description": "Barrier cannot consume readiness meaning.", "evidence": "ALL=0x70." }, { "id": "coordinator", "number": 4, "label": "coordinator waits ALL", "mode": "RUN", "event_id": "E02", "strategy_ref": "run.ready", "svg_label": "04", "code_ref": "src/tasks/task01_event_groups.c:97", "snapshot_ref": "task01.coordinator-wait", "description": "Partial READY cannot release p3.", "evidence": "Blocked path." }, { "id": "a", "number": 5, "label": "worker A owns READY_A/SYNC_A", "mode": "RUN", "event_id": "E04", "strategy_ref": "run.ready", "svg_label": "05", "code_ref": "src/tasks/task01_event_groups.c:140", "snapshot_ref": "task01.sync-a", "description": "A blocks at barrier.", "evidence": "partial mask follows." }, { "id": "b", "number": 6, "label": "worker B contributes final bits", "mode": "RUN", "event_id": "E10", "strategy_ref": "run.barrier", "svg_label": "06", "code_ref": "src/tasks/task01_event_groups.c:183", "snapshot_ref": "task01.b-release", "description": "B completes READY then SYNC.", "evidence": "returns 0x70." } ] } ] } } ] }, { "title": "A4 — Application", "order": 30, "content_kind": "prose", "asset_page_mode": "one-per-page", "page_orientation": "portrait", "content_tex": "Koordynator blokuje się pierwszy, worker A drugi, a worker B może obserwować oba wait conditions przed ustawieniem brakujących bitów.", "assets": [ { "path": "assets/a4-application.png", "html_path": "assets/a4-application.svg", "source_path": "assets/a4-application.puml", "caption": "A4 APPLICATION — deterministic release topology.", "label": "fig:a4-application", "alt": "Topologia trzech tasków i verifiera.", "kind": "diagram", "width": 1.0, "page_grid": { "columns": 1, "rows": 1, "page_width": 660, "page_height": 760, "overview": true, "step_tiles": { "c": 1, "a": 1, "b": 1, "cp": 1, "bf": 1, "v": 1 } }, "interactive": { "kind": "uml-class", "storage_key": "fc09-a4-application", "title": "A4 · participant topology", "task": { "id": "task01", "label": "Task01 · EventGroup" }, "block": { "id": "a4", "label": "A4 APPLICATION", "description": "Priorities create a deterministic observation order." }, "phases": [ { "id": "topology", "label": "BLOCK / SET / PREEMPT / VERIFY", "steps": [ { "id": "c", "number": 1, "label": "coordinator blocks first", "mode": "RUN", "event_id": "E02", "strategy_ref": "run.ready", "svg_label": "01", "code_ref": "src/tasks/task01_event_groups.c:96", "snapshot_ref": "task01.coordinator-wait", "description": "Priority 3.", "evidence": "coordinator stack." }, { "id": "a", "number": 2, "label": "A publishes partial protocols", "mode": "RUN", "event_id": "E04", "strategy_ref": "run.ready", "svg_label": "02", "code_ref": "src/tasks/task01_event_groups.c:145", "snapshot_ref": "task01.sync-a", "description": "Priority 2 then block.", "evidence": "READY_A and SYNC_A." }, { "id": "b", "number": 3, "label": "B observes two blocked tasks", "mode": "RUN", "event_id": "E05", "strategy_ref": "run.ready", "svg_label": "03", "code_ref": "src/tasks/task01_event_groups.c:175", "snapshot_ref": "task01.partial", "description": "No timing guess is needed.", "evidence": "0x11 and eBlocked." }, { "id": "cp", "number": 4, "label": "coordinator preempts on READY_ALL", "mode": "RUN", "event_id": "E06", "strategy_ref": "run.ready", "svg_label": "04", "code_ref": "src/tasks/task01_event_groups.c:107", "snapshot_ref": "task01.ready-all", "description": "Higher p3 consumes READY epoch.", "evidence": "ready_result contains 0x03." }, { "id": "bf", "number": 5, "label": "B sets the final barrier bit", "mode": "RUN", "event_id": "E10", "strategy_ref": "run.barrier", "svg_label": "05", "code_ref": "src/tasks/task01_event_groups.c:190", "snapshot_ref": "task01.b-release", "description": "All three waiters return.", "evidence": "SYNC_ALL." }, { "id": "v", "number": 6, "label": "p0 verifier observes final zero", "mode": "RUN", "event_id": "E11", "strategy_ref": "run.pass", "svg_label": "06", "code_ref": "src/tasks/task01_event_groups.c:230", "snapshot_ref": "task01.pass", "description": "Auto-clear is part of acceptance.", "evidence": "PASS and digest." } ] } ] } } ] }, { "title": "A5 — Flow", "order": 40, "content_kind": "prose", "asset_page_mode": "one-per-page", "page_orientation": "landscape", "content_tex": "SetBits może uruchomić wyższy task przed powrotem callera. Diagram pokazuje logiczny porządek, nie gwarantowaną kolejność równorzędnych waiterów.", "assets": [ { "path": "assets/a5-flow.png", "html_path": "assets/a5-flow.svg", "source_path": "assets/a5-flow.puml", "caption": "A5 FLOW — ALL-ready followed by xEventGroupSync.", "label": "fig:a5-flow", "alt": "Sekwencja EventGroup.", "kind": "diagram", "width": 1.0, "page_grid": { "columns": 1, "rows": 1, "page_width": 940, "page_height": 560, "overview": true, "step_tiles": { "config": 1, "wait": 1, "seta": 1, "synca": 1, "partial": 1, "ready": 1, "before": 1, "c": 1, "a": 1, "b": 1, "pass": 1 } }, "interactive": { "kind": "uml-sequence", "storage_key": "fc09-a5-flow", "title": "A5 · ready and barrier flow", "task": { "id": "task01", "label": "Task01 · EventGroup" }, "block": { "id": "a5", "label": "A5 FLOW", "description": "Complete E01–E11 protocol flow." }, "phases": [ { "id": "flow", "label": "READY ALL / BARRIER / CLEAR", "steps": [ { "id": "config", "number": 1, "label": "group starts at zero", "mode": "RUN", "event_id": "E01", "strategy_ref": "run.ready", "svg_label": "01", "code_ref": "src/tasks/task01_event_groups.c:266", "snapshot_ref": "task01.config", "description": "Clean RAM.", "evidence": "bits=0." }, { "id": "wait", "number": 2, "label": "coordinator waits ALL", "mode": "RUN", "event_id": "E02", "strategy_ref": "run.ready", "svg_label": "02", "code_ref": "src/tasks/task01_event_groups.c:98", "snapshot_ref": "task01.coordinator-wait", "description": "Finite timeout.", "evidence": "p3 blocks." }, { "id": "seta", "number": 3, "label": "A sets READY_A", "mode": "RUN", "event_id": "E03", "strategy_ref": "run.ready", "svg_label": "03", "code_ref": "src/tasks/task01_event_groups.c:140", "snapshot_ref": "task01.ready-a", "description": "ALL remains false.", "evidence": "bits 0x01." }, { "id": "synca", "number": 4, "label": "A contributes SYNC_A", "mode": "RUN", "event_id": "E04", "strategy_ref": "run.ready", "svg_label": "04", "code_ref": "src/tasks/task01_event_groups.c:146", "snapshot_ref": "task01.sync-a", "description": "A blocks.", "evidence": "next partial=0x11." }, { "id": "partial", "number": 5, "label": "B proves partial state", "mode": "RUN", "event_id": "E05", "strategy_ref": "run.ready", "svg_label": "05", "code_ref": "src/tasks/task01_event_groups.c:175", "snapshot_ref": "task01.partial", "description": "Neither protocol is complete.", "evidence": "0x11 and A Blocked." }, { "id": "ready", "number": 6, "label": "coordinator receives READY_ALL", "mode": "RUN", "event_id": "E06", "strategy_ref": "run.ready", "svg_label": "06", "code_ref": "src/tasks/task01_event_groups.c:107", "snapshot_ref": "task01.ready-all", "description": "Ready bits clear on exit.", "evidence": "result 0x03." }, { "id": "before", "number": 7, "label": "coordinator waits at barrier", "mode": "RUN", "event_id": "E07", "strategy_ref": "run.barrier", "svg_label": "07", "code_ref": "src/tasks/task01_event_groups.c:184", "snapshot_ref": "task01.before-final", "description": "B sees p3 Blocked.", "evidence": "state eBlocked." }, { "id": "c", "number": 8, "label": "coordinator leaves barrier", "mode": "RUN", "event_id": "E08", "strategy_ref": "run.barrier", "svg_label": "08", "code_ref": "src/tasks/task01_event_groups.c:120", "snapshot_ref": "task01.coordinator-release", "description": "Final B bit released it.", "evidence": "result contains 0x70." }, { "id": "a", "number": 9, "label": "A leaves barrier", "mode": "RUN", "event_id": "E09", "strategy_ref": "run.barrier", "svg_label": "09", "code_ref": "src/tasks/task01_event_groups.c:155", "snapshot_ref": "task01.a-release", "description": "A returns same complete mask.", "evidence": "0x70." }, { "id": "b", "number": 10, "label": "B returns and sync bits clear", "mode": "RUN", "event_id": "E10", "strategy_ref": "run.barrier", "svg_label": "10", "code_ref": "src/tasks/task01_event_groups.c:199", "snapshot_ref": "task01.b-release", "description": "Last contributor also receives full mask.", "evidence": "0x70." }, { "id": "pass", "number": 11, "label": "verifier commits PASS", "mode": "RUN", "event_id": "E11", "strategy_ref": "run.pass", "svg_label": "11", "code_ref": "src/tasks/task01_event_groups.c:230", "snapshot_ref": "task01.pass", "description": "Final group value is zero.", "evidence": "digest 2391788d." } ] } ] } } ] }, { "title": "A6 — State", "order": 50, "content_kind": "prose", "asset_page_mode": "one-per-page", "page_orientation": "portrait", "content_tex": "ALL/ANY and clear-on-exit describe transitions of the shared bit value. They do not count event multiplicity.", "assets": [ { "path": "assets/a6-state.png", "html_path": "assets/a6-state.svg", "source_path": "assets/a6-state.puml", "caption": "A6 STATE — zero, partial, ready and barrier release.", "label": "fig:a6-state", "alt": "Maszyna stanu bitów.", "kind": "diagram", "width": 1.0, "page_grid": { "columns": 1, "rows": 1, "page_width": 660, "page_height": 760, "overview": true, "step_tiles": { "zero": 1, "partial": 1, "all": 1, "barrier": 1 } }, "interactive": { "kind": "uml-class", "storage_key": "fc09-a6-state", "title": "A6 · bit-state machine", "task": { "id": "task01", "label": "Task01 · EventGroup" }, "block": { "id": "a6", "label": "A6 STATE", "description": "The same integer carries two explicit protocols." }, "phases": [ { "id": "state", "label": "ZERO / PARTIAL / COMPLETE / CLEAR", "steps": [ { "id": "zero", "number": 1, "label": "zero initial and final", "mode": "RUN", "event_id": "E01", "strategy_ref": "run.ready", "svg_label": "01", "code_ref": "src/tasks/task01_event_groups.c:261", "snapshot_ref": "task01.config", "description": "No retained epoch.", "evidence": "0x00." }, { "id": "partial", "number": 3, "label": "READY_A is insufficient", "mode": "RUN", "event_id": "E05", "strategy_ref": "run.ready", "svg_label": "03", "code_ref": "src/tasks/task01_event_groups.c:175", "snapshot_ref": "task01.partial", "description": "Both waiters remain blocked.", "evidence": "0x11." }, { "id": "all", "number": 6, "label": "READY_ALL releases and clears", "mode": "RUN", "event_id": "E06", "strategy_ref": "run.ready", "svg_label": "06", "code_ref": "src/tasks/task01_event_groups.c:97", "snapshot_ref": "task01.ready-all", "description": "Return contains pre-clear bits.", "evidence": "0x03." }, { "id": "barrier", "number": 10, "label": "SYNC_ALL releases and auto-clears", "mode": "RUN", "event_id": "E10", "strategy_ref": "run.barrier", "svg_label": "10", "code_ref": "src/tasks/task01_event_groups.c:190", "snapshot_ref": "task01.b-release", "description": "All participants see complete mask.", "evidence": "0x70 then 0." } ] } ] } } ] }, { "title": "A7 — Runtime", "order": 60, "content_kind": "prose", "asset_page_mode": "one-per-page", "page_orientation": "landscape", "content_tex": "Public task states and returned masks are acceptance evidence. Internal wait lists may be inspected in GDB but are not application dependencies.", "assets": [ { "path": "assets/a7-runtime.png", "html_path": "assets/a7-runtime.svg", "source_path": "assets/a7-runtime.puml", "caption": "A7 RUNTIME — event value and waiting TCBs.", "label": "fig:a7-runtime", "alt": "Runtime EventGroup.", "kind": "diagram", "width": 1.0, "page_grid": { "columns": 1, "rows": 1, "page_width": 940, "page_height": 560, "overview": true, "step_tiles": { "group": 1, "bits": 1, "c": 1, "a": 1, "b": 1, "log": 1 } }, "interactive": { "kind": "uml-class", "storage_key": "fc09-a7-runtime", "title": "A7 · runtime evidence", "task": { "id": "task01", "label": "Task01 · EventGroup" }, "block": { "id": "a7", "label": "A7 RUNTIME", "description": "One handle, two wait masks, three stacks and one canonical log." }, "phases": [ { "id": "runtime", "label": "GROUP / TCB / STACK / LOG", "steps": [ { "id": "group", "number": 1, "label": "real group handle", "mode": "RUN", "event_id": "E01", "strategy_ref": "run.ready", "svg_label": "01", "code_ref": "src/tasks/task01_event_groups.c:261", "snapshot_ref": "task01.config", "description": "Persistent kernel object.", "evidence": "non-null handle." }, { "id": "bits", "number": 2, "label": "value evolves by API calls", "mode": "RUN", "event_id": "E05", "strategy_ref": "run.ready", "svg_label": "02", "code_ref": "src/tasks/task01_event_groups.c:175", "snapshot_ref": "task01.partial", "description": "No shadow counter.", "evidence": "0x11." }, { "id": "c", "number": 3, "label": "coordinator has distinct stack", "mode": "RUN", "event_id": "E02", "strategy_ref": "run.ready", "svg_label": "03", "code_ref": "src/tasks/task01_event_groups.c:95", "snapshot_ref": "task01.coordinator-wait", "description": "Blocked context preserved.", "evidence": "coordinator_sp." }, { "id": "a", "number": 4, "label": "A waits at barrier", "mode": "RUN", "event_id": "E05", "strategy_ref": "run.ready", "svg_label": "04", "code_ref": "src/tasks/task01_event_groups.c:176", "snapshot_ref": "task01.partial", "description": "Public eBlocked proof.", "evidence": "worker_a_sp." }, { "id": "b", "number": 5, "label": "B provides final bit", "mode": "RUN", "event_id": "E10", "strategy_ref": "run.barrier", "svg_label": "05", "code_ref": "src/tasks/task01_event_groups.c:190", "snapshot_ref": "task01.b-release", "description": "Third stack.", "evidence": "worker_b_sp." }, { "id": "log", "number": 6, "label": "commit-last bounded evidence", "mode": "RUN", "event_id": "E11", "strategy_ref": "run.pass", "svg_label": "06", "code_ref": "src/tasks/task01_event_groups.c:55", "snapshot_ref": "task01.pass", "description": "Exact E01–E11.", "evidence": "digest." } ] } ] } } ] }, { "title": "A8 — Patterns", "order": 70, "content_kind": "prose", "asset_page_mode": "one-per-page", "page_orientation": "landscape", "content_tex": "ANY, ALL, clear-on-exit and xEventGroupSync are distinct contracts. Reusing a bit for incompatible meanings makes the protocol ambiguous.", "assets": [ { "path": "assets/a8-patterns.png", "html_path": "assets/a8-patterns.svg", "source_path": "assets/a8-patterns.puml", "caption": "A8 PATTERNS — ANY, ALL, consume and barrier.", "label": "fig:a8-patterns", "alt": "Wzorce EventGroup.", "kind": "diagram", "width": 1.0, "page_grid": { "columns": 1, "rows": 1, "page_width": 940, "page_height": 560, "overview": true, "step_tiles": { "any": 1, "all": 1, "clear": 1, "sync": 1 } }, "interactive": { "kind": "uml-class", "storage_key": "fc09-a8-patterns", "title": "A8 · event synchronization choices", "task": { "id": "task01", "label": "Task01 · EventGroup" }, "block": { "id": "a8", "label": "A8 PATTERNS", "description": "Choose bit protocol semantics explicitly." }, "phases": [ { "id": "patterns", "label": "ANY / ALL / CLEAR / SYNC", "steps": [ { "id": "any", "number": 1, "label": "ANY releases on first selected bit", "mode": "CODE", "strategy_ref": "code.protocol", "svg_label": "01", "code_ref": "include/task01_event_groups.h:11", "description": "Useful for alternatives.", "evidence": "exercise variant." }, { "id": "all", "number": 2, "label": "ALL joins independent readiness", "mode": "RUN", "event_id": "E06", "strategy_ref": "run.ready", "svg_label": "02", "code_ref": "src/tasks/task01_event_groups.c:98", "snapshot_ref": "task01.ready-all", "description": "FC09 readiness contract.", "evidence": "0x03." }, { "id": "clear", "number": 3, "label": "clear consumes the readiness epoch", "mode": "RUN", "event_id": "E06", "strategy_ref": "run.ready", "svg_label": "03", "code_ref": "src/tasks/task01_event_groups.c:100", "snapshot_ref": "task01.ready-all", "description": "Old readiness is not retained.", "evidence": "final zero." }, { "id": "sync", "number": 4, "label": "sync is a reusable barrier", "mode": "RUN", "event_id": "E10", "strategy_ref": "run.barrier", "svg_label": "04", "code_ref": "src/tasks/task01_event_groups.c:190", "snapshot_ref": "task01.b-release", "description": "Set own bit and wait ALL atomically.", "evidence": "three 0x70 results." } ] } ] } } ] }, { "title": "Task01 — EventGroup", "order": 90, "content_kind": "tasks", "task_refs": [ "task01" ] } ], "tasks": { "task01": { "title": "ALL-ready i trzyosobowa bariera", "uuid": "3f4c1b8b-d54b-58d5-b92d-87a7233cbd9f", "prompt_tex": "Przejdź po A2, A4, A5, A6, A7 i A8. Odtwórz E01–E11 i udowodnij, że maska częściowa nie zwalnia tasków, a bariera zwalnia wszystkich dokładnie raz.", "criterion": "PASS; partial=0x11; READY result contains 0x03; all SYNC results contain 0x70; final=0; deterministic digest.", "conclusion_tex": "EventGroup przechowuje bity stanu protokołu, nie historię zdarzeń. Rozłączne maski i jawne reguły clear są warunkiem poprawnej synchronizacji.", "flow": [ { "kind": "block", "id": "predict", "title": "A — mask table", "content_tex": "Przypisz READY i SYNC do właścicieli.", "steps": [ { "id": "partial", "title": "Przewidź 0x11.", "content_tex": "Wskaż, które taski muszą być Blocked." }, { "id": "clear", "title": "Przewidź final zero.", "content_tex": "Rozdziel clear-on-exit od barrier auto-clear." } ] }, { "kind": "block", "id": "replay", "title": "B — replay Hazard3", "content_tex": "RUN zaczyna się od czystej RAM.", "steps": [ { "id": "ready", "title": "Zbadaj E02–E06.", "content_tex": "Porównaj maski i task states." }, { "id": "barrier", "title": "Zbadaj E07–E10.", "content_tex": "Porównaj trzy wartości zwrotne." }, { "id": "pass", "title": "Zbadaj E11.", "content_tex": "Zapisz final bits, SP, PASS i digest." } ] }, { "kind": "exercise", "id": "any-all", "title": "Ćwiczenie — ANY kontra ALL", "prompt_tex": "Uruchom kontrolowany wariant wait ANY na tej samej sekwencji READY_A/READY_B. Zachowaj osobne maski i porównaj moment release oraz wartość zwrotną.", "evidence_tex": "Dwa timestampowane ślady i tabela semantyki clear-on-exit.", "criterion": "Uczeń nie przypisuje API gwarancji kolejności równorzędnych waiterów.", "based_on": [ "predict", "replay" ] } ], "educational_requirement_refs": [ "FC09.WE01" ], "learning_effect_refs": [ "FC09.EN01", "FC09.EK01" ], "assessment_criterion_ref": "FC09.KW01" } }, "tasks_order": [ "task01" ] }