{ "schema": "esc-card-react-view.v1", "card": { "id": "mpabi-freertos-c-01-heap4-mechanics", "series": "freertos-c", "series_title": "FreeRTOS C", "number": "01", "count": "15", "slug": "heap4-mechanics", "title": "heap_4: From Linear Cursor to Reusable Blocks", "topic": "headers, address-ordered free list, first-fit, split, coalescing and heap statistics", "project": "Freestanding C nad FreeRTOS", "subject": "Informatyka", "level": "Rok 2 · L01 · RV32I/Hazard3", "revision_date": "2026-07-20T00:00:00+02:00", "status": "Gotowa", "version": "v00.01", "uuid": "87e48095-7793-54e3-9230-4e61d31bd459", "author": "M. Pabiszczak", "year": "2026" }, "library": { "schema": "stem-card-library.v2", "workspace": "edu", "subjects": [ { "id": "inf", "title": "INF · Informatyka", "current": true, "levels": [ { "id": "year-1", "title": "Rok 1", "current": false, "series": [ { "id": "console-bash", "title": "Bash · Console Tools", "current": false, "catalog_only": true, "role": "", "status": "", "cards": [ { "id": "L01", "title": "BusyBox — the Swiss Army Knife", "repo": "lab-console-busybox", "href": "", "available": false, "current": false, "number": "01", "version": "", "status": "planned", "tasks": [] }, { "id": "L02", "title": "Tmux — sessions, windows and panes", "repo": "lab-console-tmux", "href": "", "available": false, "current": false, "number": "02", "version": "", "status": "planned", "tasks": [] }, { "id": "L03", "title": "Neovim — navigation and editing", "repo": "lab-console-neovim", "href": "", "available": false, "current": false, "number": "03", "version": "", "status": "planned", "tasks": [] }, { "id": "L04", "title": "Git Basics I — status, add and commit", "repo": "lab-console-git-basics-1", "href": "", "available": false, "current": false, "number": "04", "version": "", "status": "planned", "tasks": [] }, { "id": "L05", "title": "Git Basics II — log, diff and restore", "repo": "lab-console-git-basics-2", "href": "", "available": false, "current": false, "number": "05", "version": "", "status": "planned", "tasks": [] }, { "id": "L06", "title": "Git Branching I — branch, switch and merge", "repo": "lab-console-git-branching-1", "href": "", "available": false, "current": false, "number": "06", "version": "", "status": "planned", "tasks": [] }, { "id": "L07", "title": "Git Branching II — rebase and conflicts", "repo": "lab-console-git-branching-2", "href": "", "available": false, "current": false, "number": "07", "version": "", "status": "planned", "tasks": [] }, { "id": "L08", "title": "Docker Fundamentals", "repo": "lab-console-docker", "href": "", "available": false, "current": false, "number": "08", "version": "", "status": "planned", "tasks": [] } ] }, { "id": "rv32i-asm", "title": "ASM · RV32I From Blinker to RISC-V", "current": false, "catalog_only": true, "role": "", "status": "", "cards": [ { "id": "L01", "title": "Number Systems and Storage", "repo": "lab-rv32i-asm-number-systems", "href": "", "available": false, "current": false, "number": "01", "version": "", "status": "planned", "tasks": [] }, { "id": "L02", "title": "FPGA Bring-up and Programming", "repo": "lab-rv32i-asm-fpga-bringup", "href": "", "available": false, "current": false, "number": "02", "version": "", "status": "planned", "tasks": [] }, { "id": "L03", "title": "Blinker and Synchronous Logic", "repo": "lab-rv32i-asm-blinker", "href": "", "available": false, "current": false, "number": "03", "version": "", "status": "planned", "tasks": [] }, { "id": "L04", "title": "The RISC-V ISA and Instruction Decoder", "repo": "lab-rv32i-asm-decoder", "href": "", "available": false, "current": false, "number": "04", "version": "", "status": "planned", "tasks": [] }, { "id": "L05", "title": "ALU and the Verilog Assembler", "repo": "lab-rv32i-asm-alu", "href": "", "available": false, "current": false, "number": "05", "version": "", "status": "planned", "tasks": [] }, { "id": "L06", "title": "Control Flow — Jumps and Branches", "repo": "lab-rv32i-asm-control-flow", "href": "", "available": false, "current": false, "number": "06", "version": "", "status": "planned", "tasks": [] }, { "id": "L07", "title": "Addresses and Memory", "repo": "lab-rv32i-asm-addresses-memory", "href": "", "available": false, "current": false, "number": "07", "version": "", "status": "planned", "tasks": [] }, { "id": "L08", "title": "Subroutines and the RISC-V ABI", "repo": "lab-rv32i-asm-subroutines-abi", "href": "", "available": false, "current": false, "number": "08", "version": "", "status": "planned", "tasks": [] }, { "id": "L09", "title": "Load and Store", "repo": "lab-rv32i-asm-load-store", "href": "", "available": false, "current": false, "number": "09", "version": "", "status": "planned", "tasks": [] } ] }, { "id": "c", "title": "C · Freestanding RV32I and K&R", "current": false, "catalog_only": true, "role": "", "status": "", "cards": [ { "id": "C01", "title": "ASM, C and GCC", "repo": "lab-rv32i-strlen-asm-c-gcc", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/852fa3c7-8329-583a-a244-b639d2e04495", "available": true, "current": false, "number": "01", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "Ręczna implementacja RV32I ASM" }, { "id": "task02", "title": "Referencyjna implementacja w C" }, { "id": "task03", "title": "ASM wyemitowany przez GCC" } ] }, { "id": "C02", "title": ".bss, .data and static storage", "repo": "lab-rv32i-strlen-bss-data-stack", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/74afa921-fb51-5017-bcdb-f6e84fb444d8", "available": true, "current": false, "number": "02", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "Wynik strlen w .bss" }, { "id": "task02", "title": "Wynik i napis w .data" }, { "id": "task03", "title": "Nieużyta tablica lokalna" }, { "id": "task04", "title": "Użyta tablica lokalna i stack frame" } ] }, { "id": "C03", "title": "ABI and Stack Frame", "repo": "lab-rv32i-strlen-abi-stack", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/72b22a0a-3297-5d75-a6ff-d1af48132d6c", "available": true, "current": false, "number": "03", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "Argument i wynik bez powrotu z main" }, { "id": "task02", "title": "Pełny stack frame i zachowanie ra" } ] }, { "id": "C04", "title": "Types, Operators and Expressions", "repo": "lab-rv32i-c-types-operators-expressions", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/7818aa68-4983-5aca-bf7f-541cfce5c601", "available": true, "current": false, "number": "04", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "Nazwy i stałe symboliczne" }, { "id": "task02", "title": "Typy i zakresy" }, { "id": "task03", "title": "Stałe, długość i enum" }, { "id": "task04", "title": "Deklaracje, inicjalizacja i const" }, { "id": "task05", "title": "Arytmetyka i rok przestępny" }, { "id": "task06", "title": "Porównania i logika" }, { "id": "task07", "title": "Konwersje: atoi, lower i htoi" }, { "id": "task08", "title": "Inkrementacja i operacje na napisach" }, { "id": "task09", "title": "Operatory bitowe" }, { "id": "task10", "title": "Przypisania i bitcount" }, { "id": "task11", "title": "Operator warunkowy" }, { "id": "task12", "title": "Priorytet i kolejność obliczeń" } ] }, { "id": "C05", "title": "Control Flow", "repo": "lab-rv32i-c-control-flow", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/7512361d-e5e6-5c08-ab18-8be29dacdc10", "available": true, "current": false, "number": "05", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "Instrukcje i bloki" }, { "id": "task02", "title": "if-else i dangling else" }, { "id": "task03", "title": "else-if i wyszukiwanie binarne" }, { "id": "task04", "title": "switch: escape i unescape" }, { "id": "task05", "title": "while, for i Shell sort" }, { "id": "task06", "title": "do-while i itoa" }, { "id": "task07", "title": "break i continue" }, { "id": "task08", "title": "goto i etykiety" } ] }, { "id": "C06", "title": "Functions and Program Structure", "repo": "lab-rv32i-c-functions-program-structure", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/9667818d-b691-501d-817c-b58be4cbd594", "available": true, "current": false, "number": "06", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "Funkcje i strindex" }, { "id": "task02", "title": "double i atof z wykładnikiem" }, { "id": "task03", "title": "Zewnętrzny stos RPN" }, { "id": "task04", "title": "Scope i extern" }, { "id": "task05", "title": "Nagłówki i prototypy" }, { "id": "task06", "title": "Static storage" }, { "id": "task07", "title": "Zmienne register" }, { "id": "task08", "title": "Struktura blokowa" }, { "id": "task09", "title": "Inicjalizacja" }, { "id": "task10", "title": "Rekurencja i quicksort" }, { "id": "task11", "title": "Preprocesor i makra" } ] }, { "id": "C07", "title": "Pointers, Arrays and Linear Allocator", "repo": "lab-rv32i-c-pointers-arrays", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/98dbe323-c624-53d6-9fe2-4ee688c44b38", "available": true, "current": false, "number": "07", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "task01" }, { "id": "task02", "title": "task02" }, { "id": "task03", "title": "task03" }, { "id": "task04", "title": "K&R 5.4 -- Linear Memory Allocator" }, { "id": "task05", "title": "task05" }, { "id": "task06", "title": "task06" }, { "id": "task07", "title": "task07" }, { "id": "task08", "title": "task08" }, { "id": "task09", "title": "task09" }, { "id": "task10", "title": "task10" }, { "id": "task11", "title": "task11" }, { "id": "task12", "title": "task12" } ] }, { "id": "C08", "title": "Structures and Linked State", "repo": "lab-rv32i-c-structures", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/f60fbba3-a788-5f1e-bc24-52af82f227c9", "available": true, "current": false, "number": "08", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "Układ BlockHeader" }, { "id": "task02", "title": "Nagłówek, payload i odzyskanie właściciela" }, { "id": "task03", "title": "Intruzywna lista wolnych bloków" }, { "id": "task04", "title": "Wyrównana arena dwóch bloków" } ] }, { "id": "C09", "title": "smalloc, sbrk and minimal libc", "repo": "lab-rv32i-c-smalloc-sbrk-libc", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/8e4f8bee-41f0-523b-8ea2-8926bd3d7ab0", "available": true, "current": false, "number": "09", "version": "v00.01", "status": "planned", "tasks": [ { "id": "task01", "title": "strlen z libc bez sterty" }, { "id": "task02", "title": "Kontrolowany brak dostawcy sbrk" }, { "id": "task03", "title": "Bounded sbrk i atomowy błąd" }, { "id": "task04", "title": "Wyrównany smalloc append-only" }, { "id": "task05", "title": "malloc/free picolibc jako czarna skrzynka" } ] }, { "id": "C10", "title": "RV32I Traps and Interrupt Control", "repo": "lab-rv32i-c-interrupts", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/8fb9c110-557b-5081-8ae2-a56800f872e8", "available": true, "current": false, "number": "10", "version": "v00.01", "status": "planned", "tasks": [ { "id": "task01", "title": "ECALL i wznowienie pod mepc+4" }, { "id": "task02", "title": "Machine software IRQ i clear źródła" }, { "id": "task03", "title": "Macierz pending, MSIE i MIE" } ] }, { "id": "C11", "title": "Machine Timer and Periodic Work", "repo": "lab-rv32i-c-timer", "href": "", "available": false, "current": false, "number": "11", "version": "", "status": "planned", "tasks": [] }, { "id": "C12", "title": "UART — polling and interrupts", "repo": "lab-rv32i-c-uart", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/64f7c516-78b1-58ee-8619-a82d7061079f", "available": true, "current": false, "number": "12", "version": "v00.01", "status": "planned", "tasks": [ { "id": "task01", "title": "Polling jednego bajtu" }, { "id": "task02", "title": "Odbiór R przez external IRQ 16" }, { "id": "task03", "title": "Jednokomórkowa skrzynka drop-newest" } ] }, { "id": "C13", "title": "GPIO, Edges and Debounce", "repo": "lab-rv32i-c-gpio", "href": "", "available": false, "current": false, "number": "13", "version": "", "status": "planned", "tasks": [] } ] } ] }, { "id": "year-2", "title": "Rok 2", "current": true, "series": [ { "id": "cpp", "title": "C++", "current": false, "catalog_only": true, "role": "", "status": "", "cards": [ { "id": "CPP01", "title": "Translation Units, Linkage and Namespaces", "repo": "lab-cpp-build-namespaces", "href": "", "available": false, "current": false, "number": "01", "version": "", "status": "planned", "tasks": [] }, { "id": "CPP02", "title": "Classes, Encapsulation and Invariants", "repo": "lab-cpp-classes-invariants", "href": "", "available": false, "current": false, "number": "02", "version": "", "status": "planned", "tasks": [] }, { "id": "CPP03", "title": "Construction, Destruction and RAII", "repo": "lab-cpp-lifetime-raii", "href": "", "available": false, "current": false, "number": "03", "version": "", "status": "planned", "tasks": [] }, { "id": "CPP04", "title": "References, const and Value Categories", "repo": "lab-cpp-references-const", "href": "", "available": false, "current": false, "number": "04", "version": "", "status": "planned", "tasks": [] }, { "id": "CPP05", "title": "Copy, Move and the Rule of Zero/Five", "repo": "lab-cpp-copy-move", "href": "", "available": false, "current": false, "number": "05", "version": "", "status": "planned", "tasks": [] }, { "id": "CPP06", "title": "Ownership and Resource Types", "repo": "lab-cpp-ownership", "href": "", "available": false, "current": false, "number": "06", "version": "", "status": "planned", "tasks": [] }, { "id": "CPP07", "title": "Function and Class Templates", "repo": "lab-cpp-templates", "href": "", "available": false, "current": false, "number": "07", "version": "", "status": "planned", "tasks": [] }, { "id": "CPP08", "title": "Static Polymorphism and CRTP", "repo": "lab-cpp-static-polymorphism", "href": "", "available": false, "current": false, "number": "08", "version": "", "status": "planned", "tasks": [] }, { "id": "CPP09", "title": "Inheritance, Interfaces and Dynamic Dispatch", "repo": "lab-cpp-dynamic-polymorphism", "href": "", "available": false, "current": false, "number": "09", "version": "", "status": "planned", "tasks": [] }, { "id": "CPP10", "title": "Operator Overloading and Strong Types", "repo": "lab-cpp-strong-types", "href": "", "available": false, "current": false, "number": "10", "version": "", "status": "planned", "tasks": [] }, { "id": "CPP11", "title": "Containers, Iterators and Algorithms", "repo": "lab-cpp-containers-iterators", "href": "", "available": false, "current": false, "number": "11", "version": "", "status": "planned", "tasks": [] }, { "id": "CPP12", "title": "Lambdas, Function Objects and Callables", "repo": "lab-cpp-lambdas-callables", "href": "", "available": false, "current": false, "number": "12", "version": "", "status": "planned", "tasks": [] }, { "id": "CPP13", "title": "Error Models with and without Exceptions", "repo": "lab-cpp-error-models", "href": "", "available": false, "current": false, "number": "13", "version": "", "status": "planned", "tasks": [] }, { "id": "CPP14", "title": "Object Layout, ABI and Binary Evidence", "repo": "lab-cpp-abi-evidence", "href": "", "available": false, "current": false, "number": "14", "version": "", "status": "planned", "tasks": [] }, { "id": "CPP15", "title": "Resource-type Integration Project", "repo": "lab-cpp-resource-integration", "href": "", "available": false, "current": false, "number": "15", "version": "", "status": "planned", "tasks": [] } ] }, { "id": "freertos-c", "title": "FreeRTOS C", "current": true, "catalog_only": true, "role": "", "status": "", "cards": [ { "id": "FC01", "title": "heap_4: From Linear Cursor to Reusable Blocks", "repo": "lab-rv32i-freertos-heap4", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/aea09ab7-9bfd-5368-8d1b-c8724871c1a7", "available": true, "current": true, "number": "01", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "Predict and prove reusable heap_4 blocks" } ] }, { "id": "FC02", "title": "First Task, TCB and Task Stack", "repo": "lab-rv32i-freertos-c-first-task", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/a2538a1a-3c37-4c14-a6ea-db5aba8fd038", "available": true, "current": false, "number": "02", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "Pierwszy task FreeRTOS — callback, context, TCB i stos" } ] }, { "id": "FC03", "title": "Tick, Scheduler, Priorities and Time Slicing", "repo": "lab-rv32i-freertos-c-scheduler", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/2214a13f-34c6-40a1-a561-70a00ec98285", "available": true, "current": false, "number": "03", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "Kontrolowany eksperyment schedulera FreeRTOS" } ] }, { "id": "FC04", "title": "Delay, Blocking and Task States", "repo": "lab-rv32i-freertos-c-delay-state", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/4a7ef04c-ab08-5783-9192-5b02a90f05f8", "available": true, "current": false, "number": "04", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "Delay, blokowanie, zawieszenie i self-delete" } ] }, { "id": "FC05", "title": "Queues and Byte-copy Semantics", "repo": "lab-rv32i-freertos-c-queue", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/8ee8f36a-471b-51bc-97b8-e204bd541c61", "available": true, "current": false, "number": "05", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "Kolejka długości 1: empty, full, copy i FIFO" } ] }, { "id": "FC06", "title": "Software Timers and the Daemon Task", "repo": "lab-rv32i-freertos-c-software-timers", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/ab188300-f03d-5ddb-8316-b9534876a5bc", "available": true, "current": false, "number": "06", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "One-shot, auto-reload i timer daemon" } ] }, { "id": "FC07", "title": "Interrupt-safe API and Semaphore Handoff", "repo": "lab-rv32i-freertos-c-isr-semaphore", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/a6da1075-8d1f-5615-b0e6-0fc33e59e1e3", "available": true, "current": false, "number": "07", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "External IRQ → FromISR semaphore → high-priority task" } ] }, { "id": "FC08", "title": "Critical Sections, Mutexes and Priority Inheritance", "repo": "lab-rv32i-freertos-c-resource-management", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/2392f81a-ed6c-510b-86b5-06c5e2f1c6aa", "available": true, "current": false, "number": "08", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "Low/Medium/High: ownership i dziedziczenie priorytetu" } ] }, { "id": "FC09", "title": "Event Groups and Multi-event Synchronization", "repo": "lab-rv32i-freertos-c-event-groups", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/3f4c1b8b-d54b-58d5-b92d-87a7233cbd9f", "available": true, "current": false, "number": "09", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "ALL-ready i trzyosobowa bariera" } ] }, { "id": "FC10", "title": "Direct-to-task Notifications", "repo": "lab-rv32i-freertos-c-notifications", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/3b57334e-2c35-5207-a51d-9321906db078", "available": true, "current": false, "number": "10", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "Count, overwrite i bit flags na jednym slocie" } ] }, { "id": "FC11", "title": "Static Allocation and Bounded Storage", "repo": "lab-rv32i-freertos-c-static-allocation", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/f4d7caf3-d665-5a2d-b9eb-39a120a64ff7", "available": true, "current": false, "number": "11", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "Same behavior, two storage policies" } ] }, { "id": "FC12", "title": "Assertions, Hooks, Stack Checks and Runtime Diagnostics", "repo": "lab-rv32i-freertos-c-diagnostics", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/c3027314-85a4-5e4a-af13-0939c7467a62", "available": true, "current": false, "number": "12", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "Diagnose before changing the program" } ] }, { "id": "FC13", "title": "UART Interrupt-to-task Pipeline", "repo": "lab-rv32i-freertos-c-uart", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/6a838fd1-ab1b-52b6-baaf-659120a4d60a", "available": true, "current": false, "number": "13", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "Build and prove a bounded UART RX pipeline" } ] }, { "id": "FC14", "title": "GPIO, Hardware Timer and Deferred Work", "repo": "lab-rv32i-freertos-c-gpio-timer", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/0cc561df-bf81-5bba-9df1-c872d5b42eb8", "available": true, "current": false, "number": "14", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "Prove one machine-timer event from ISR to daemon GPIO work" } ] }, { "id": "FC15", "title": "Integrated Deterministic FreeRTOS C Application", "repo": "lab-rv32i-freertos-c-integration", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/fe92efeb-3c38-5975-86d8-ed630e1ad3bb", "available": true, "current": false, "number": "15", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "Prove one complete FreeRTOS C architecture" } ] } ] }, { "id": "freertos-cpp", "title": "FreeRTOS C++", "current": false, "catalog_only": true, "role": "", "status": "", "cards": [ { "id": "K02", "title": "C++ Task Wrapper, CRTP and Lifecycle", "repo": "lab-rv32i-freertos-task-stack-vector", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/948ce9fd-3d0c-5721-a0ae-ef422008fec8", "available": true, "current": false, "number": "02", "version": "v00.04", "status": "existing", "tasks": [ { "id": "task01", "title": "C++ Task wrapper — OOP i debugowanie cyklu życia" } ] }, { "id": "K03", "title": "Vector V1 — Destructor, Move, Ownership and RAII", "repo": "lab-rv32i-freertos-vector-raii", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/de1a2818-4c30-5760-8b31-255114f82e90", "available": true, "current": false, "number": "03", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "Vector V1 — transfer własności i powrót heapu" } ] }, { "id": "K04", "title": "Scheduler States, Priorities and Typed Ticks", "repo": "lab-rv32i-freertos-scheduler-states", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/853a7dd7-b00b-4f4a-96e8-c160fc5bb04a", "available": true, "current": false, "number": "04", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "Osiem snapshotów decyzji schedulera" } ] }, { "id": "K05", "title": "C++ Heap Bridge, Heap Models and HeapStats", "repo": "lab-rv32i-freertos-heap-models", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/c456b505-dc5c-4894-b832-bb4c5afd0feb", "available": true, "current": false, "number": "05", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "Fragmentacja, koalescencja i historyczny watermark" } ] }, { "id": "K06", "title": "MemoryResource and FreeRtosAllocator", "repo": "lab-rv32i-freertos-allocator-resource", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/1af48a2e-8564-4e18-8115-b2c0208169d6", "available": true, "current": false, "number": "06", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "Dwa zasoby, jeden typed allocator" } ] }, { "id": "K07", "title": "TaskHandle_t, Explicit Start and Static Trampoline", "repo": "lab-rv32i-freertos-task-wrapper", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/9bffead0-4341-4350-806d-e975b1a3a08f", "available": true, "current": false, "number": "07", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "Stabilny obiekt przez statyczny trampoline" } ] }, { "id": "K08", "title": "DynamicTask, StaticTask, Deletion and Lifetime", "repo": "lab-rv32i-freertos-static-task", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/d9e45417-a37f-487c-813f-fc7a44d4b4f3", "available": true, "current": false, "number": "08", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "Dwie polityki storage i pełna oś delete" } ] }, { "id": "K09", "title": "Scheduler Facade and Scoped Kernel Guards", "repo": "lab-rv32i-freertos-kernel-facade", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/6a2ab068-17e7-4bfa-b726-2df37787ed69", "available": true, "current": false, "number": "09", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "Fasada kernela i restore na każdej ścieżce" } ] }, { "id": "K10", "title": "Queue and StaticQueue", "repo": "lab-rv32i-freertos-queue", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/66967c2d-bb34-4344-8064-f54d06cce47a", "available": true, "current": false, "number": "10", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "Typed byte-copy queue z dwiema politykami storage" } ] }, { "id": "K11", "title": "Mutex, LockGuard and Priority Inheritance", "repo": "lab-rv32i-freertos-mutex", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/34d7ad61-6b03-4922-8e58-b8b98316e5f7", "available": true, "current": false, "number": "11", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "LockGuard i zmierzone priority inheritance" } ] }, { "id": "K12", "title": "Semaphores and Task Notifications", "repo": "lab-rv32i-freertos-semaphore-notify", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/fcb6107c-268f-4e86-a8cc-092e5875f6f0", "available": true, "current": false, "number": "12", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "Semaphore slots i jednoodbiorcza notification" } ] }, { "id": "K13", "title": "EventGroup and Coordinated State", "repo": "lab-rv32i-freertos-event-group", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/5fbcd7c6-3a73-4cd2-b76c-bdb016d1daaa", "available": true, "current": false, "number": "13", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "Typed EventGroup i trzy źródła stanu" } ] }, { "id": "K14", "title": "Software Timer and the Timer Daemon Task", "repo": "lab-rv32i-freertos-sw-timer", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/78db37df-63e5-4c5b-80ce-f73a411f0b50", "available": true, "current": false, "number": "14", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "Static one-shot i periodic timer na daemon tasku" } ] }, { "id": "K15", "title": "Explicit FromISR, UART and GPIO Wrappers", "repo": "lab-rv32i-freertos-isr-drivers", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/02f6cd71-5c85-4883-a237-1d4ba08d9469", "available": true, "current": false, "number": "15", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "UART queue i GPIO notify z realnego IRQ" } ] }, { "id": "K16", "title": "Integrated Real-time Application and Evidence", "repo": "lab-rv32i-freertos-integration", "href": "https://dce7fb9d-7b2f-5d49-96a2-3a30d3070b84.mpabi.pl/05b4f486-a27c-455d-a315-f4e51a4c66b3", "available": true, "current": false, "number": "16", "version": "v00.01", "status": "existing", "tasks": [ { "id": "task01", "title": "End-to-end RTOS service i evidence report" } ] } ] }, { "id": "posix-threads", "title": "POSIX Threads", "current": false, "catalog_only": true, "role": "", "status": "", "cards": [ { "id": "PT01", "title": "Process and Thread Execution Context", "repo": "lab-posix-process-thread", "href": "", "available": false, "current": false, "number": "01", "version": "", "status": "planned", "tasks": [] }, { "id": "PT02", "title": "pthread_create, pthread_join and Lifecycle", "repo": "lab-posix-pthread-create-join", "href": "", "available": false, "current": false, "number": "02", "version": "", "status": "planned", "tasks": [] }, { "id": "PT03", "title": "Arguments, Return Values and Ownership", "repo": "lab-posix-thread-arguments", "href": "", "available": false, "current": false, "number": "03", "version": "", "status": "planned", "tasks": [] }, { "id": "PT04", "title": "Data Races and the Happens-before Question", "repo": "lab-posix-data-races", "href": "", "available": false, "current": false, "number": "04", "version": "", "status": "planned", "tasks": [] }, { "id": "PT05", "title": "Mutex, Critical Section and Deadlock", "repo": "lab-posix-mutex", "href": "", "available": false, "current": false, "number": "05", "version": "", "status": "planned", "tasks": [] }, { "id": "PT06", "title": "Condition Variables and Predicates", "repo": "lab-posix-condition-variable", "href": "", "available": false, "current": false, "number": "06", "version": "", "status": "planned", "tasks": [] }, { "id": "PT07", "title": "Bounded Producer–Consumer Queue", "repo": "lab-posix-producer-consumer", "href": "", "available": false, "current": false, "number": "07", "version": "", "status": "planned", "tasks": [] }, { "id": "PT08", "title": "POSIX Semaphores", "repo": "lab-posix-semaphore", "href": "", "available": false, "current": false, "number": "08", "version": "", "status": "planned", "tasks": [] }, { "id": "PT09", "title": "Reader–Writer Lock", "repo": "lab-posix-rwlock", "href": "", "available": false, "current": false, "number": "09", "version": "", "status": "planned", "tasks": [] }, { "id": "PT10", "title": "C Atomics and Memory Ordering", "repo": "lab-posix-atomics", "href": "", "available": false, "current": false, "number": "10", "version": "", "status": "planned", "tasks": [] }, { "id": "PT11", "title": "Cancellation, Cleanup and Safe Shutdown", "repo": "lab-posix-cancellation-cleanup", "href": "", "available": false, "current": false, "number": "11", "version": "", "status": "planned", "tasks": [] }, { "id": "PT12", "title": "Thread-local Storage", "repo": "lab-posix-thread-local", "href": "", "available": false, "current": false, "number": "12", "version": "", "status": "planned", "tasks": [] }, { "id": "PT13", "title": "Scheduling Policy, Priority and Affinity", "repo": "lab-posix-scheduling", "href": "", "available": false, "current": false, "number": "13", "version": "", "status": "planned", "tasks": [] }, { "id": "PT14", "title": "GDB, Sanitizers and Race Evidence", "repo": "lab-posix-thread-debugging", "href": "", "available": false, "current": false, "number": "14", "version": "", "status": "planned", "tasks": [] }, { "id": "PT15", "title": "POSIX Threads vs FreeRTOS Integration", "repo": "lab-posix-freertos-comparison", "href": "", "available": false, "current": false, "number": "15", "version": "", "status": "planned", "tasks": [] } ] }, { "id": "oop", "title": "OOP and Design Patterns", "current": false, "catalog_only": true, "role": "reference", "status": "", "cards": [ { "id": "OOP01", "title": "Strategy — Replaceable Behaviour", "repo": "lab-cpp-oop-strategy", "href": "", "available": false, "current": false, "number": "01", "version": "", "status": "design", "tasks": [] }, { "id": "OOP02", "title": "Adapter — Stable Boundary", "repo": "lab-cpp-oop-adapter", "href": "", "available": false, "current": false, "number": "02", "version": "", "status": "planned", "tasks": [] }, { "id": "OOP03", "title": "Template Method — Fixed Skeleton", "repo": "lab-cpp-oop-template-method", "href": "", "available": false, "current": false, "number": "03", "version": "", "status": "planned", "tasks": [] }, { "id": "OOP04", "title": "Static vs Dynamic Dispatch", "repo": "lab-cpp-oop-dispatch", "href": "", "available": false, "current": false, "number": "04", "version": "", "status": "planned", "tasks": [] }, { "id": "OOP05", "title": "RAII and Ownership", "repo": "lab-cpp-oop-raii", "href": "", "available": false, "current": false, "number": "05", "version": "", "status": "planned", "tasks": [] }, { "id": "OOP06", "title": "State — Explicit Behaviour", "repo": "lab-cpp-oop-state", "href": "", "available": false, "current": false, "number": "06", "version": "", "status": "planned", "tasks": [] }, { "id": "OOP07", "title": "Facade — Subsystem Boundary", "repo": "lab-cpp-oop-facade", "href": "", "available": false, "current": false, "number": "07", "version": "", "status": "planned", "tasks": [] }, { "id": "OOP08", "title": "Command — Request as Object", "repo": "lab-cpp-oop-command", "href": "", "available": false, "current": false, "number": "08", "version": "", "status": "planned", "tasks": [] }, { "id": "OOP09", "title": "Observer — Subscription and Telemetry", "repo": "lab-cpp-oop-observer", "href": "", "available": false, "current": false, "number": "09", "version": "", "status": "planned", "tasks": [] }, { "id": "OOP10", "title": "Factory Method — Resource Policy", "repo": "lab-cpp-oop-factory-method", "href": "", "available": false, "current": false, "number": "10", "version": "", "status": "planned", "tasks": [] }, { "id": "OOP11", "title": "Builder — Valid Configuration", "repo": "lab-cpp-oop-builder", "href": "", "available": false, "current": false, "number": "11", "version": "", "status": "planned", "tasks": [] }, { "id": "OOP12", "title": "Decorator — Measurement and Diagnostics", "repo": "lab-cpp-oop-decorator", "href": "", "available": false, "current": false, "number": "12", "version": "", "status": "planned", "tasks": [] }, { "id": "OOP13", "title": "Composite — Component Tree", "repo": "lab-cpp-oop-composite", "href": "", "available": false, "current": false, "number": "13", "version": "", "status": "planned", "tasks": [] }, { "id": "OOP14", "title": "Chain of Responsibility", "repo": "lab-cpp-oop-chain", "href": "", "available": false, "current": false, "number": "14", "version": "", "status": "planned", "tasks": [] }, { "id": "OOP15", "title": "Pattern-language Integration", "repo": "lab-cpp-oop-integration", "href": "", "available": false, "current": false, "number": "15", "version": "", "status": "planned", "tasks": [] } ] } ] }, { "id": "year-3", "title": "Rok 3 · plan", "current": false, "series": [ { "id": "modern-cpp-stl", "title": "Modern C++ / STL", "current": false, "catalog_only": true, "role": "", "status": "scope-reserved", "cards": [] }, { "id": "std-threads", "title": "std::thread / std::jthread", "current": false, "catalog_only": true, "role": "", "status": "scope-reserved", "cards": [] }, { "id": "boost-asio", "title": "Boost.Asio", "current": false, "catalog_only": true, "role": "", "status": "scope-reserved", "cards": [] }, { "id": "oop", "title": "OOP and Design Patterns", "current": false, "catalog_only": true, "role": "reference", "status": "", "cards": [ { "id": "OOP01", "title": "Strategy — Replaceable Behaviour", "repo": "lab-cpp-oop-strategy", "href": "", "available": false, "current": false, "number": "01", "version": "", "status": "design", "tasks": [] }, { "id": "OOP02", "title": "Adapter — Stable Boundary", "repo": "lab-cpp-oop-adapter", "href": "", "available": false, "current": false, "number": "02", "version": "", "status": "planned", "tasks": [] }, { "id": "OOP03", "title": "Template Method — Fixed Skeleton", "repo": "lab-cpp-oop-template-method", "href": "", "available": false, "current": false, "number": "03", "version": "", "status": "planned", "tasks": [] }, { "id": "OOP04", "title": "Static vs Dynamic Dispatch", "repo": "lab-cpp-oop-dispatch", "href": "", "available": false, "current": false, "number": "04", "version": "", "status": "planned", "tasks": [] }, { "id": "OOP05", "title": "RAII and Ownership", "repo": "lab-cpp-oop-raii", "href": "", "available": false, "current": false, "number": "05", "version": "", "status": "planned", "tasks": [] }, { "id": "OOP06", "title": "State — Explicit Behaviour", "repo": "lab-cpp-oop-state", "href": "", "available": false, "current": false, "number": "06", "version": "", "status": "planned", "tasks": [] }, { "id": "OOP07", "title": "Facade — Subsystem Boundary", "repo": "lab-cpp-oop-facade", "href": "", "available": false, "current": false, "number": "07", "version": "", "status": "planned", "tasks": [] }, { "id": "OOP08", "title": "Command — Request as Object", "repo": "lab-cpp-oop-command", "href": "", "available": false, "current": false, "number": "08", "version": "", "status": "planned", "tasks": [] }, { "id": "OOP09", "title": "Observer — Subscription and Telemetry", "repo": "lab-cpp-oop-observer", "href": "", "available": false, "current": false, "number": "09", "version": "", "status": "planned", "tasks": [] }, { "id": "OOP10", "title": "Factory Method — Resource Policy", "repo": "lab-cpp-oop-factory-method", "href": "", "available": false, "current": false, "number": "10", "version": "", "status": "planned", "tasks": [] }, { "id": "OOP11", "title": "Builder — Valid Configuration", "repo": "lab-cpp-oop-builder", "href": "", "available": false, "current": false, "number": "11", "version": "", "status": "planned", "tasks": [] }, { "id": "OOP12", "title": "Decorator — Measurement and Diagnostics", "repo": "lab-cpp-oop-decorator", "href": "", "available": false, "current": false, "number": "12", "version": "", "status": "planned", "tasks": [] }, { "id": "OOP13", "title": "Composite — Component Tree", "repo": "lab-cpp-oop-composite", "href": "", "available": false, "current": false, "number": "13", "version": "", "status": "planned", "tasks": [] }, { "id": "OOP14", "title": "Chain of Responsibility", "repo": "lab-cpp-oop-chain", "href": "", "available": false, "current": false, "number": "14", "version": "", "status": "planned", "tasks": [] }, { "id": "OOP15", "title": "Pattern-language Integration", "repo": "lab-cpp-oop-integration", "href": "", "available": false, "current": false, "number": "15", "version": "", "status": "planned", "tasks": [] } ] } ] }, { "id": "year-4", "title": "Rok 4 · plan", "current": false, "series": [ { "id": "transformers-gpu", "title": "Transformers on GPU", "current": false, "catalog_only": true, "role": "", "status": "scope-reserved", "cards": [] } ] } ] }, { "id": "fiz", "title": "FIZ · Fizyka", "current": false, "levels": [ { "id": "all", "title": "Katalog", "current": false, "series": [ { "id": "fiz", "title": "Fizyka", "current": false, "catalog_only": false, "role": "", "status": "", "cards": [ { "id": "ruch-1d", "title": "Ruch 1D", "repo": "ruch-1d", "href": "", "available": false, "current": false, "number": "", "version": "", "status": "", "tasks": [] }, { "id": "ruch-2d", "title": "Ruch 2D", "repo": "ruch-2d", "href": "", "available": false, "current": false, "number": "", "version": "", "status": "", "tasks": [] }, { "id": "ruch-po-okregu", "title": "Ruch po okręgu", "repo": "ruch-po-okregu", "href": "", "available": false, "current": false, "number": "", "version": "", "status": "", "tasks": [] } ] } ] } ] } ] }, "total_pages": 7, "front": { "header_html": "
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
TITLEheap_4: From Linear Cursor to Reusable Blocks
VER.v00.01
DATETIME2026-07-20T00:00:00+02:00
PROJECTFreestanding C nad FreeRTOS
SERIESFreeRTOS C
CARD01/15
SHEET1/7
SUBJ.Inf.
PROG.
CORE
SCOPE
LEVEL
POS.
GITEA UUID87e48095-7793-54e3-9230-4e61d31bd459CARD UUIDaea09ab7-9bfd-5368-8d1b-c8724871c1a7AUTHOR  M. Pabiszczak
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
", "left_margin_html": "
TECH
", "right_margin_html": "
OG
", "goal_title": "Cel karty", "goal_html": "

Uczeń przechodzi od liniowego kursora z K&R 5.4 do wielokrotnego użycia tej samej areny: rozpoznaje nagłówek bloku, first-fit, split oraz dwustronne scalanie wolnych bloków w heap_4.

", "scope_title": "Zakres karty", "scope_html": "

Dwa małe modele C przygotowują przewidywanie. Główny replay uruchamia prawdziwe FreeRTOS-Kernel V11.3.0 heap_4 na RV32I/Hazard3 i dowodzi fragmentacji, pełnego scalenia, minimum-ever oraz kontrolowanego OOM.

", "scope_columns": [ "chapter", "task", "idea", "priority", "status", "version" ], "scope_headers": [ "Lekcja", "Task", "Najważniejsza idea", "Priorytet", "Status", "Version" ], "scope_rows": [ { "chapter": "FC01", "task": "Task01", "idea_html": "

headers, address-ordered free list, first-fit, split, coalescing and heap statistics

", "priority": "główny", "status": "ready", "status_label": "opracowane", "version": "v00.01", "key": true } ] }, "sections": [ { "id": "section-1-content", "index": 1, "title": "A1 — Od liniowego kursora do odzyskiwalnej areny", "show_heading": false, "toc_entry": true, "header_html": "
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
TITLEheap_4: From Linear Cursor to Reusable Blocks
VER.v00.01
DATETIME2026-07-20T00:00:00+02:00
PROJECTFreestanding C nad FreeRTOS
SERIESFreeRTOS C
CARD01/15
SHEET2/7
SUBJ.Inf.
PROG.
CORE
SCOPE
LEVEL
POS.
GITEA UUID87e48095-7793-54e3-9230-4e61d31bd459CARD UUIDaea09ab7-9bfd-5368-8d1b-c8724871c1a7AUTHOR  M. Pabiszczak
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
", "left_margin_html": "
TECH
-
", "right_margin_html": "
OG
-
", "content_html": "", "tasks": [], "assets": [ { "label": "fig:a1-context", "logical_label": "fig:a1-context", "figure_number": 1, "caption": "A1 CONTEXT — od żądania aplikacji do rzeczywistych bajtów ucHeap. — część 1/1 (r1 c1)", "alt": "A1 · granice odpowiedzialności heap_4", "href": "figures/a1-context.svg", "source_href": "figures/a1-context.puml", "width": 1.0, "kind": "diagram", "interactive": { "kind": "uml-class", "storage_key": "fc01-a1-context-tile-1", "title": "A1 · granice odpowiedzialności heap_4", "task": { "id": "task01", "label": "Task01 · mechanika heap_4" }, "block": { "id": "a1", "label": "A1 CONTEXT", "description": "Aplikacja korzysta z publicznego API, heap_4 zarządza jedną areną, a Hazard3 pokazuje jej rzeczywisty stan." }, "phases": [ { "id": "boundary", "label": "APPLICATION / API / ALLOCATOR / TARGET", "steps": [ { "id": "application", "number": 1, "label": "aplikacja żąda i zwalnia bajty", "mode": "CODE", "strategy_ref": "code.heap4", "svg_label": "01", "code_ref": "src/tasks/task03_freertos_heap4.c:78", "description": "Aplikacja zna wyłącznie publiczne API i wskaźniki payloadu.", "evidence": "trzy żądania 24, 40 i 16 bajtów", "strategy": { "id": "task01/a1/boundary/application", "kind": "code", "action": "open", "expected_observations": [ "heap_4 keeps metadata inside the arena", "free blocks form one address-ordered intrusive list" ], "assertions": [ "allocated bit is stored in the size field", "xStart and pxEnd are sentinels" ], "evidence_fields": [ "symbol", "list link", "block size", "arena address" ], "prerequisites": [ "FreeRTOS-Kernel V11.3.0 available" ], "layout": [ "ucHeap", "BlockLink_t", "xStart", "pxEnd" ], "commands": [ "rg -n 'BlockLink_t|prvInsertBlockIntoFreeList|pvPortMalloc|vPortFree' vendor/FreeRTOS-Kernel/portable/MemMang/heap_4.c" ], "template_id": "code.heap4" } }, { "id": "api", "number": 2, "label": "FreeRTOS wystawia malloc, free i statystyki", "mode": "CODE", "strategy_ref": "code.heap4", "svg_label": "02", "code_ref": "src/tasks/task03_freertos_heap4.c:90", "description": "API oddziela eksperyment od prywatnej listy bloków.", "evidence": "pvPortMalloc, vPortFree, vPortGetHeapStats", "strategy": { "id": "task01/a1/boundary/api", "kind": "code", "action": "open", "expected_observations": [ "heap_4 keeps metadata inside the arena", "free blocks form one address-ordered intrusive list" ], "assertions": [ "allocated bit is stored in the size field", "xStart and pxEnd are sentinels" ], "evidence_fields": [ "symbol", "list link", "block size", "arena address" ], "prerequisites": [ "FreeRTOS-Kernel V11.3.0 available" ], "layout": [ "ucHeap", "BlockLink_t", "xStart", "pxEnd" ], "commands": [ "rg -n 'BlockLink_t|prvInsertBlockIntoFreeList|pvPortMalloc|vPortFree' vendor/FreeRTOS-Kernel/portable/MemMang/heap_4.c" ], "template_id": "code.heap4" } }, { "id": "allocator", "number": 3, "label": "heap_4 zarządza blokami i kolejnością adresów", "mode": "CODE", "strategy_ref": "code.heap4", "svg_label": "03", "code_ref": "src/tasks/task03_freertos_heap4.c:70", "description": "Prywatny mechanizm wybiera, dzieli i scala wolne bloki.", "evidence": "reset i inicjalizacja listy", "strategy": { "id": "task01/a1/boundary/allocator", "kind": "code", "action": "open", "expected_observations": [ "heap_4 keeps metadata inside the arena", "free blocks form one address-ordered intrusive list" ], "assertions": [ "allocated bit is stored in the size field", "xStart and pxEnd are sentinels" ], "evidence_fields": [ "symbol", "list link", "block size", "arena address" ], "prerequisites": [ "FreeRTOS-Kernel V11.3.0 available" ], "layout": [ "ucHeap", "BlockLink_t", "xStart", "pxEnd" ], "commands": [ "rg -n 'BlockLink_t|prvInsertBlockIntoFreeList|pvPortMalloc|vPortFree' vendor/FreeRTOS-Kernel/portable/MemMang/heap_4.c" ], "template_id": "code.heap4" } }, { "id": "arena", "number": 4, "label": "ucHeap jest jedną ograniczoną areną", "mode": "CODE", "strategy_ref": "code.heap4", "svg_label": "04", "code_ref": "src/tasks/task03_freertos_heap4.c:11", "description": "Metadane i payload znajdują się w tej samej statycznej tablicy.", "evidence": "4096 bajtów, wyrównanie portu", "strategy": { "id": "task01/a1/boundary/arena", "kind": "code", "action": "open", "expected_observations": [ "heap_4 keeps metadata inside the arena", "free blocks form one address-ordered intrusive list" ], "assertions": [ "allocated bit is stored in the size field", "xStart and pxEnd are sentinels" ], "evidence_fields": [ "symbol", "list link", "block size", "arena address" ], "prerequisites": [ "FreeRTOS-Kernel V11.3.0 available" ], "layout": [ "ucHeap", "BlockLink_t", "xStart", "pxEnd" ], "commands": [ "rg -n 'BlockLink_t|prvInsertBlockIntoFreeList|pvPortMalloc|vPortFree' vendor/FreeRTOS-Kernel/portable/MemMang/heap_4.c" ], "template_id": "code.heap4" } }, { "id": "target", "number": 5, "label": "Hazard3 ujawnia adresy i bajty", "mode": "CODE", "strategy_ref": "code.identity", "svg_label": "05", "code_ref": "tests/check_task03_elf.sh:8", "description": "ELF łączy kod, symbole i pamięć obserwowaną przez GDB.", "evidence": "ucHeap i checkpointy w symbolach ELF", "strategy": { "id": "task01/a1/boundary/target", "kind": "code", "action": "open", "expected_observations": [ "upstream heap_4 symbols are linked", "checkpoint and ucHeap symbols remain observable" ], "assertions": [ "pvPortMalloc and vPortFree are present", "prvInsertBlockIntoFreeList is present" ], "evidence_fields": [ "source blob", "ELF SHA256", "image SHA256", "symbol" ], "prerequisites": [ "built ELF" ], "layout": [ "symbols", "sections", "artifact hashes" ], "commands": [ "tests/check_task03_elf.sh build/task03_freertos_heap4/prog.elf" ], "template_id": "code.identity" } } ] } ] }, "tile": { "index": 1, "count": 1, "row": 1, "column": 1, "rows": 1, "columns": 1, "x": 0.0, "y": 0.0, "width": 311.0, "height": 600.0, "full_x": 0.0, "full_y": 0.0, "full_width": 311.0, "full_height": 600.0, "page_width": 660.0, "page_height": 760.0, "overview": true, "step_ids": [ "allocator", "api", "application", "arena", "target" ] }, "diagram_title": "A1 · granice odpowiedzialności heap_4", "diagram_block_label": "A1 CONTEXT", "diagram_description": "Aplikacja korzysta z publicznego API, heap_4 zarządza jedną areną, a Hazard3 pokazuje jej rzeczywisty stan.", "diagram_phase_labels": [ "APPLICATION / API / ALLOCATOR / TARGET" ] } ], "steps": [], "spread_group": "", "spread_label": "A1 CONTEXT — od żądania aplikacji do rzeczywistych bajtów ucHeap.", "spread_columns": 1, "spread_index": 1, "spread_count": 1, "page_orientation": "portrait" }, { "id": "section-2-content", "index": 2, "title": "A2 — Nagłówek, payload i lista wolnych bloków", "show_heading": false, "toc_entry": true, "header_html": "
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
TITLEheap_4: From Linear Cursor to Reusable Blocks
VER.v00.01
DATETIME2026-07-20T00:00:00+02:00
PROJECTFreestanding C nad FreeRTOS
SERIESFreeRTOS C
CARD01/15
SHEET3/7
SUBJ.Inf.
PROG.
CORE
SCOPE
LEVEL
POS.
GITEA UUID87e48095-7793-54e3-9230-4e61d31bd459CARD UUIDaea09ab7-9bfd-5368-8d1b-c8724871c1a7AUTHOR  M. Pabiszczak
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
", "left_margin_html": "
TECH
-
", "right_margin_html": "
OG
-
", "content_html": "", "tasks": [], "assets": [ { "label": "fig:a2-structure", "logical_label": "fig:a2-structure", "figure_number": 2, "caption": "A2 STRUCTURE — metadane wewnątrz areny i adresowo uporządkowana lista. — część 1/1 (r1 c1)", "alt": "A2 · struktura bloku i listy", "href": "figures/a2-structure.svg", "source_href": "figures/a2-structure.puml", "width": 1.0, "kind": "diagram", "interactive": { "kind": "uml-class", "storage_key": "fc01-a2-structure-tile-1", "title": "A2 · struktura bloku i listy", "task": { "id": "task01", "label": "Task01 · mechanika heap_4" }, "block": { "id": "a2", "label": "A2 STRUCTURE", "description": "Każdy blok ma nagłówek, a tylko wolne bloki wykorzystują wskaźnik next do budowy listy uporządkowanej adresami." }, "phases": [ { "id": "blocks", "label": "HEADER / PAYLOAD / FREE LIST", "steps": [ { "id": "header", "number": 1, "label": "nagłówek przechowuje next i size", "mode": "CODE", "strategy_ref": "code.model", "svg_label": "01", "code_ref": "src/tasks/heap4_model.h:11", "description": "ModelBlock pokazuje minimalny kontrakt metadanych heap_4.", "evidence": "dwa słowa metadanych", "strategy": { "id": "task01/a2/blocks/header", "kind": "code", "action": "open", "expected_observations": [ "requested size includes header and alignment", "free list is ordered by block address" ], "assertions": [ "payload begins after the header", "split preserves the total arena size" ], "evidence_fields": [ "code_ref", "header bytes", "wanted bytes", "block address" ], "prerequisites": [ "K&R 5.4 linear allocator complete" ], "layout": [ "header", "payload", "remainder", "address-ordered list" ], "commands": [ "rg -n 'ModelBlock|align_up|insert_and_coalesce' src/tasks" ], "template_id": "code.model" } }, { "id": "alignment", "number": 2, "label": "żądanie obejmuje nagłówek i wyrównanie", "mode": "CODE", "strategy_ref": "code.model", "svg_label": "02", "code_ref": "src/tasks/task01_first_fit_split.c:3", "description": "13 bajtów payloadu zajmuje 32 bajty całego bloku.", "evidence": "header=16, wanted=32", "strategy": { "id": "task01/a2/blocks/alignment", "kind": "code", "action": "open", "expected_observations": [ "requested size includes header and alignment", "free list is ordered by block address" ], "assertions": [ "payload begins after the header", "split preserves the total arena size" ], "evidence_fields": [ "code_ref", "header bytes", "wanted bytes", "block address" ], "prerequisites": [ "K&R 5.4 linear allocator complete" ], "layout": [ "header", "payload", "remainder", "address-ordered list" ], "commands": [ "rg -n 'ModelBlock|align_up|insert_and_coalesce' src/tasks" ], "template_id": "code.model" } }, { "id": "split", "number": 3, "label": "split pozostawia osobny wolny blok", "mode": "CODE", "strategy_ref": "code.model", "svg_label": "03", "code_ref": "src/tasks/task01_first_fit_split.c:43", "description": "Reszta zachowuje własny nagłówek i trafia na listę wolnych.", "evidence": "32 + 224 = 256", "strategy": { "id": "task01/a2/blocks/split", "kind": "code", "action": "open", "expected_observations": [ "requested size includes header and alignment", "free list is ordered by block address" ], "assertions": [ "payload begins after the header", "split preserves the total arena size" ], "evidence_fields": [ "code_ref", "header bytes", "wanted bytes", "block address" ], "prerequisites": [ "K&R 5.4 linear allocator complete" ], "layout": [ "header", "payload", "remainder", "address-ordered list" ], "commands": [ "rg -n 'ModelBlock|align_up|insert_and_coalesce' src/tasks" ], "template_id": "code.model" } }, { "id": "address-order", "number": 4, "label": "lista jest uporządkowana rosnącymi adresami", "mode": "CODE", "strategy_ref": "code.model", "svg_label": "04", "code_ref": "src/tasks/task02_address_order_coalesce.c:29", "description": "Pozycja w liście ujawnia bezpośredniego poprzednika i następnika.", "evidence": "previous < block < current", "strategy": { "id": "task01/a2/blocks/address-order", "kind": "code", "action": "open", "expected_observations": [ "requested size includes header and alignment", "free list is ordered by block address" ], "assertions": [ "payload begins after the header", "split preserves the total arena size" ], "evidence_fields": [ "code_ref", "header bytes", "wanted bytes", "block address" ], "prerequisites": [ "K&R 5.4 linear allocator complete" ], "layout": [ "header", "payload", "remainder", "address-ordered list" ], "commands": [ "rg -n 'ModelBlock|align_up|insert_and_coalesce' src/tasks" ], "template_id": "code.model" } }, { "id": "right-join", "number": 5, "label": "blok scala się z prawym sąsiadem", "mode": "CODE", "strategy_ref": "code.model", "svg_label": "05", "code_ref": "src/tasks/task02_address_order_coalesce.c:40", "description": "Koniec zwalnianego bloku równy adresowi current oznacza ciągłość.", "evidence": "block + size == current", "strategy": { "id": "task01/a2/blocks/right-join", "kind": "code", "action": "open", "expected_observations": [ "requested size includes header and alignment", "free list is ordered by block address" ], "assertions": [ "payload begins after the header", "split preserves the total arena size" ], "evidence_fields": [ "code_ref", "header bytes", "wanted bytes", "block address" ], "prerequisites": [ "K&R 5.4 linear allocator complete" ], "layout": [ "header", "payload", "remainder", "address-ordered list" ], "commands": [ "rg -n 'ModelBlock|align_up|insert_and_coalesce' src/tasks" ], "template_id": "code.model" } }, { "id": "left-join", "number": 6, "label": "wynik scala się z lewym sąsiadem", "mode": "CODE", "strategy_ref": "code.model", "svg_label": "06", "code_ref": "src/tasks/task02_address_order_coalesce.c:48", "description": "Drugi test domyka dwustronne scalanie w jeden blok.", "evidence": "previous + size == block", "strategy": { "id": "task01/a2/blocks/left-join", "kind": "code", "action": "open", "expected_observations": [ "requested size includes header and alignment", "free list is ordered by block address" ], "assertions": [ "payload begins after the header", "split preserves the total arena size" ], "evidence_fields": [ "code_ref", "header bytes", "wanted bytes", "block address" ], "prerequisites": [ "K&R 5.4 linear allocator complete" ], "layout": [ "header", "payload", "remainder", "address-ordered list" ], "commands": [ "rg -n 'ModelBlock|align_up|insert_and_coalesce' src/tasks" ], "template_id": "code.model" } } ] } ] }, "tile": { "index": 1, "count": 1, "row": 1, "column": 1, "rows": 1, "columns": 1, "x": 0.0, "y": 0.0, "width": 295.0, "height": 620.0, "full_x": 0.0, "full_y": 0.0, "full_width": 295.0, "full_height": 620.0, "page_width": 660.0, "page_height": 760.0, "overview": true, "step_ids": [ "address-order", "alignment", "header", "left-join", "right-join", "split" ] }, "diagram_title": "A2 · struktura bloku i listy", "diagram_block_label": "A2 STRUCTURE", "diagram_description": "Każdy blok ma nagłówek, a tylko wolne bloki wykorzystują wskaźnik next do budowy listy uporządkowanej adresami.", "diagram_phase_labels": [ "HEADER / PAYLOAD / FREE LIST" ] } ], "steps": [], "spread_group": "", "spread_label": "A2 STRUCTURE — metadane wewnątrz areny i adresowo uporządkowana lista.", "spread_columns": 1, "spread_index": 1, "spread_count": 1, "page_orientation": "portrait" }, { "id": "section-3-content", "index": 3, "title": "A5 — First-fit, fragmentacja i pełne scalenie", "show_heading": false, "toc_entry": true, "header_html": "
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
TITLEheap_4: From Linear Cursor to Reusable Blocks
VER.v00.01
DATETIME2026-07-20T00:00:00+02:00
PROJECTFreestanding C nad FreeRTOS
SERIESFreeRTOS C
CARD01/15
SHEET4/7
SUBJ.Inf.
PROG.
CORE
SCOPE
LEVEL
POS.
GITEA UUID87e48095-7793-54e3-9230-4e61d31bd459CARD UUIDaea09ab7-9bfd-5368-8d1b-c8724871c1a7AUTHOR  M. Pabiszczak
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
", "left_margin_html": "
TECH
-
", "right_margin_html": "
OG
-
", "content_html": "", "tasks": [], "assets": [ { "label": "fig:a5-flow", "logical_label": "fig:a5-flow", "figure_number": 3, "caption": "A5 FLOW — inicjalizacja, A/B/C, fragmentacja, dwustronne scalenie i OOM. — część 1/1 (r1 c1)", "alt": "A5 · pełny przebieg heap_4", "href": "figures/a5-flow.svg", "source_href": "figures/a5-flow.puml", "width": 1.0, "kind": "diagram", "interactive": { "kind": "uml-sequence", "storage_key": "fc01-a5-flow-tile-1", "title": "A5 · pełny przebieg heap_4", "task": { "id": "task01", "label": "Task01 · mechanika heap_4" }, "block": { "id": "a5", "label": "A5 FLOW", "description": "Jeden przebieg A/B/C przechodzi od pustej areny przez trzy przydziały i dwa wolne obszary do ponownie scalonego bloku." }, "phases": [ { "id": "replay", "label": "ALLOCATE / FRAGMENT / COALESCE", "steps": [ { "id": "reset", "number": 1, "label": "reset i inicjalizacja areny", "mode": "CODE", "strategy_ref": "code.heap4", "svg_label": "01", "code_ref": "src/tasks/task03_freertos_heap4.c:70", "description": "Pierwsze małe żądanie inicjalizuje sentinele i listę.", "evidence": "initial free = 4080", "strategy": { "id": "task01/a5/replay/reset", "kind": "code", "action": "open", "expected_observations": [ "heap_4 keeps metadata inside the arena", "free blocks form one address-ordered intrusive list" ], "assertions": [ "allocated bit is stored in the size field", "xStart and pxEnd are sentinels" ], "evidence_fields": [ "symbol", "list link", "block size", "arena address" ], "prerequisites": [ "FreeRTOS-Kernel V11.3.0 available" ], "layout": [ "ucHeap", "BlockLink_t", "xStart", "pxEnd" ], "commands": [ "rg -n 'BlockLink_t|prvInsertBlockIntoFreeList|pvPortMalloc|vPortFree' vendor/FreeRTOS-Kernel/portable/MemMang/heap_4.c" ], "template_id": "code.heap4" } }, { "id": "alloc-a", "number": 2, "label": "first-fit przydziela A", "mode": "CODE", "strategy_ref": "code.heap4", "svg_label": "02", "code_ref": "src/tasks/task03_freertos_heap4.c:78", "description": "Pierwszy wystarczający blok zostaje rozdzielony.", "evidence": "A payload = 24", "strategy": { "id": "task01/a5/replay/alloc-a", "kind": "code", "action": "open", "expected_observations": [ "heap_4 keeps metadata inside the arena", "free blocks form one address-ordered intrusive list" ], "assertions": [ "allocated bit is stored in the size field", "xStart and pxEnd are sentinels" ], "evidence_fields": [ "symbol", "list link", "block size", "arena address" ], "prerequisites": [ "FreeRTOS-Kernel V11.3.0 available" ], "layout": [ "ucHeap", "BlockLink_t", "xStart", "pxEnd" ], "commands": [ "rg -n 'BlockLink_t|prvInsertBlockIntoFreeList|pvPortMalloc|vPortFree' vendor/FreeRTOS-Kernel/portable/MemMang/heap_4.c" ], "template_id": "code.heap4" } }, { "id": "alloc-bc", "number": 3, "label": "kolejne split tworzą B i C", "mode": "CODE", "strategy_ref": "code.heap4", "svg_label": "03", "code_ref": "src/tasks/task03_freertos_heap4.c:79", "description": "B i C zajmują kolejne fragmenty tego samego wolnego bloku.", "evidence": "after allocations = 3952", "strategy": { "id": "task01/a5/replay/alloc-bc", "kind": "code", "action": "open", "expected_observations": [ "heap_4 keeps metadata inside the arena", "free blocks form one address-ordered intrusive list" ], "assertions": [ "allocated bit is stored in the size field", "xStart and pxEnd are sentinels" ], "evidence_fields": [ "symbol", "list link", "block size", "arena address" ], "prerequisites": [ "FreeRTOS-Kernel V11.3.0 available" ], "layout": [ "ucHeap", "BlockLink_t", "xStart", "pxEnd" ], "commands": [ "rg -n 'BlockLink_t|prvInsertBlockIntoFreeList|pvPortMalloc|vPortFree' vendor/FreeRTOS-Kernel/portable/MemMang/heap_4.c" ], "template_id": "code.heap4" } }, { "id": "free-ac", "number": 4, "label": "zwolnij A i C, pozostaw B", "mode": "CODE", "strategy_ref": "code.heap4", "svg_label": "04", "code_ref": "src/tasks/task03_freertos_heap4.c:88", "description": "C scala się z prawą resztą, ale B oddziela ją od A.", "evidence": "dwa wolne bloki", "strategy": { "id": "task01/a5/replay/free-ac", "kind": "code", "action": "open", "expected_observations": [ "heap_4 keeps metadata inside the arena", "free blocks form one address-ordered intrusive list" ], "assertions": [ "allocated bit is stored in the size field", "xStart and pxEnd are sentinels" ], "evidence_fields": [ "symbol", "list link", "block size", "arena address" ], "prerequisites": [ "FreeRTOS-Kernel V11.3.0 available" ], "layout": [ "ucHeap", "BlockLink_t", "xStart", "pxEnd" ], "commands": [ "rg -n 'BlockLink_t|prvInsertBlockIntoFreeList|pvPortMalloc|vPortFree' vendor/FreeRTOS-Kernel/portable/MemMang/heap_4.c" ], "template_id": "code.heap4" } }, { "id": "fragmented", "number": 5, "label": "checkpoint fragmentacji", "mode": "RUN", "event_id": "E01", "strategy_ref": "run.fragmented", "svg_label": "05", "code_ref": "src/tasks/task03_freertos_heap4.c:91", "snapshot_ref": "task01.fragmented", "description": "GDB zatrzymuje program przy dwóch wolnych blokach.", "evidence": "xNumberOfFreeBlocks = 2", "strategy": { "id": "task01/a5/replay/fragmented", "kind": "run", "action": "replay", "expected_observations": [ "A and C are free while B remains allocated", "the free list contains two blocks" ], "assertions": [ "xNumberOfFreeBlocks equals 2", "current free bytes exceed the largest free block" ], "evidence_fields": [ "free blocks", "largest block", "free bytes", "heap bytes" ], "prerequisites": [ "clean Hazard3 RAM", "task03 image loaded" ], "layout": [ "source", "free-list stats", "ucHeap memory", "registers" ], "commands": [ "break heap4_fragmented_checkpoint", "print g_fragmented_stats", "x/64bx ucHeap" ], "template_id": "run.fragmented" } }, { "id": "free-b", "number": 6, "label": "zwolnij B między dwoma sąsiadami", "mode": "CODE", "strategy_ref": "code.heap4", "svg_label": "06", "code_ref": "src/tasks/task03_freertos_heap4.c:93", "description": "Wstawienie adresowe umożliwia dwa testy ciągłości.", "evidence": "A + B + C + reszta są ciągłe", "strategy": { "id": "task01/a5/replay/free-b", "kind": "code", "action": "open", "expected_observations": [ "heap_4 keeps metadata inside the arena", "free blocks form one address-ordered intrusive list" ], "assertions": [ "allocated bit is stored in the size field", "xStart and pxEnd are sentinels" ], "evidence_fields": [ "symbol", "list link", "block size", "arena address" ], "prerequisites": [ "FreeRTOS-Kernel V11.3.0 available" ], "layout": [ "ucHeap", "BlockLink_t", "xStart", "pxEnd" ], "commands": [ "rg -n 'BlockLink_t|prvInsertBlockIntoFreeList|pvPortMalloc|vPortFree' vendor/FreeRTOS-Kernel/portable/MemMang/heap_4.c" ], "template_id": "code.heap4" } }, { "id": "coalesced", "number": 7, "label": "arena wraca do jednego bloku", "mode": "RUN", "event_id": "E02", "strategy_ref": "run.coalesced", "svg_label": "07", "code_ref": "src/tasks/task03_freertos_heap4.c:96", "snapshot_ref": "task01.coalesced", "description": "Finalne statystyki dowodzą pełnego odzyskania areny.", "evidence": "final free = initial free; blocks = 1", "strategy": { "id": "task01/a5/replay/coalesced", "kind": "run", "action": "replay", "expected_observations": [ "freeing B joins both neighbours", "the arena returns to one reusable block" ], "assertions": [ "final free equals initial free", "minimum-ever does not rise after free", "oversized allocation returns NULL and calls the hook once" ], "evidence_fields": [ "final free", "largest block", "minimum-ever", "OOM hook", "PASS" ], "prerequisites": [ "fragmented checkpoint reached" ], "layout": [ "final stats", "minimum-ever", "OOM hook", "PASS" ], "commands": [ "break task03_debug_checkpoint", "print g_final_stats", "print g_task03_pass" ], "template_id": "run.coalesced" } }, { "id": "oom", "number": 8, "label": "zbyt duże żądanie kończy się NULL", "mode": "CODE", "strategy_ref": "code.heap4", "svg_label": "08", "code_ref": "src/tasks/task03_freertos_heap4.c:98", "description": "Kontrolowany OOM nie narusza listy i wywołuje hook dokładnie raz.", "evidence": "NULL, hooks=1, asserts=0", "strategy": { "id": "task01/a5/replay/oom", "kind": "code", "action": "open", "expected_observations": [ "heap_4 keeps metadata inside the arena", "free blocks form one address-ordered intrusive list" ], "assertions": [ "allocated bit is stored in the size field", "xStart and pxEnd are sentinels" ], "evidence_fields": [ "symbol", "list link", "block size", "arena address" ], "prerequisites": [ "FreeRTOS-Kernel V11.3.0 available" ], "layout": [ "ucHeap", "BlockLink_t", "xStart", "pxEnd" ], "commands": [ "rg -n 'BlockLink_t|prvInsertBlockIntoFreeList|pvPortMalloc|vPortFree' vendor/FreeRTOS-Kernel/portable/MemMang/heap_4.c" ], "template_id": "code.heap4" } } ] } ] }, "tile": { "index": 1, "count": 1, "row": 1, "column": 1, "rows": 1, "columns": 1, "x": 0.0, "y": 0.0, "width": 811.0, "height": 263.0, "full_x": 0.0, "full_y": 0.0, "full_width": 811.0, "full_height": 263.0, "page_width": 940.0, "page_height": 560.0, "overview": true, "step_ids": [ "alloc-a", "alloc-bc", "coalesced", "fragmented", "free-ac", "free-b", "oom", "reset" ] }, "diagram_title": "A5 · pełny przebieg heap_4", "diagram_block_label": "A5 FLOW", "diagram_description": "Jeden przebieg A/B/C przechodzi od pustej areny przez trzy przydziały i dwa wolne obszary do ponownie scalonego bloku.", "diagram_phase_labels": [ "ALLOCATE / FRAGMENT / COALESCE" ] } ], "steps": [], "spread_group": "", "spread_label": "A5 FLOW — inicjalizacja, A/B/C, fragmentacja, dwustronne scalenie i OOM.", "spread_columns": 1, "spread_index": 1, "spread_count": 1, "page_orientation": "landscape" }, { "id": "section-4-content", "index": 4, "title": "A6 — Stan bloku a stan statystyk", "show_heading": false, "toc_entry": true, "header_html": "
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
TITLEheap_4: From Linear Cursor to Reusable Blocks
VER.v00.01
DATETIME2026-07-20T00:00:00+02:00
PROJECTFreestanding C nad FreeRTOS
SERIESFreeRTOS C
CARD01/15
SHEET5/7
SUBJ.Inf.
PROG.
CORE
SCOPE
LEVEL
POS.
GITEA UUID87e48095-7793-54e3-9230-4e61d31bd459CARD UUIDaea09ab7-9bfd-5368-8d1b-c8724871c1a7AUTHOR  M. Pabiszczak
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
", "left_margin_html": "
TECH
-
", "right_margin_html": "
OG
-
", "content_html": "", "tasks": [], "assets": [ { "label": "fig:a6-state", "logical_label": "fig:a6-state", "figure_number": 4, "caption": "A6 STATE — wolny, przydzielony, rozdzielony, scalony oraz minimum-ever. — część 1/1 (r1 c1)", "alt": "A6 · stany bloków i liczników", "href": "figures/a6-state.svg", "source_href": "figures/a6-state.puml", "width": 1.0, "kind": "diagram", "interactive": { "kind": "uml-class", "storage_key": "fc01-a6-state-tile-1", "title": "A6 · stany bloków i liczników", "task": { "id": "task01", "label": "Task01 · mechanika heap_4" }, "block": { "id": "a6", "label": "A6 STATE", "description": "Bieżąca liczba wolnych bajtów może rosnąć po free, ale minimum-ever pozostaje historycznym minimum." }, "phases": [ { "id": "state", "label": "BLOCK STATE / HEAP STATS", "steps": [ { "id": "free", "number": 1, "label": "wolny blok należy do listy", "mode": "CODE", "strategy_ref": "code.heap4", "svg_label": "01", "code_ref": "src/tasks/task03_freertos_heap4.c:70", "description": "Stan początkowy zawiera jeden największy wolny blok.", "evidence": "initial free = largest free", "strategy": { "id": "task01/a6/state/free", "kind": "code", "action": "open", "expected_observations": [ "heap_4 keeps metadata inside the arena", "free blocks form one address-ordered intrusive list" ], "assertions": [ "allocated bit is stored in the size field", "xStart and pxEnd are sentinels" ], "evidence_fields": [ "symbol", "list link", "block size", "arena address" ], "prerequisites": [ "FreeRTOS-Kernel V11.3.0 available" ], "layout": [ "ucHeap", "BlockLink_t", "xStart", "pxEnd" ], "commands": [ "rg -n 'BlockLink_t|prvInsertBlockIntoFreeList|pvPortMalloc|vPortFree' vendor/FreeRTOS-Kernel/portable/MemMang/heap_4.c" ], "template_id": "code.heap4" } }, { "id": "allocated", "number": 2, "label": "przydzielony blok znika z listy wolnych", "mode": "CODE", "strategy_ref": "code.heap4", "svg_label": "02", "code_ref": "src/tasks/task03_freertos_heap4.c:78", "description": "Payload jest wyrównany, a bieżąca wolna pamięć maleje.", "evidence": "all payload pointers aligned", "strategy": { "id": "task01/a6/state/allocated", "kind": "code", "action": "open", "expected_observations": [ "heap_4 keeps metadata inside the arena", "free blocks form one address-ordered intrusive list" ], "assertions": [ "allocated bit is stored in the size field", "xStart and pxEnd are sentinels" ], "evidence_fields": [ "symbol", "list link", "block size", "arena address" ], "prerequisites": [ "FreeRTOS-Kernel V11.3.0 available" ], "layout": [ "ucHeap", "BlockLink_t", "xStart", "pxEnd" ], "commands": [ "rg -n 'BlockLink_t|prvInsertBlockIntoFreeList|pvPortMalloc|vPortFree' vendor/FreeRTOS-Kernel/portable/MemMang/heap_4.c" ], "template_id": "code.heap4" } }, { "id": "fragmented-state", "number": 3, "label": "dwa wolne bloki nie są jednym dużym blokiem", "mode": "RUN", "event_id": "E01", "strategy_ref": "run.fragmented", "svg_label": "03", "code_ref": "src/tasks/task03_freertos_heap4.c:90", "snapshot_ref": "task01.fragmented", "description": "Suma wolnego miejsca nie gwarantuje jednego dużego przydziału.", "evidence": "free blocks = 2", "strategy": { "id": "task01/a6/state/fragmented-state", "kind": "run", "action": "replay", "expected_observations": [ "A and C are free while B remains allocated", "the free list contains two blocks" ], "assertions": [ "xNumberOfFreeBlocks equals 2", "current free bytes exceed the largest free block" ], "evidence_fields": [ "free blocks", "largest block", "free bytes", "heap bytes" ], "prerequisites": [ "clean Hazard3 RAM", "task03 image loaded" ], "layout": [ "source", "free-list stats", "ucHeap memory", "registers" ], "commands": [ "break heap4_fragmented_checkpoint", "print g_fragmented_stats", "x/64bx ucHeap" ], "template_id": "run.fragmented" } }, { "id": "coalesced-state", "number": 4, "label": "scalenie przywraca jeden największy blok", "mode": "RUN", "event_id": "E02", "strategy_ref": "run.coalesced", "svg_label": "04", "code_ref": "src/tasks/task03_freertos_heap4.c:94", "snapshot_ref": "task01.coalesced", "description": "Current free i largest wracają do wartości początkowej.", "evidence": "free blocks = 1", "strategy": { "id": "task01/a6/state/coalesced-state", "kind": "run", "action": "replay", "expected_observations": [ "freeing B joins both neighbours", "the arena returns to one reusable block" ], "assertions": [ "final free equals initial free", "minimum-ever does not rise after free", "oversized allocation returns NULL and calls the hook once" ], "evidence_fields": [ "final free", "largest block", "minimum-ever", "OOM hook", "PASS" ], "prerequisites": [ "fragmented checkpoint reached" ], "layout": [ "final stats", "minimum-ever", "OOM hook", "PASS" ], "commands": [ "break task03_debug_checkpoint", "print g_final_stats", "print g_task03_pass" ], "template_id": "run.coalesced" } }, { "id": "minimum-ever", "number": 5, "label": "minimum-ever zachowuje najniższy poziom", "mode": "CODE", "strategy_ref": "code.heap4", "svg_label": "05", "code_ref": "src/tasks/task03_freertos_heap4.c:95", "description": "Historyczne minimum nie zwiększa się po odzyskaniu pamięci.", "evidence": "minimum-ever <= after allocations", "strategy": { "id": "task01/a6/state/minimum-ever", "kind": "code", "action": "open", "expected_observations": [ "heap_4 keeps metadata inside the arena", "free blocks form one address-ordered intrusive list" ], "assertions": [ "allocated bit is stored in the size field", "xStart and pxEnd are sentinels" ], "evidence_fields": [ "symbol", "list link", "block size", "arena address" ], "prerequisites": [ "FreeRTOS-Kernel V11.3.0 available" ], "layout": [ "ucHeap", "BlockLink_t", "xStart", "pxEnd" ], "commands": [ "rg -n 'BlockLink_t|prvInsertBlockIntoFreeList|pvPortMalloc|vPortFree' vendor/FreeRTOS-Kernel/portable/MemMang/heap_4.c" ], "template_id": "code.heap4" } } ] } ] }, "tile": { "index": 1, "count": 1, "row": 1, "column": 1, "rows": 1, "columns": 1, "x": 0.0, "y": 0.0, "width": 346.0, "height": 600.0, "full_x": 0.0, "full_y": 0.0, "full_width": 346.0, "full_height": 600.0, "page_width": 660.0, "page_height": 760.0, "overview": true, "step_ids": [ "allocated", "coalesced-state", "fragmented-state", "free", "minimum-ever" ] }, "diagram_title": "A6 · stany bloków i liczników", "diagram_block_label": "A6 STATE", "diagram_description": "Bieżąca liczba wolnych bajtów może rosnąć po free, ale minimum-ever pozostaje historycznym minimum.", "diagram_phase_labels": [ "BLOCK STATE / HEAP STATS" ] } ], "steps": [], "spread_group": "", "spread_label": "A6 STATE — wolny, przydzielony, rozdzielony, scalony oraz minimum-ever.", "spread_columns": 1, "spread_index": 1, "spread_count": 1, "page_orientation": "portrait" }, { "id": "section-5-content", "index": 5, "title": "A7 — Dowód w Hazard3 i ELF", "show_heading": false, "toc_entry": true, "header_html": "
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
TITLEheap_4: From Linear Cursor to Reusable Blocks
VER.v00.01
DATETIME2026-07-20T00:00:00+02:00
PROJECTFreestanding C nad FreeRTOS
SERIESFreeRTOS C
CARD01/15
SHEET6/7
SUBJ.Inf.
PROG.
CORE
SCOPE
LEVEL
POS.
GITEA UUID87e48095-7793-54e3-9230-4e61d31bd459CARD UUIDaea09ab7-9bfd-5368-8d1b-c8724871c1a7AUTHOR  M. Pabiszczak
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
", "left_margin_html": "
TECH
-
", "right_margin_html": "
OG
-
", "content_html": "", "tasks": [], "assets": [ { "label": "fig:a7-runtime", "logical_label": "fig:a7-runtime", "figure_number": 5, "caption": "A7 RUNTIME — kod, ELF, checkpoint, pamięć i statystyki jednego przebiegu. — część 1/1 (r1 c1)", "alt": "A7 · dowód runtime heap_4", "href": "figures/a7-runtime.svg", "source_href": "figures/a7-runtime.puml", "width": 1.0, "kind": "diagram", "interactive": { "kind": "uml-class", "storage_key": "fc01-a7-runtime-tile-1", "title": "A7 · dowód runtime heap_4", "task": { "id": "task01", "label": "Task01 · mechanika heap_4" }, "block": { "id": "a7", "label": "A7 RUNTIME", "description": "Ten sam artefakt łączy źródło, symbole ELF, dwa checkpointy, pamięć ucHeap i końcowe asercje." }, "phases": [ { "id": "evidence", "label": "ARTIFACT / CHECKPOINT / MEMORY / ASSERTION", "steps": [ { "id": "source", "number": 1, "label": "źródło wskazuje eksperyment A/B/C", "mode": "CODE", "strategy_ref": "code.identity", "svg_label": "01", "code_ref": "src/tasks/task03_freertos_heap4.c:62", "description": "Blob źródła jest częścią tożsamości karty.", "evidence": "source git blob", "strategy": { "id": "task01/a7/evidence/source", "kind": "code", "action": "open", "expected_observations": [ "upstream heap_4 symbols are linked", "checkpoint and ucHeap symbols remain observable" ], "assertions": [ "pvPortMalloc and vPortFree are present", "prvInsertBlockIntoFreeList is present" ], "evidence_fields": [ "source blob", "ELF SHA256", "image SHA256", "symbol" ], "prerequisites": [ "built ELF" ], "layout": [ "symbols", "sections", "artifact hashes" ], "commands": [ "tests/check_task03_elf.sh build/task03_freertos_heap4/prog.elf" ], "template_id": "code.identity" } }, { "id": "elf", "number": 2, "label": "ELF zawiera prawdziwe symbole heap_4", "mode": "CODE", "strategy_ref": "code.identity", "svg_label": "02", "code_ref": "tests/check_task03_elf.sh:8", "description": "Test ABI odrzuca atrapę bez pvPortMalloc, vPortFree i ucHeap.", "evidence": "upstream symbols present", "strategy": { "id": "task01/a7/evidence/elf", "kind": "code", "action": "open", "expected_observations": [ "upstream heap_4 symbols are linked", "checkpoint and ucHeap symbols remain observable" ], "assertions": [ "pvPortMalloc and vPortFree are present", "prvInsertBlockIntoFreeList is present" ], "evidence_fields": [ "source blob", "ELF SHA256", "image SHA256", "symbol" ], "prerequisites": [ "built ELF" ], "layout": [ "symbols", "sections", "artifact hashes" ], "commands": [ "tests/check_task03_elf.sh build/task03_freertos_heap4/prog.elf" ], "template_id": "code.identity" } }, { "id": "fragmented-runtime", "number": 3, "label": "checkpoint pokazuje dwa wolne bloki", "mode": "RUN", "event_id": "E01", "strategy_ref": "run.fragmented", "svg_label": "03", "code_ref": "src/tasks/task03_freertos_heap4.c:91", "snapshot_ref": "task01.fragmented", "description": "Neovim, GDB i pamięć zatrzymują się na tym samym stanie.", "evidence": "blocks=2 and aligned=1", "strategy": { "id": "task01/a7/evidence/fragmented-runtime", "kind": "run", "action": "replay", "expected_observations": [ "A and C are free while B remains allocated", "the free list contains two blocks" ], "assertions": [ "xNumberOfFreeBlocks equals 2", "current free bytes exceed the largest free block" ], "evidence_fields": [ "free blocks", "largest block", "free bytes", "heap bytes" ], "prerequisites": [ "clean Hazard3 RAM", "task03 image loaded" ], "layout": [ "source", "free-list stats", "ucHeap memory", "registers" ], "commands": [ "break heap4_fragmented_checkpoint", "print g_fragmented_stats", "x/64bx ucHeap" ], "template_id": "run.fragmented" } }, { "id": "memory", "number": 4, "label": "ucHeap ujawnia nagłówki i payload", "mode": "CODE", "strategy_ref": "code.heap4", "svg_label": "04", "code_ref": "src/tasks/task03_freertos_heap4.c:11", "description": "Widok bajtów łączy diagram z realnym układem areny.", "evidence": "aligned arena and in-band metadata", "strategy": { "id": "task01/a7/evidence/memory", "kind": "code", "action": "open", "expected_observations": [ "heap_4 keeps metadata inside the arena", "free blocks form one address-ordered intrusive list" ], "assertions": [ "allocated bit is stored in the size field", "xStart and pxEnd are sentinels" ], "evidence_fields": [ "symbol", "list link", "block size", "arena address" ], "prerequisites": [ "FreeRTOS-Kernel V11.3.0 available" ], "layout": [ "ucHeap", "BlockLink_t", "xStart", "pxEnd" ], "commands": [ "rg -n 'BlockLink_t|prvInsertBlockIntoFreeList|pvPortMalloc|vPortFree' vendor/FreeRTOS-Kernel/portable/MemMang/heap_4.c" ], "template_id": "code.heap4" } }, { "id": "final-runtime", "number": 5, "label": "checkpoint końcowy dowodzi odzyskania", "mode": "RUN", "event_id": "E02", "strategy_ref": "run.coalesced", "svg_label": "05", "code_ref": "src/tasks/task03_freertos_heap4.c:111", "snapshot_ref": "task01.coalesced", "description": "Jedna ramka łączy stats, OOM, hook i PASS.", "evidence": "final=initial, blocks=1, pass=1", "strategy": { "id": "task01/a7/evidence/final-runtime", "kind": "run", "action": "replay", "expected_observations": [ "freeing B joins both neighbours", "the arena returns to one reusable block" ], "assertions": [ "final free equals initial free", "minimum-ever does not rise after free", "oversized allocation returns NULL and calls the hook once" ], "evidence_fields": [ "final free", "largest block", "minimum-ever", "OOM hook", "PASS" ], "prerequisites": [ "fragmented checkpoint reached" ], "layout": [ "final stats", "minimum-ever", "OOM hook", "PASS" ], "commands": [ "break task03_debug_checkpoint", "print g_final_stats", "print g_task03_pass" ], "template_id": "run.coalesced" } } ] } ] }, "tile": { "index": 1, "count": 1, "row": 1, "column": 1, "rows": 1, "columns": 1, "x": 0.0, "y": 0.0, "width": 814.0, "height": 82.0, "full_x": 0.0, "full_y": 0.0, "full_width": 814.0, "full_height": 82.0, "page_width": 940.0, "page_height": 560.0, "overview": true, "step_ids": [ "elf", "final-runtime", "fragmented-runtime", "memory", "source" ] }, "diagram_title": "A7 · dowód runtime heap_4", "diagram_block_label": "A7 RUNTIME", "diagram_description": "Ten sam artefakt łączy źródło, symbole ELF, dwa checkpointy, pamięć ucHeap i końcowe asercje.", "diagram_phase_labels": [ "ARTIFACT / CHECKPOINT / MEMORY / ASSERTION" ] } ], "steps": [], "spread_group": "", "spread_label": "A7 RUNTIME — kod, ELF, checkpoint, pamięć i statystyki jednego przebiegu.", "spread_columns": 1, "spread_index": 1, "spread_count": 1, "page_orientation": "landscape" }, { "id": "section-6-task01", "index": 6, "title": "Task01 — mechanika heap_4", "show_heading": true, "toc_entry": true, "header_html": "
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
TITLEheap_4: From Linear Cursor to Reusable Blocks
VER.v00.01
DATETIME2026-07-20T00:00:00+02:00
PROJECTFreestanding C nad FreeRTOS
SERIESFreeRTOS C
CARD01/15
SHEET7/7
SUBJ.Inf.
PROG.
CORE
SCOPE
LEVEL
POS.
GITEA UUID87e48095-7793-54e3-9230-4e61d31bd459CARD UUIDaea09ab7-9bfd-5368-8d1b-c8724871c1a7AUTHOR  M. Pabiszczak
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
", "left_margin_html": "
TECH
-
", "right_margin_html": "
OG
-
", "content_html": "", "tasks": [ { "ref": "task01", "title": "Predict and prove reusable heap_4 blocks", "uuid": "aea09ab7-9bfd-5368-8d1b-c8724871c1a7", "criterion": "Model 13 -> 32 bajty; poprawna predykcja dwóch wolnych bloków po free(A,C) i jednego po free(B); final free = initial free; minimum-ever nie rośnie; OOM zwraca NULL; PASS=1.", "conclusion_html": "

heap_4 odzyskuje pamięć dzięki metadanym w arenie, adresowo uporządkowanej liście i scalaniu sąsiadów. Suma wolnych bajtów nie zastępuje informacji o największym bloku, a minimum-ever jest historią, nie bieżącym stanem.

", "prompt_html": "

Przewidź układ bloków po alloc A/B/C, następnie po free(A,C) i free(B). Odtwórz oba checkpointy i udowodnij, że arena została scalona bez utraty minimum-ever.

", "flow": [ { "id": "predict", "kind": "block", "title": "A — przewidywanie", "content_html": "

Przejdź przez model nagłówka, split i porządek adresowy przed uruchomieniem prawdziwego heap_4.

", "steps": [ { "id": "size", "title": "Policz rozmiar bloku.", "content_html": "

Dodaj nagłówek do 13 bajtów i wyrównaj wynik do ośmiu.

" }, { "id": "list", "title": "Narysuj listę po free(A,C).", "content_html": "

Zaznacz, dlaczego przydzielony B rozdziela dwa wolne obszary.

" } ] }, { "id": "replay", "kind": "block", "title": "B — replay Hazard3", "content_html": "

Powiąż diagram z dwoma deterministycznymi checkpointami.

", "steps": [ { "id": "fragmented", "title": "Sprawdź E01.", "content_html": "

Porównaj liczbę wolnych bloków, największy blok i bieżące wolne bajty.

" }, { "id": "coalesced", "title": "Sprawdź E02.", "content_html": "

Udowodnij pełne scalenie, zachowanie minimum-ever i kontrolowany OOM.

" } ] }, { "id": "fragmentation", "kind": "exercise", "title": "Ćwiczenie — ta sama suma, inna użyteczność", "content_html": "", "steps": [] } ] } ], "assets": [], "steps": [], "spread_group": "", "spread_label": "", "spread_columns": 1, "spread_index": 1, "spread_count": 1, "page_orientation": "portrait" } ], "viewpoints": [ { "id": "A1", "label": "CONTEXT", "subtitle": "from cursor to reusable heap", "status": "enabled", "target_label": "fig:a1-context", "target_id": "fig-a1-context" }, { "id": "A2", "label": "STRUCTURE", "subtitle": "headers and address order", "status": "enabled", "target_label": "fig:a2-structure", "target_id": "fig-a2-structure" }, { "id": "A3", "label": "DISPATCH", "subtitle": "not used by the allocator", "status": "unavailable", "reason": "heap_4 is called directly through pvPortMalloc and vPortFree; there is no callback or dispatch mechanism to explain.", "target_id": "" }, { "id": "A4", "label": "APPLICATION", "subtitle": "experiment is already explicit", "status": "unavailable", "reason": "The concrete A/B/C allocation experiment is completely represented by A5 and its two runtime checkpoints.", "target_id": "" }, { "id": "A5", "label": "FLOW", "subtitle": "allocate, fragment, coalesce", "status": "enabled", "target_label": "fig:a5-flow", "target_id": "fig-a5-flow" }, { "id": "A6", "label": "STATE", "subtitle": "block list and statistics", "status": "enabled", "target_label": "fig:a6-state", "target_id": "fig-a6-state" }, { "id": "A7", "label": "RUNTIME", "subtitle": "Hazard3 evidence", "status": "enabled", "target_label": "fig:a7-runtime", "target_id": "fig-a7-runtime" }, { "id": "A8", "label": "PATTERNS", "subtitle": "mechanism, not a separate page", "status": "unavailable", "reason": "First-fit and the intrusive address-ordered free list are already proved in A2 and A5; a separate pattern page would duplicate them.", "target_id": "" } ], "has_spread": false, "has_allocator_model": false, "dictionary": null, "toc": [ { "id": "section-1-content", "label": "1. A1 — Od liniowego kursora do odzyskiwalnej areny" }, { "id": "section-2-content", "label": "2. A2 — Nagłówek, payload i lista wolnych bloków" }, { "id": "section-3-content", "label": "3. A5 — First-fit, fragmentacja i pełne scalenie" }, { "id": "section-4-content", "label": "4. A6 — Stan bloku a stan statystyk" }, { "id": "section-5-content", "label": "5. A7 — Dowód w Hazard3 i ELF" }, { "id": "section-6-task01", "label": "6. Task01 — mechanika heap_4" } ] }