1461 lines
48 KiB
JSON
1461 lines
48 KiB
JSON
{
|
||
"$schema": "../../../tools/card-layouts/schemas/card-source.schema.json",
|
||
"schema": "esc-card-source.v1",
|
||
"card": {
|
||
"id": "mpabi-freertos-c-08-mutex-priority-inheritance",
|
||
"series": "freertos-c",
|
||
"series_title": "FreeRTOS C",
|
||
"number": "08",
|
||
"count": "15",
|
||
"slug": "mutex-priority-inheritance",
|
||
"title": "Mutex i dziedziczenie priorytetu",
|
||
"topic": "ownership, bounded inversion i priority inheritance",
|
||
"project": "Freestanding C nad FreeRTOS",
|
||
"subject": "Informatyka",
|
||
"level": "Rok 2 · L08 · RV32I/Hazard3",
|
||
"revision_date": "2026-07-19T00:00:00+02:00",
|
||
"status": "Gotowa",
|
||
"version": "v00.01",
|
||
"uuid": "b408a0e1-ca9f-52b8-9075-ff324bfce778",
|
||
"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 systemu",
|
||
"status": "unavailable",
|
||
"reason": "Granica aplikacja–kernel–Hazard3 jest utrwalona w FC07."
|
||
},
|
||
{
|
||
"id": "A2",
|
||
"label": "STRUCTURE",
|
||
"subtitle": "Mutex, owner, wait list i zasób",
|
||
"status": "enabled",
|
||
"target_label": "fig:a2-structure"
|
||
},
|
||
{
|
||
"id": "A3",
|
||
"label": "DISPATCH",
|
||
"subtitle": "Binding",
|
||
"status": "unavailable",
|
||
"reason": "FC08 nie wprowadza callbacku ani granicy ISR."
|
||
},
|
||
{
|
||
"id": "A4",
|
||
"label": "APPLICATION",
|
||
"subtitle": "Low, Medium, High i verifier",
|
||
"status": "enabled",
|
||
"target_label": "fig:a4-application"
|
||
},
|
||
{
|
||
"id": "A5",
|
||
"label": "FLOW",
|
||
"subtitle": "E01–E10 i handoff mutexu",
|
||
"status": "enabled",
|
||
"target_label": "fig:a5-flow"
|
||
},
|
||
{
|
||
"id": "A6",
|
||
"label": "STATE",
|
||
"subtitle": "Owner, waiter i effective priority",
|
||
"status": "enabled",
|
||
"target_label": "fig:a6-state"
|
||
},
|
||
{
|
||
"id": "A7",
|
||
"label": "RUNTIME",
|
||
"subtitle": "Handle, TCB, stos i event log",
|
||
"status": "enabled",
|
||
"target_label": "fig:a7-runtime"
|
||
},
|
||
{
|
||
"id": "A8",
|
||
"label": "PATTERNS",
|
||
"subtitle": "Critical, suspend, mutex, gatekeeper",
|
||
"status": "enabled",
|
||
"target_label": "fig:a8-patterns"
|
||
}
|
||
],
|
||
"debug_strategies": {
|
||
"code.contract": {
|
||
"id": "code.contract",
|
||
"kind": "code",
|
||
"action": "open",
|
||
"expected_observations": [
|
||
"genuine mutex API",
|
||
"brak vTaskPrioritySet"
|
||
],
|
||
"assertions": [
|
||
"one mutex",
|
||
"fixed p1/p2/p3"
|
||
],
|
||
"evidence_fields": [
|
||
"code_ref",
|
||
"API",
|
||
"priority"
|
||
],
|
||
"prerequisites": [
|
||
"źródło FC08"
|
||
],
|
||
"layout": [
|
||
"FreeRTOSConfig",
|
||
"MutexExperiment",
|
||
"task priorities"
|
||
],
|
||
"commands": [
|
||
"rg -n 'configUSE_MUTEXES|xSemaphore|uxTaskPriorityGet' include src"
|
||
]
|
||
},
|
||
"run.inheritance": {
|
||
"id": "run.inheritance",
|
||
"kind": "run",
|
||
"action": "replay",
|
||
"expected_observations": [
|
||
"Low effective=3",
|
||
"Medium Ready and not started"
|
||
],
|
||
"assertions": [
|
||
"holder=Low",
|
||
"High uses portMAX_DELAY"
|
||
],
|
||
"evidence_fields": [
|
||
"event",
|
||
"holder",
|
||
"priority",
|
||
"state",
|
||
"PC",
|
||
"SP",
|
||
"timestamp"
|
||
],
|
||
"prerequisites": [
|
||
"Hazard3 online",
|
||
"czysta RAM"
|
||
],
|
||
"layout": [
|
||
"Low/High/Medium",
|
||
"mutex holder",
|
||
"task states",
|
||
"event log"
|
||
],
|
||
"commands": [
|
||
"print g_fc08",
|
||
"print g_fc08_events"
|
||
]
|
||
},
|
||
"run.handoff": {
|
||
"id": "run.handoff",
|
||
"kind": "run",
|
||
"action": "replay",
|
||
"expected_observations": [
|
||
"High E07 before Medium E08",
|
||
"value 2 under High ownership"
|
||
],
|
||
"assertions": [
|
||
"Low restored to 1",
|
||
"resource invariant"
|
||
],
|
||
"evidence_fields": [
|
||
"order",
|
||
"priority",
|
||
"value"
|
||
],
|
||
"prerequisites": [
|
||
"Low owns contended mutex"
|
||
],
|
||
"layout": [
|
||
"give path",
|
||
"High",
|
||
"Medium",
|
||
"protected value"
|
||
],
|
||
"commands": [
|
||
"print g_fc08.protected_value",
|
||
"print g_fc08_events[6]",
|
||
"print g_fc08_events[7]"
|
||
]
|
||
},
|
||
"run.pass": {
|
||
"id": "run.pass",
|
||
"kind": "run",
|
||
"action": "replay",
|
||
"expected_observations": [
|
||
"PASS=1",
|
||
"10 committed records"
|
||
],
|
||
"assertions": [
|
||
"stable three-run digest",
|
||
"verifier priority 0"
|
||
],
|
||
"evidence_fields": [
|
||
"PASS",
|
||
"digest",
|
||
"source blob",
|
||
"ELF hash",
|
||
"timestamp"
|
||
],
|
||
"prerequisites": [
|
||
"three workers finished"
|
||
],
|
||
"layout": [
|
||
"bounded log",
|
||
"PASS",
|
||
"digest"
|
||
],
|
||
"commands": [
|
||
"print g_fc08_pass",
|
||
"print g_fc08.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": "Mutex i dziedziczenie priorytetu",
|
||
"url": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/2392f81a-ed6c-510b-86b5-06c5e2f1c6aa",
|
||
"repository_url": "https://zsl-gitea.mpabi.pl/edu-freertos-c/lab-rv32i-freertos-c-resource-management",
|
||
"url_host_uuid": "dce7fb9d-7b2f-5d49-96a2-3a30d3070b84",
|
||
"url_domain": "mpabi.pl",
|
||
"doc_uuid": "2392f81a-ed6c-510b-86b5-06c5e2f1c6aa",
|
||
"revision": "v00.01",
|
||
"issued_on": "2026-07-19T00:00:00+02:00",
|
||
"series": "FREERTOS-C-08",
|
||
"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ń odróżnia mutex od semafora binarnego i dowodzi, że FreeRTOS tymczasowo podnosi efektywny priorytet właściciela blokującego task o wyższym priorytecie.",
|
||
"scope_title": "Zakres karty",
|
||
"scope_content_tex": "Low p1 przejmuje mutex i tworzy High p3. High blokuje się bez timeoutu, Low dziedziczy p3, a nowy Medium p2 pozostaje Ready bez wykonania. Po give High przejmuje zasób przed Medium, a Low wraca do p1. Verifier sprawdza publiczne API, własność, trzy stosy, porządek E01–E10 i stabilny digest.",
|
||
"scope_table": {
|
||
"headers": [
|
||
"Lekcja",
|
||
"Task",
|
||
"Najważniejsza idea",
|
||
"Priorytet",
|
||
"Status",
|
||
"Version"
|
||
],
|
||
"rows": [
|
||
{
|
||
"chapter": "FC08",
|
||
"task": "Task01",
|
||
"idea_tex": "ownership, bounded inversion i priority inheritance",
|
||
"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": {
|
||
"FC08.EN01": {
|
||
"bloom_level": "Analiza",
|
||
"label": "Model mutexu",
|
||
"text": "Uczeń wiąże ownership, wait list i effective priority bez ręcznej zmiany priorytetu.",
|
||
"assessment_criteria": [
|
||
"FC08.KW01"
|
||
]
|
||
},
|
||
"FC08.EK01": {
|
||
"bloom_level": "Zastosowanie",
|
||
"label": "Replay PIP",
|
||
"text": "Uczeń odtwarza E01–E10 i pokazuje holder, publiczne priority/state, trzy stosy, protected value i digest.",
|
||
"assessment_criteria": [
|
||
"FC08.KW01"
|
||
]
|
||
}
|
||
},
|
||
"assessment_criteria": {
|
||
"FC08.KW01": {
|
||
"text": "PASS; Low 1→3→1; Medium eReady i started=0 podczas dziedziczenia; High E07 przed Medium E08; digest jest deterministyczny.",
|
||
"learning_effects": [
|
||
"FC08.EN01",
|
||
"FC08.EK01"
|
||
]
|
||
}
|
||
},
|
||
"educational_requirements": {
|
||
"FC08.WE01": {
|
||
"text": "Zbadanie mechanizmu bounded priority inversion na prawdziwym mutexie FreeRTOS.",
|
||
"label": "ownership, bounded inversion i priority inheritance",
|
||
"learning_effects": [
|
||
"FC08.EN01",
|
||
"FC08.EK01"
|
||
],
|
||
"learning_tree": {
|
||
"schema": "we-learning-tree.v1",
|
||
"policy": "Każda aktywna kotwica wskazuje kod lub checkpoint.",
|
||
"ogolne": [
|
||
{
|
||
"effect_ref": "FC08.EN01",
|
||
"display": "EN LOCAL RTOS.08",
|
||
"source": "LOCAL",
|
||
"official": "RTOS",
|
||
"local": "08",
|
||
"kind": "EN",
|
||
"tree_id": "FC08.WE01.OG.LOCAL.RTOS.08",
|
||
"text": "Uczeń wiąże ownership, wait list i effective priority bez ręcznej zmiany priorytetu.",
|
||
"kw": [
|
||
{
|
||
"criterion_ref": "FC08.KW01",
|
||
"display": "KW LOCAL RTOS.08",
|
||
"source": "LOCAL",
|
||
"kind": "KW",
|
||
"official": "RTOS",
|
||
"local": "08",
|
||
"text": "Łączy kod, diagram i zweryfikowany dowód."
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"zawodowe": [
|
||
{
|
||
"effect_ref": "FC08.EK01",
|
||
"display": "EK LOCAL RTOS.08",
|
||
"source": "LOCAL",
|
||
"official": "RTOS",
|
||
"local": "08",
|
||
"kind": "EK",
|
||
"tree_id": "FC08.WE01.TECH.LOCAL.RTOS.08",
|
||
"text": "Uczeń odtwarza E01–E10 i pokazuje holder, publiczne priority/state, trzy stosy, protected value i digest.",
|
||
"kw": [
|
||
{
|
||
"criterion_ref": "FC08.KW01",
|
||
"display": "KW LOCAL RTOS.08",
|
||
"source": "LOCAL",
|
||
"kind": "KW",
|
||
"official": "RTOS",
|
||
"local": "08",
|
||
"text": "Łączy kod, diagram i zweryfikowany dowód."
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
}
|
||
},
|
||
"debug_checkpoints": {
|
||
"schema": "stem-debug-checkpoints.v1",
|
||
"semantics": "deterministic-replay",
|
||
"artifact": {
|
||
"source": "src/tasks/task01_mutex.c",
|
||
"source_git_blob": "520c0396319fb331443650c1664dfb692a806e44",
|
||
"elf": "build/task01_mutex/prog.elf",
|
||
"hazard3_elf_sha256": "9a02076cc36ed00ad1ca23e90c756f30cb69524fe6531983b536538bf5ebd388",
|
||
"hazard3_image": "build/task01_mutex/prog.bin",
|
||
"hazard3_image_sha256": "89802a1007fc59f285d07da7ba002b6593ae2cf9891df151af8182fe8bfe9b04"
|
||
},
|
||
"targets": {
|
||
"hazard3-sim": {
|
||
"adapter": "hazard3-reset-load-replay.v1",
|
||
"baseline": "restart-backend",
|
||
"clean_ram": true
|
||
}
|
||
},
|
||
"items": {
|
||
"task01.config": {
|
||
"event_id": "E01",
|
||
"stop": {
|
||
"symbol": "fc08_checkpoint_committed",
|
||
"offset": 0,
|
||
"condition": "$a0 == 1"
|
||
},
|
||
"verify": {
|
||
"expressions": [
|
||
{
|
||
"expr": "g_fc08_event_count",
|
||
"equals": 1
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"task01.low-owns": {
|
||
"event_id": "E02",
|
||
"stop": {
|
||
"symbol": "fc08_checkpoint_committed",
|
||
"offset": 0,
|
||
"condition": "$a0 == 2"
|
||
},
|
||
"verify": {
|
||
"expressions": [
|
||
{
|
||
"expr": "g_fc08.protected_value",
|
||
"equals": 1
|
||
},
|
||
{
|
||
"expr": "g_fc08.low_sp != 0",
|
||
"equals": 1
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"task01.high-blocks": {
|
||
"event_id": "E03",
|
||
"stop": {
|
||
"symbol": "fc08_checkpoint_committed",
|
||
"offset": 0,
|
||
"condition": "$a0 == 3"
|
||
},
|
||
"verify": {
|
||
"expressions": [
|
||
{
|
||
"expr": "g_fc08.high_sp != 0",
|
||
"equals": 1
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"task01.inherited": {
|
||
"event_id": "E04",
|
||
"stop": {
|
||
"symbol": "fc08_checkpoint_committed",
|
||
"offset": 0,
|
||
"condition": "$a0 == 4"
|
||
},
|
||
"verify": {
|
||
"expressions": [
|
||
{
|
||
"expr": "g_fc08.inherited_priority",
|
||
"equals": 3
|
||
},
|
||
{
|
||
"expr": "g_fc08.holder_while_contended == g_fc08.low_handle",
|
||
"equals": 1
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"task01.medium-ready": {
|
||
"event_id": "E05",
|
||
"stop": {
|
||
"symbol": "fc08_checkpoint_committed",
|
||
"offset": 0,
|
||
"condition": "$a0 == 5"
|
||
},
|
||
"verify": {
|
||
"expressions": [
|
||
{
|
||
"expr": "g_fc08.medium_state_while_inherited",
|
||
"equals": 1
|
||
},
|
||
{
|
||
"expr": "g_fc08.medium_started_while_inherited",
|
||
"equals": 0
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"task01.release": {
|
||
"event_id": "E06",
|
||
"stop": {
|
||
"symbol": "fc08_checkpoint_committed",
|
||
"offset": 0,
|
||
"condition": "$a0 == 6"
|
||
},
|
||
"verify": {
|
||
"expressions": [
|
||
{
|
||
"expr": "g_fc08.protected_value",
|
||
"equals": 1
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"task01.high-acquires": {
|
||
"event_id": "E07",
|
||
"stop": {
|
||
"symbol": "fc08_checkpoint_committed",
|
||
"offset": 0,
|
||
"condition": "$a0 == 7"
|
||
},
|
||
"verify": {
|
||
"expressions": [
|
||
{
|
||
"expr": "g_fc08.high_acquired",
|
||
"equals": 1
|
||
},
|
||
{
|
||
"expr": "g_fc08.protected_value",
|
||
"equals": 2
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"task01.medium-runs": {
|
||
"event_id": "E08",
|
||
"stop": {
|
||
"symbol": "fc08_checkpoint_committed",
|
||
"offset": 0,
|
||
"condition": "$a0 == 8"
|
||
},
|
||
"verify": {
|
||
"expressions": [
|
||
{
|
||
"expr": "g_fc08.medium_started",
|
||
"equals": 1
|
||
},
|
||
{
|
||
"expr": "g_fc08_events[6].event",
|
||
"equals": 7
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"task01.restored": {
|
||
"event_id": "E09",
|
||
"stop": {
|
||
"symbol": "fc08_checkpoint_committed",
|
||
"offset": 0,
|
||
"condition": "$a0 == 9"
|
||
},
|
||
"verify": {
|
||
"expressions": [
|
||
{
|
||
"expr": "g_fc08.restored_priority",
|
||
"equals": 1
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"task01.pass": {
|
||
"event_id": "E10",
|
||
"stop": {
|
||
"symbol": "fc08_checkpoint_committed",
|
||
"offset": 0,
|
||
"condition": "$a0 == 10"
|
||
},
|
||
"verify": {
|
||
"expressions": [
|
||
{
|
||
"expr": "g_fc08_pass",
|
||
"equals": 1
|
||
},
|
||
{
|
||
"expr": "g_fc08_event_count",
|
||
"equals": 10
|
||
}
|
||
]
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"sections": [
|
||
{
|
||
"title": "A2 — Structure",
|
||
"order": 20,
|
||
"content_kind": "prose",
|
||
"asset_page_mode": "one-per-page",
|
||
"page_orientation": "portrait",
|
||
"content_tex": "Mutex przechowuje właściciela i wait list. Dziedziczenie zmienia efektywny priorytet właściciela, nie bazową konfigurację aplikacji.",
|
||
"assets": [
|
||
{
|
||
"path": "assets/a2-structure.png",
|
||
"html_path": "assets/a2-structure.svg",
|
||
"source_path": "assets/a2-structure.puml",
|
||
"caption": "A2 STRUCTURE — ownership i wait list.",
|
||
"label": "fig:a2-structure",
|
||
"alt": "Struktura mutexu i trzech tasków.",
|
||
"kind": "diagram",
|
||
"width": 1.0,
|
||
"page_grid": {
|
||
"columns": 1,
|
||
"rows": 1,
|
||
"page_width": 660,
|
||
"page_height": 760,
|
||
"overview": true,
|
||
"step_tiles": {
|
||
"mutex": 1,
|
||
"low": 1,
|
||
"high": 1,
|
||
"medium": 1,
|
||
"resource": 1
|
||
}
|
||
},
|
||
"interactive": {
|
||
"kind": "uml-class",
|
||
"storage_key": "fc08-a2-structure",
|
||
"title": "A2 · struktura mutexu",
|
||
"task": {
|
||
"id": "task01",
|
||
"label": "Task01 · mutex i PIP"
|
||
},
|
||
"block": {
|
||
"id": "a2",
|
||
"label": "A2 STRUCTURE",
|
||
"description": "Genuine mutex, owner, waiter, Ready task and guarded resource."
|
||
},
|
||
"phases": [
|
||
{
|
||
"id": "structure",
|
||
"label": "MUTEX / OWNER / WAITERS",
|
||
"steps": [
|
||
{
|
||
"id": "mutex",
|
||
"number": 1,
|
||
"label": "genuine FreeRTOS mutex",
|
||
"mode": "CODE",
|
||
"strategy_ref": "code.contract",
|
||
"svg_label": "01",
|
||
"code_ref": "src/tasks/task01_mutex.c:237",
|
||
"description": "xSemaphoreCreateMutex wybiera mechanizm ownership/PIP.",
|
||
"evidence": "xQueueCreateMutex symbol."
|
||
},
|
||
{
|
||
"id": "low",
|
||
"number": 2,
|
||
"label": "Low owns protected value",
|
||
"mode": "RUN",
|
||
"event_id": "E02",
|
||
"strategy_ref": "run.inheritance",
|
||
"svg_label": "02",
|
||
"code_ref": "src/tasks/task01_mutex.c:142",
|
||
"snapshot_ref": "task01.low-owns",
|
||
"description": "Take z zerowym wait jest legalny dla wolnego mutexu.",
|
||
"evidence": "holder Low; value 1."
|
||
},
|
||
{
|
||
"id": "high",
|
||
"number": 3,
|
||
"label": "High waits indefinitely",
|
||
"mode": "RUN",
|
||
"event_id": "E03",
|
||
"strategy_ref": "run.inheritance",
|
||
"svg_label": "03",
|
||
"code_ref": "src/tasks/task01_mutex.c:97",
|
||
"snapshot_ref": "task01.high-blocks",
|
||
"description": "High trafia na mutex wait list.",
|
||
"evidence": "High stack and Blocked path."
|
||
},
|
||
{
|
||
"id": "medium",
|
||
"number": 4,
|
||
"label": "Medium is Ready, not executed",
|
||
"mode": "RUN",
|
||
"event_id": "E05",
|
||
"strategy_ref": "run.inheritance",
|
||
"svg_label": "04",
|
||
"code_ref": "src/tasks/task01_mutex.c:160",
|
||
"snapshot_ref": "task01.medium-ready",
|
||
"description": "P2 nie wyprzedza odziedziczonego p3.",
|
||
"evidence": "eReady; started=0."
|
||
},
|
||
{
|
||
"id": "resource",
|
||
"number": 5,
|
||
"label": "all writes occur under ownership",
|
||
"mode": "RUN",
|
||
"event_id": "E07",
|
||
"strategy_ref": "run.handoff",
|
||
"svg_label": "05",
|
||
"code_ref": "src/tasks/task01_mutex.c:101",
|
||
"snapshot_ref": "task01.high-acquires",
|
||
"description": "High zapisuje 2 po przejęciu mutexu.",
|
||
"evidence": "protected_value=2."
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"title": "A4 — Application",
|
||
"order": 30,
|
||
"content_kind": "prose",
|
||
"asset_page_mode": "one-per-page",
|
||
"page_orientation": "portrait",
|
||
"content_tex": "Low tworzy High dopiero po przejęciu mutexu, a Medium dopiero po potwierdzeniu dziedziczenia. Topologia jest deterministyczna.",
|
||
"assets": [
|
||
{
|
||
"path": "assets/a4-application.png",
|
||
"html_path": "assets/a4-application.svg",
|
||
"source_path": "assets/a4-application.puml",
|
||
"caption": "A4 APPLICATION — deterministic creation topology.",
|
||
"label": "fig:a4-application",
|
||
"alt": "Topologia Low, High, Medium i verifier.",
|
||
"kind": "diagram",
|
||
"width": 1.0,
|
||
"page_grid": {
|
||
"columns": 1,
|
||
"rows": 1,
|
||
"page_width": 660,
|
||
"page_height": 760,
|
||
"overview": true,
|
||
"step_tiles": {
|
||
"main": 1,
|
||
"low": 1,
|
||
"high": 1,
|
||
"inherited": 1,
|
||
"medium": 1,
|
||
"verifier": 1
|
||
}
|
||
},
|
||
"interactive": {
|
||
"kind": "uml-class",
|
||
"storage_key": "fc08-a4-application",
|
||
"title": "A4 · topologia eksperymentu",
|
||
"task": {
|
||
"id": "task01",
|
||
"label": "Task01 · mutex i PIP"
|
||
},
|
||
"block": {
|
||
"id": "a4",
|
||
"label": "A4 APPLICATION",
|
||
"description": "Construction order makes inheritance observable without timing guesses."
|
||
},
|
||
"phases": [
|
||
{
|
||
"id": "topology",
|
||
"label": "CREATE / BLOCK / VERIFY",
|
||
"steps": [
|
||
{
|
||
"id": "main",
|
||
"number": 1,
|
||
"label": "main creates only Low and verifier",
|
||
"mode": "CODE",
|
||
"strategy_ref": "code.contract",
|
||
"svg_label": "01",
|
||
"code_ref": "src/tasks/task01_mutex.c:233",
|
||
"description": "High nie może przejąć wolnego mutexu przed Low.",
|
||
"evidence": "fixed topology."
|
||
},
|
||
{
|
||
"id": "low",
|
||
"number": 2,
|
||
"label": "Low creates High while owning",
|
||
"mode": "RUN",
|
||
"event_id": "E02",
|
||
"strategy_ref": "run.inheritance",
|
||
"svg_label": "02",
|
||
"code_ref": "src/tasks/task01_mutex.c:149",
|
||
"snapshot_ref": "task01.low-owns",
|
||
"description": "High natychmiast preemptuje i blokuje się.",
|
||
"evidence": "next event E03."
|
||
},
|
||
{
|
||
"id": "high",
|
||
"number": 3,
|
||
"label": "High creates contention",
|
||
"mode": "RUN",
|
||
"event_id": "E03",
|
||
"strategy_ref": "run.inheritance",
|
||
"svg_label": "03",
|
||
"code_ref": "src/tasks/task01_mutex.c:96",
|
||
"snapshot_ref": "task01.high-blocks",
|
||
"description": "Nie ma sztucznej zmiany priorytetu.",
|
||
"evidence": "real mutex wait."
|
||
},
|
||
{
|
||
"id": "inherited",
|
||
"number": 4,
|
||
"label": "Low continues at effective p3",
|
||
"mode": "RUN",
|
||
"event_id": "E04",
|
||
"strategy_ref": "run.inheritance",
|
||
"svg_label": "04",
|
||
"code_ref": "src/tasks/task01_mutex.c:152",
|
||
"snapshot_ref": "task01.inherited",
|
||
"description": "Public API zwraca 3.",
|
||
"evidence": "holder remains Low."
|
||
},
|
||
{
|
||
"id": "medium",
|
||
"number": 5,
|
||
"label": "Medium is the inversion probe",
|
||
"mode": "RUN",
|
||
"event_id": "E05",
|
||
"strategy_ref": "run.inheritance",
|
||
"svg_label": "05",
|
||
"code_ref": "src/tasks/task01_mutex.c:162",
|
||
"snapshot_ref": "task01.medium-ready",
|
||
"description": "Ready p2 nie wykonuje nawet pierwszej instrukcji.",
|
||
"evidence": "started=0."
|
||
},
|
||
{
|
||
"id": "verifier",
|
||
"number": 6,
|
||
"label": "lowest verifier asserts relations",
|
||
"mode": "RUN",
|
||
"event_id": "E10",
|
||
"strategy_ref": "run.pass",
|
||
"svg_label": "06",
|
||
"code_ref": "src/tasks/task01_mutex.c:207",
|
||
"snapshot_ref": "task01.pass",
|
||
"description": "Sprawdzenie nie zakłóca workerów.",
|
||
"evidence": "PASS and digest."
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"title": "A5 — Flow",
|
||
"order": 40,
|
||
"content_kind": "prose",
|
||
"asset_page_mode": "one-per-page",
|
||
"page_orientation": "portrait",
|
||
"content_tex": "Decydujący porządek to High blocks → Low inherits → Medium Ready/not-run → give → High acquires → Medium runs.",
|
||
"assets": [
|
||
{
|
||
"path": "assets/a5-flow.png",
|
||
"html_path": "assets/a5-flow.svg",
|
||
"source_path": "assets/a5-flow.puml",
|
||
"caption": "A5 FLOW — bounded priority inversion.",
|
||
"label": "fig:a5-flow",
|
||
"alt": "Sekwencja dziedziczenia priorytetu.",
|
||
"kind": "diagram",
|
||
"width": 1.0,
|
||
"page_grid": {
|
||
"columns": 1,
|
||
"rows": 1,
|
||
"page_width": 660,
|
||
"page_height": 760,
|
||
"overview": true,
|
||
"step_tiles": {
|
||
"config": 1,
|
||
"own": 1,
|
||
"block": 1,
|
||
"inherit": 1,
|
||
"ready": 1,
|
||
"give": 1,
|
||
"high": 1,
|
||
"medium": 1,
|
||
"restore": 1,
|
||
"pass": 1
|
||
}
|
||
},
|
||
"interactive": {
|
||
"kind": "uml-sequence",
|
||
"storage_key": "fc08-a5-flow",
|
||
"title": "A5 · priority inheritance flow",
|
||
"task": {
|
||
"id": "task01",
|
||
"label": "Task01 · mutex i PIP"
|
||
},
|
||
"block": {
|
||
"id": "a5",
|
||
"label": "A5 FLOW",
|
||
"description": "One complete E01–E10 run."
|
||
},
|
||
"phases": [
|
||
{
|
||
"id": "flow",
|
||
"label": "OWN / INHERIT / HANDOFF / RESTORE",
|
||
"steps": [
|
||
{
|
||
"id": "config",
|
||
"number": 1,
|
||
"label": "configuration committed",
|
||
"mode": "RUN",
|
||
"event_id": "E01",
|
||
"strategy_ref": "run.inheritance",
|
||
"svg_label": "01",
|
||
"code_ref": "src/tasks/task01_mutex.c:236",
|
||
"snapshot_ref": "task01.config",
|
||
"description": "Clean RAM and fixed priorities.",
|
||
"evidence": "one record."
|
||
},
|
||
{
|
||
"id": "own",
|
||
"number": 2,
|
||
"label": "Low takes mutex",
|
||
"mode": "RUN",
|
||
"event_id": "E02",
|
||
"strategy_ref": "run.inheritance",
|
||
"svg_label": "02",
|
||
"code_ref": "src/tasks/task01_mutex.c:142",
|
||
"snapshot_ref": "task01.low-owns",
|
||
"description": "Low becomes owner.",
|
||
"evidence": "value=1."
|
||
},
|
||
{
|
||
"id": "block",
|
||
"number": 3,
|
||
"label": "High blocks",
|
||
"mode": "RUN",
|
||
"event_id": "E03",
|
||
"strategy_ref": "run.inheritance",
|
||
"svg_label": "03",
|
||
"code_ref": "src/tasks/task01_mutex.c:97",
|
||
"snapshot_ref": "task01.high-blocks",
|
||
"description": "Non-zero wait creates contention.",
|
||
"evidence": "High stack."
|
||
},
|
||
{
|
||
"id": "inherit",
|
||
"number": 4,
|
||
"label": "Low inherits p3",
|
||
"mode": "RUN",
|
||
"event_id": "E04",
|
||
"strategy_ref": "run.inheritance",
|
||
"svg_label": "04",
|
||
"code_ref": "src/tasks/task01_mutex.c:152",
|
||
"snapshot_ref": "task01.inherited",
|
||
"description": "Kernel PIP, not application code.",
|
||
"evidence": "priority=3."
|
||
},
|
||
{
|
||
"id": "ready",
|
||
"number": 5,
|
||
"label": "Medium Ready but not run",
|
||
"mode": "RUN",
|
||
"event_id": "E05",
|
||
"strategy_ref": "run.inheritance",
|
||
"svg_label": "05",
|
||
"code_ref": "src/tasks/task01_mutex.c:162",
|
||
"snapshot_ref": "task01.medium-ready",
|
||
"description": "Bounded inversion proof.",
|
||
"evidence": "eReady and zero flag."
|
||
},
|
||
{
|
||
"id": "give",
|
||
"number": 6,
|
||
"label": "Low begins give",
|
||
"mode": "RUN",
|
||
"event_id": "E06",
|
||
"strategy_ref": "run.handoff",
|
||
"svg_label": "06",
|
||
"code_ref": "src/tasks/task01_mutex.c:169",
|
||
"snapshot_ref": "task01.release",
|
||
"description": "High may preempt inside API.",
|
||
"evidence": "value still 1."
|
||
},
|
||
{
|
||
"id": "high",
|
||
"number": 7,
|
||
"label": "High acquires first",
|
||
"mode": "RUN",
|
||
"event_id": "E07",
|
||
"strategy_ref": "run.handoff",
|
||
"svg_label": "07",
|
||
"code_ref": "src/tasks/task01_mutex.c:101",
|
||
"snapshot_ref": "task01.high-acquires",
|
||
"description": "Ownership transfers to top waiter.",
|
||
"evidence": "value=2."
|
||
},
|
||
{
|
||
"id": "medium",
|
||
"number": 8,
|
||
"label": "Medium runs after High",
|
||
"mode": "RUN",
|
||
"event_id": "E08",
|
||
"strategy_ref": "run.handoff",
|
||
"svg_label": "08",
|
||
"code_ref": "src/tasks/task01_mutex.c:123",
|
||
"snapshot_ref": "task01.medium-runs",
|
||
"description": "No priority inversion remains.",
|
||
"evidence": "E07 before E08."
|
||
},
|
||
{
|
||
"id": "restore",
|
||
"number": 9,
|
||
"label": "Low returns to base p1",
|
||
"mode": "RUN",
|
||
"event_id": "E09",
|
||
"strategy_ref": "run.handoff",
|
||
"svg_label": "09",
|
||
"code_ref": "src/tasks/task01_mutex.c:175",
|
||
"snapshot_ref": "task01.restored",
|
||
"description": "Disinherit after give.",
|
||
"evidence": "priority=1."
|
||
},
|
||
{
|
||
"id": "pass",
|
||
"number": 10,
|
||
"label": "verifier commits PASS",
|
||
"mode": "RUN",
|
||
"event_id": "E10",
|
||
"strategy_ref": "run.pass",
|
||
"svg_label": "10",
|
||
"code_ref": "src/tasks/task01_mutex.c:207",
|
||
"snapshot_ref": "task01.pass",
|
||
"description": "All relational assertions hold.",
|
||
"evidence": "digest 5433b784."
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"title": "A6 — State",
|
||
"order": 50,
|
||
"content_kind": "prose",
|
||
"asset_page_mode": "one-per-page",
|
||
"page_orientation": "portrait",
|
||
"content_tex": "High nie przejmuje zasobu w chwili blokady. Kernel tymczasowo podnosi właściciela, a dopiero give przenosi własność i przywraca bazowy priorytet.",
|
||
"assets": [
|
||
{
|
||
"path": "assets/a6-state.png",
|
||
"html_path": "assets/a6-state.svg",
|
||
"source_path": "assets/a6-state.puml",
|
||
"caption": "A6 STATE — free, owned, contended, transferred.",
|
||
"label": "fig:a6-state",
|
||
"alt": "Maszyna stanu mutexu.",
|
||
"kind": "diagram",
|
||
"width": 1.0,
|
||
"page_grid": {
|
||
"columns": 1,
|
||
"rows": 1,
|
||
"page_width": 660,
|
||
"page_height": 760,
|
||
"overview": true,
|
||
"step_tiles": {
|
||
"free": 1,
|
||
"owned": 1,
|
||
"contended": 1,
|
||
"transfer": 1,
|
||
"verified": 1
|
||
}
|
||
},
|
||
"interactive": {
|
||
"kind": "uml-class",
|
||
"storage_key": "fc08-a6-state",
|
||
"title": "A6 · owner and priority state",
|
||
"task": {
|
||
"id": "task01",
|
||
"label": "Task01 · mutex i PIP"
|
||
},
|
||
"block": {
|
||
"id": "a6",
|
||
"label": "A6 STATE",
|
||
"description": "Mutex ownership and effective-priority states."
|
||
},
|
||
"phases": [
|
||
{
|
||
"id": "state",
|
||
"label": "FREE / OWNED / CONTENDED / TRANSFERRED",
|
||
"steps": [
|
||
{
|
||
"id": "free",
|
||
"number": 1,
|
||
"label": "mutex starts free",
|
||
"mode": "RUN",
|
||
"event_id": "E01",
|
||
"strategy_ref": "run.inheritance",
|
||
"svg_label": "01",
|
||
"code_ref": "src/tasks/task01_mutex.c:237",
|
||
"snapshot_ref": "task01.config",
|
||
"description": "No owner.",
|
||
"evidence": "handle created after E01."
|
||
},
|
||
{
|
||
"id": "owned",
|
||
"number": 2,
|
||
"label": "Low owns at p1",
|
||
"mode": "RUN",
|
||
"event_id": "E02",
|
||
"strategy_ref": "run.inheritance",
|
||
"svg_label": "02",
|
||
"code_ref": "src/tasks/task01_mutex.c:142",
|
||
"snapshot_ref": "task01.low-owns",
|
||
"description": "Uncontended state.",
|
||
"evidence": "protected value 1."
|
||
},
|
||
{
|
||
"id": "contended",
|
||
"number": 3,
|
||
"label": "High waits; Low effective p3",
|
||
"mode": "RUN",
|
||
"event_id": "E04",
|
||
"strategy_ref": "run.inheritance",
|
||
"svg_label": "03",
|
||
"code_ref": "src/tasks/task01_mutex.c:152",
|
||
"snapshot_ref": "task01.inherited",
|
||
"description": "Owner stays Low.",
|
||
"evidence": "priority 3, holder Low."
|
||
},
|
||
{
|
||
"id": "transfer",
|
||
"number": 6,
|
||
"label": "give transfers to High",
|
||
"mode": "RUN",
|
||
"event_id": "E07",
|
||
"strategy_ref": "run.handoff",
|
||
"svg_label": "06",
|
||
"code_ref": "src/tasks/task01_mutex.c:103",
|
||
"snapshot_ref": "task01.high-acquires",
|
||
"description": "High returns from take.",
|
||
"evidence": "value 2."
|
||
},
|
||
{
|
||
"id": "verified",
|
||
"number": 9,
|
||
"label": "Low is restored",
|
||
"mode": "RUN",
|
||
"event_id": "E09",
|
||
"strategy_ref": "run.handoff",
|
||
"svg_label": "09",
|
||
"code_ref": "src/tasks/task01_mutex.c:175",
|
||
"snapshot_ref": "task01.restored",
|
||
"description": "Effective equals base again.",
|
||
"evidence": "priority 1."
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"title": "A7 — Runtime",
|
||
"order": 60,
|
||
"content_kind": "prose",
|
||
"asset_page_mode": "one-per-page",
|
||
"page_orientation": "portrait",
|
||
"content_tex": "Aplikacja asercyjnie używa wyłącznie publicznego API. uxBasePriority i uxPriority są dowodem debuggera, a nie kontraktem kodu ucznia.",
|
||
"assets": [
|
||
{
|
||
"path": "assets/a7-runtime.png",
|
||
"html_path": "assets/a7-runtime.svg",
|
||
"source_path": "assets/a7-runtime.puml",
|
||
"caption": "A7 RUNTIME — handles, stacks, public states and TCB detail.",
|
||
"label": "fig:a7-runtime",
|
||
"alt": "Runtime mutexu i trzech tasków.",
|
||
"kind": "diagram",
|
||
"width": 1.0,
|
||
"page_grid": {
|
||
"columns": 1,
|
||
"rows": 1,
|
||
"page_width": 660,
|
||
"page_height": 760,
|
||
"overview": true,
|
||
"step_tiles": {
|
||
"experiment": 1,
|
||
"low": 1,
|
||
"high": 1,
|
||
"medium": 1,
|
||
"tcb": 1,
|
||
"log": 1
|
||
}
|
||
},
|
||
"interactive": {
|
||
"kind": "uml-class",
|
||
"storage_key": "fc08-a7-runtime",
|
||
"title": "A7 · runtime evidence",
|
||
"task": {
|
||
"id": "task01",
|
||
"label": "Task01 · mutex i PIP"
|
||
},
|
||
"block": {
|
||
"id": "a7",
|
||
"label": "A7 RUNTIME",
|
||
"description": "Public acceptance evidence plus optional TCB inspection."
|
||
},
|
||
"phases": [
|
||
{
|
||
"id": "runtime",
|
||
"label": "HANDLES / STACKS / TCB / LOG",
|
||
"steps": [
|
||
{
|
||
"id": "experiment",
|
||
"number": 1,
|
||
"label": "experiment owns bounded evidence",
|
||
"mode": "CODE",
|
||
"strategy_ref": "code.contract",
|
||
"svg_label": "01",
|
||
"code_ref": "include/task01_mutex.h:26",
|
||
"description": "Persistent static context.",
|
||
"evidence": "handles and observations."
|
||
},
|
||
{
|
||
"id": "low",
|
||
"number": 2,
|
||
"label": "Low handle remains forensic identity",
|
||
"mode": "RUN",
|
||
"event_id": "E04",
|
||
"strategy_ref": "run.inheritance",
|
||
"svg_label": "02",
|
||
"code_ref": "src/tasks/task01_mutex.c:153",
|
||
"snapshot_ref": "task01.inherited",
|
||
"description": "Holder compares to saved handle.",
|
||
"evidence": "SP and priority."
|
||
},
|
||
{
|
||
"id": "high",
|
||
"number": 3,
|
||
"label": "High owns distinct stack",
|
||
"mode": "RUN",
|
||
"event_id": "E03",
|
||
"strategy_ref": "run.inheritance",
|
||
"svg_label": "03",
|
||
"code_ref": "src/tasks/task01_mutex.c:95",
|
||
"snapshot_ref": "task01.high-blocks",
|
||
"description": "Blocked task preserves context.",
|
||
"evidence": "high_sp."
|
||
},
|
||
{
|
||
"id": "medium",
|
||
"number": 4,
|
||
"label": "Medium state is public eReady",
|
||
"mode": "RUN",
|
||
"event_id": "E05",
|
||
"strategy_ref": "run.inheritance",
|
||
"svg_label": "04",
|
||
"code_ref": "src/tasks/task01_mutex.c:162",
|
||
"snapshot_ref": "task01.medium-ready",
|
||
"description": "No private TCB dependency.",
|
||
"evidence": "eTaskGetState."
|
||
},
|
||
{
|
||
"id": "tcb",
|
||
"number": 5,
|
||
"label": "TCB base/effective is debugger evidence",
|
||
"mode": "RUN",
|
||
"event_id": "E04",
|
||
"strategy_ref": "run.inheritance",
|
||
"svg_label": "05",
|
||
"code_ref": "vendor/FreeRTOS-Kernel/tasks.c:1000",
|
||
"snapshot_ref": "task01.inherited",
|
||
"description": "Inspect uxBasePriority and uxPriority only in GDB.",
|
||
"evidence": "1 and 3."
|
||
},
|
||
{
|
||
"id": "log",
|
||
"number": 6,
|
||
"label": "record commits marker last",
|
||
"mode": "CODE",
|
||
"strategy_ref": "code.contract",
|
||
"svg_label": "06",
|
||
"code_ref": "src/tasks/task01_mutex.c:55",
|
||
"description": "Partial record cannot masquerade as evidence.",
|
||
"evidence": "committed after payload."
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"title": "A8 — Patterns",
|
||
"order": 70,
|
||
"content_kind": "prose",
|
||
"asset_page_mode": "one-per-page",
|
||
"page_orientation": "landscape",
|
||
"content_tex": "Critical section, scheduler suspension, mutex and gatekeeper solve different problems. FC08 requires task ownership and priority inheritance, therefore selects a mutex.",
|
||
"assets": [
|
||
{
|
||
"path": "assets/a8-patterns.png",
|
||
"html_path": "assets/a8-patterns.svg",
|
||
"source_path": "assets/a8-patterns.puml",
|
||
"caption": "A8 PATTERNS — four distinct synchronization contracts.",
|
||
"label": "fig:a8-patterns",
|
||
"alt": "Porównanie czterech wzorców ochrony zasobu.",
|
||
"kind": "diagram",
|
||
"width": 1.0,
|
||
"page_grid": {
|
||
"columns": 1,
|
||
"rows": 1,
|
||
"page_width": 940,
|
||
"page_height": 560,
|
||
"overview": true,
|
||
"step_tiles": {
|
||
"critical": 1,
|
||
"suspend": 1,
|
||
"mutex": 1,
|
||
"gatekeeper": 1
|
||
}
|
||
},
|
||
"interactive": {
|
||
"kind": "uml-class",
|
||
"storage_key": "fc08-a8-patterns",
|
||
"title": "A8 · resource-management choices",
|
||
"task": {
|
||
"id": "task01",
|
||
"label": "Task01 · mutex i PIP"
|
||
},
|
||
"block": {
|
||
"id": "a8",
|
||
"label": "A8 PATTERNS",
|
||
"description": "Select synchronization by contract, not by similar syntax."
|
||
},
|
||
"phases": [
|
||
{
|
||
"id": "patterns",
|
||
"label": "CRITICAL / SUSPEND / MUTEX / GATEKEEPER",
|
||
"steps": [
|
||
{
|
||
"id": "critical",
|
||
"number": 1,
|
||
"label": "critical section is bounded and nonblocking",
|
||
"mode": "CODE",
|
||
"strategy_ref": "code.contract",
|
||
"svg_label": "01",
|
||
"code_ref": "src/tasks/task01_mutex.c:48",
|
||
"description": "Protects evidence commit only.",
|
||
"evidence": "short interrupt mask."
|
||
},
|
||
{
|
||
"id": "suspend",
|
||
"number": 2,
|
||
"label": "scheduler suspension is not a lock",
|
||
"mode": "CODE",
|
||
"strategy_ref": "code.contract",
|
||
"svg_label": "02",
|
||
"code_ref": "doc/card-plan.md:1",
|
||
"description": "Interrupts continue and ownership is absent.",
|
||
"evidence": "not selected."
|
||
},
|
||
{
|
||
"id": "mutex",
|
||
"number": 3,
|
||
"label": "mutex owns and inherits",
|
||
"mode": "RUN",
|
||
"event_id": "E04",
|
||
"strategy_ref": "run.inheritance",
|
||
"svg_label": "03",
|
||
"code_ref": "src/tasks/task01_mutex.c:152",
|
||
"snapshot_ref": "task01.inherited",
|
||
"description": "Selected FC08 contract.",
|
||
"evidence": "holder Low, effective 3."
|
||
},
|
||
{
|
||
"id": "gatekeeper",
|
||
"number": 4,
|
||
"label": "gatekeeper serializes by message",
|
||
"mode": "CODE",
|
||
"strategy_ref": "code.contract",
|
||
"svg_label": "04",
|
||
"code_ref": "doc/card-plan.md:1",
|
||
"description": "Useful when only one task may touch device API.",
|
||
"evidence": "extension decision."
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"title": "Task01 — mutex i PIP",
|
||
"order": 90,
|
||
"content_kind": "tasks",
|
||
"task_refs": [
|
||
"task01"
|
||
]
|
||
}
|
||
],
|
||
"tasks": {
|
||
"task01": {
|
||
"title": "Low/Medium/High: ownership i dziedziczenie priorytetu",
|
||
"uuid": "2392f81a-ed6c-510b-86b5-06c5e2f1c6aa",
|
||
"prompt_tex": "Przejdź po A2, A4, A5, A6, A7 i A8. Odtwórz E01–E10 i udowodnij, że task średni nie wyprzedza właściciela z odziedziczonym p3.",
|
||
"criterion": "PASS; Low 1→3→1; Medium eReady i started=0 podczas dziedziczenia; High E07 przed Medium E08; digest jest deterministyczny.",
|
||
"conclusion_tex": "Mutex rozwiązuje bounded priority inversion przez tymczasowe podniesienie efektywnego priorytetu właściciela. Give może uruchomić High wewnątrz API, zanim kod Low wykona następną instrukcję.",
|
||
"flow": [
|
||
{
|
||
"kind": "block",
|
||
"id": "predict",
|
||
"title": "A — kontrakt i przewidywanie",
|
||
"content_tex": "Rozpisz owner, wait list i priorytety p1/p2/p3.",
|
||
"steps": [
|
||
{
|
||
"id": "order",
|
||
"title": "Przewidź E03–E08.",
|
||
"content_tex": "Wskaż, kiedy Medium może wykonać pierwszą instrukcję."
|
||
},
|
||
{
|
||
"id": "api",
|
||
"title": "Odrzuć fałszywe zamienniki.",
|
||
"content_tex": "Wyjaśnij, dlaczego semafor binarny i vTaskPrioritySet nie dowodzą PIP."
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"kind": "block",
|
||
"id": "replay",
|
||
"title": "B — replay Hazard3",
|
||
"content_tex": "Każdy RUN zaczyna się od czystej RAM.",
|
||
"steps": [
|
||
{
|
||
"id": "inherit",
|
||
"title": "Zbadaj E02–E05.",
|
||
"content_tex": "Porównaj holder, priority, eReady i started."
|
||
},
|
||
{
|
||
"id": "handoff",
|
||
"title": "Zbadaj E06–E09.",
|
||
"content_tex": "Sprawdź High-before-Medium i przywrócenie p1."
|
||
},
|
||
{
|
||
"id": "pass",
|
||
"title": "Zbadaj E10.",
|
||
"content_tex": "Zapisz PASS, trzy SP i digest."
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"kind": "exercise",
|
||
"id": "lock-order",
|
||
"title": "Ćwiczenie — dwie blokady",
|
||
"prompt_tex": "Dodaj drugi zasób wyłącznie do modelu projektowego. Utwórz tabelę globalnego lock order, która usuwa cykl oczekiwania, i wskaż maksymalny czas trzymania obu mutexów.",
|
||
"evidence_tex": "Diagram A8, tabela lock order i kontrprzykład z cyklem.",
|
||
"criterion": "Porządek jest globalny, acykliczny i nie obejmuje nieograniczonej operacji.",
|
||
"based_on": [
|
||
"predict",
|
||
"replay"
|
||
]
|
||
}
|
||
],
|
||
"educational_requirement_refs": [
|
||
"FC08.WE01"
|
||
],
|
||
"learning_effect_refs": [
|
||
"FC08.EN01",
|
||
"FC08.EK01"
|
||
],
|
||
"assessment_criterion_ref": "FC08.KW01"
|
||
}
|
||
},
|
||
"tasks_order": [
|
||
"task01"
|
||
]
|
||
}
|