feat: publish FreeRTOS C FC08 card
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,89 @@
|
||||
{
|
||||
"card":{"number":"08","slug":"mutex-priority-inheritance","title":"Mutex i dziedziczenie priorytetu","topic":"ownership, bounded inversion i priority inheritance","status":"Gotowa","version":"v00.01"},
|
||||
"front":{"goal":"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":"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."},
|
||||
"viewpoints":[
|
||||
{"id":"A1","label":"CONTEXT","status":"unavailable","subtitle":"Granice systemu","reason":"Granica aplikacja–kernel–Hazard3 jest utrwalona w FC07."},
|
||||
{"id":"A2","label":"STRUCTURE","status":"enabled","subtitle":"Mutex, owner, wait list i zasób"},
|
||||
{"id":"A3","label":"DISPATCH","status":"unavailable","subtitle":"Binding","reason":"FC08 nie wprowadza callbacku ani granicy ISR."},
|
||||
{"id":"A4","label":"APPLICATION","status":"enabled","subtitle":"Low, Medium, High i verifier"},
|
||||
{"id":"A5","label":"FLOW","status":"enabled","subtitle":"E01–E10 i handoff mutexu"},
|
||||
{"id":"A6","label":"STATE","status":"enabled","subtitle":"Owner, waiter i effective priority"},
|
||||
{"id":"A7","label":"RUNTIME","status":"enabled","subtitle":"Handle, TCB, stos i event log"},
|
||||
{"id":"A8","label":"PATTERNS","status":"enabled","subtitle":"Critical, suspend, mutex, gatekeeper"}
|
||||
],
|
||||
"artifact":{"source":"src/tasks/task01_mutex.c","elf":"build/task01_mutex/prog.elf","image":"build/task01_mutex/prog.bin"},
|
||||
"strategies":[
|
||||
{"id":"code.contract","kind":"code","prerequisites":["źródło FC08"],"layout":["FreeRTOSConfig","MutexExperiment","task priorities"],"commands":["rg -n 'configUSE_MUTEXES|xSemaphore|uxTaskPriorityGet' include src"],"expected_observations":["genuine mutex API","brak vTaskPrioritySet"],"assertions":["one mutex","fixed p1/p2/p3"],"evidence_fields":["code_ref","API","priority"]},
|
||||
{"id":"run.inheritance","kind":"run","prerequisites":["Hazard3 online","czysta RAM"],"layout":["Low/High/Medium","mutex holder","task states","event log"],"commands":["print g_fc08","print g_fc08_events"],"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"]},
|
||||
{"id":"run.handoff","kind":"run","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]"],"expected_observations":["High E07 before Medium E08","value 2 under High ownership"],"assertions":["Low restored to 1","resource invariant"],"evidence_fields":["order","priority","value"]},
|
||||
{"id":"run.pass","kind":"run","prerequisites":["three workers finished"],"layout":["bounded log","PASS","digest"],"commands":["print g_fc08_pass","print g_fc08.evidence_digest"],"expected_observations":["PASS=1","10 committed records"],"assertions":["stable three-run digest","verifier priority 0"],"evidence_fields":["PASS","digest","source blob","ELF hash","timestamp"]}
|
||||
],
|
||||
"checkpoints":{
|
||||
"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":[
|
||||
{"id":"A2","label":"STRUCTURE","title":"Structure","order":20,"orientation":"portrait","description":"Genuine mutex, owner, waiter, Ready task and guarded resource.","content_tex":"Mutex przechowuje właściciela i wait list. Dziedziczenie zmienia efektywny priorytet właściciela, nie bazową konfigurację aplikacji.","assets":[{"stem":"a2-structure","title":"A2 · struktura mutexu","caption":"A2 STRUCTURE — ownership i wait list.","label":"fig:a2-structure","alt":"Struktura mutexu i trzech tasków.","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."}
|
||||
]}]}]},
|
||||
{"id":"A4","label":"APPLICATION","title":"Application","order":30,"orientation":"portrait","description":"Construction order makes inheritance observable without timing guesses.","content_tex":"Low tworzy High dopiero po przejęciu mutexu, a Medium dopiero po potwierdzeniu dziedziczenia. Topologia jest deterministyczna.","assets":[{"stem":"a4-application","title":"A4 · topologia eksperymentu","caption":"A4 APPLICATION — deterministic creation topology.","label":"fig:a4-application","alt":"Topologia Low, High, Medium i verifier.","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."}
|
||||
]}]}]},
|
||||
{"id":"A5","label":"FLOW","title":"Flow","order":40,"orientation":"portrait","description":"One complete E01–E10 run.","content_tex":"Decydujący porządek to High blocks → Low inherits → Medium Ready/not-run → give → High acquires → Medium runs.","assets":[{"stem":"a5-flow","diagram_kind":"sequence","title":"A5 · priority inheritance flow","caption":"A5 FLOW — bounded priority inversion.","label":"fig:a5-flow","alt":"Sekwencja dziedziczenia priorytetu.","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."}
|
||||
]}]}]},
|
||||
{"id":"A6","label":"STATE","title":"State","order":50,"orientation":"portrait","description":"Mutex ownership and effective-priority states.","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":[{"stem":"a6-state","title":"A6 · owner and priority state","caption":"A6 STATE — free, owned, contended, transferred.","label":"fig:a6-state","alt":"Maszyna stanu mutexu.","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."}
|
||||
]}]}]},
|
||||
{"id":"A7","label":"RUNTIME","title":"Runtime","order":60,"orientation":"portrait","description":"Public acceptance evidence plus optional TCB inspection.","content_tex":"Aplikacja asercyjnie używa wyłącznie publicznego API. uxBasePriority i uxPriority są dowodem debuggera, a nie kontraktem kodu ucznia.","assets":[{"stem":"a7-runtime","title":"A7 · runtime evidence","caption":"A7 RUNTIME — handles, stacks, public states and TCB detail.","label":"fig:a7-runtime","alt":"Runtime mutexu i trzech tasków.","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."}
|
||||
]}]}]},
|
||||
{"id":"A8","label":"PATTERNS","title":"Patterns","order":70,"orientation":"landscape","description":"Select synchronization by contract, not by similar syntax.","content_tex":"Critical section, scheduler suspension, mutex and gatekeeper solve different problems. FC08 requires task ownership and priority inheritance, therefore selects a mutex.","assets":[{"stem":"a8-patterns","title":"A8 · resource-management choices","caption":"A8 PATTERNS — four distinct synchronization contracts.","label":"fig:a8-patterns","alt":"Porównanie czterech wzorców ochrony zasobu.","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."}
|
||||
]}]}]}
|
||||
],
|
||||
"learning":{"model_label":"Model mutexu","model":"Uczeń wiąże ownership, wait list i effective priority bez ręcznej zmiany priorytetu.","replay_label":"Replay PIP","replay":"Uczeń odtwarza E01–E10 i pokazuje holder, publiczne priority/state, trzy stosy, protected value i digest.","criterion":"PASS; Low 1→3→1; Medium eReady i started=0 podczas dziedziczenia; High E07 przed Medium E08; digest jest deterministyczny.","requirement":"Zbadanie mechanizmu bounded priority inversion na prawdziwym mutexie FreeRTOS."},
|
||||
"task":{"short_label":"mutex i PIP","title":"Low/Medium/High: ownership i dziedziczenie priorytetu","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.","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"]}
|
||||
]}
|
||||
}
|
||||
Reference in New Issue
Block a user