feat: add lab-rv32i-freertos-heap-models card

This commit is contained in:
user
2026-07-21 19:13:55 +02:00
commit 70fea255f9
64 changed files with 33932 additions and 0 deletions
+118
View File
@@ -0,0 +1,118 @@
# K05 — C++ heap bridge, heap models and HeapStats
## Position
- Series: FreeRTOS C++
- Lesson: L04, card K05
- Duration: 30 minutes
- Runtime: real FreeRTOS V11.3.0 `heap_4.c` on Hazard3/RV32I
- C++ mode: freestanding C++17, no exceptions, RTTI or hosted `libstdc++`
- New surface: `HeapStats`, `HeapWatermark`, complete `new`/`delete` bridge
K03 proved one-owner RAII, while K05 now exposes the allocator policy and its
metrics. It does not introduce runtime resource selection; K06 will build that
on top of the explicit failure and alignment contract established here.
## Outcome
After 30 minutes the student can choose among `heap_1``heap_5` for a stated
memory topology/lifetime policy, enumerate all C++ allocation bridge forms,
distinguish total free bytes from largest free block, and prove that
minimum-ever free bytes retain history after current free returns to baseline.
## Lesson plan — 30 minutes
| Time | Mode | Evidence |
| --- | --- | --- |
| 05 | choose policy | justify heap scheme for three deployments |
| 59 | bridge | trace `new[] -> pvPortMalloc` and `delete[] -> vPortFree` |
| 914 | predict | draw A/B/C blocks and predicted stats after freeing A/C |
| 1421 | Hazard3 | prove `request < total`, `request > largest`, failure |
| 2126 | coalescence | free B; retry same request; inspect one free block |
| 2630 | history/exit | baseline recovery versus minimum-ever history |
## Policy table
| Scheme | Free? | Coalesce? | Key deployment constraint |
| --- | --- | --- | --- |
| heap_1 | no | n/a | monotonic startup allocation only |
| heap_2 | yes | no | holes remain separate; fragmentation grows |
| heap_3 | libc | libc | linker/compiler must provide a suitable heap |
| heap_4 | yes | yes | one FreeRTOS-owned region |
| heap_5 | yes | yes | regions defined in increasing address order before allocation |
Student choices:
1. All objects allocated once at startup, never deleted: `heap_1` is a valid
simplest policy.
2. One freestanding RAM region, dynamic tasks/queues with deletion: `heap_4`.
3. Two disjoint RAM banks that must both feed the kernel allocator: `heap_5`.
`heap_3` is not treated as a portable freestanding default because it delegates
storage and behavior to the compiler C library and linker heap.
## Canonical experiment
```text
baseline: [ free ........................................ ]
allocate: [ A 2K ][ B 4K ][ C 2K ][ free ............... ]
free A/C: [ free ][ B live ][ free + trailing free ...... ]
total=12256, largest=10192, blocks=2
request 10193 -> FAIL (sum is enough, no individual block is)
free B: [ one coalesced free block ..................... ]
retry 10193 -> SUCCESS
free retry -> current free returns to baseline
minimum-ever remains at the historical low
```
Exact values may change with alignment/header configuration. Assessment uses
relations, except for the fixed requested payload sizes in the source.
## Stable evidence contract
| Evidence | Required relation |
| --- | --- |
| C++ addresses | three distinct, aligned addresses inside `ucHeap` |
| bridge counters | allocations=3, deallocations=3, live=0 |
| deallocation order | A, C, B |
| fragmented stats | free blocks >=2 and total > largest |
| failed request | largest < request < total; successful allocations unchanged |
| coalesced stats | free blocks=1; largest=current=baseline |
| retry | same request succeeds inside `ucHeap` |
| final stats | current=baseline, minimum-ever remains below current |
## Complete bridge contract
```cpp
void* operator new(size_t);
void* operator new[](size_t);
void operator delete(void*) noexcept;
void operator delete[](void*) noexcept;
void operator delete(void*, size_t) noexcept;
void operator delete[](void*, size_t) noexcept;
```
Ordinary `new` is fail-fast in this course profile because exceptions are off.
The recoverable experiment uses raw `pvPortMalloc` and checks `nullptr`.
## Misconceptions
1. Total free bytes do not imply one payload of that size can be allocated.
2. Returning to the current-free baseline does not erase the minimum-ever
watermark.
3. `heap_4` limits external fragmentation by coalescing; it cannot promise
absence of all fragmentation while live blocks separate holes.
4. A C++ bridge selects one heap domain; it does not merge five schemes.
5. `heap_3` inherits the C library/linker heap contract and is therefore not a
self-contained freestanding answer.
## Acceptance
- host test verifies field mapping and current/peak watermark calculations;
- ABI test finds all six allocation functions and no hosted C++ runtime;
- Hazard3 reaches all seven checkpoints and PASS;
- failure request lies strictly between largest block and total free bytes;
- retry succeeds only after B is freed and blocks coalesce;
- student chooses heap_1, heap_4 and heap_5 for the three stated scenarios and
justifies each constraint.
+389
View File
@@ -0,0 +1,389 @@
% Generated from json/card_source.json by tools/render_card.py.
% Do not edit manually; update the JSON and regenerate.
\documentclass[12pt,a4paper]{article}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage[utf8]{inputenc}
\usepackage[polish]{babel}
\usepackage{csquotes}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{xcolor}
\usepackage[a4paper,left=2.15cm,right=2.15cm,top=0.5cm,bottom=0.5cm,headheight=24mm,headsep=3mm,includehead]{geometry}
\usepackage{eso-pic}
\usepackage{marginnote}
\usepackage{array}
\usepackage{tabularx}
\usepackage{graphicx}
\usepackage{pdflscape}
\usepackage{float}
\usepackage{silence}
\WarningFilter{soulutf8}{This package is obsolete}
\usepackage{pdfcomment}
\usepackage{enumitem}
\usepackage{needspace}
\usepackage{fancyhdr}
\usepackage{lastpage}
\usepackage{microtype}
\usepackage[most]{tcolorbox}
\usepackage{qrcode}
\IfFileExists{references.bib}{%
\usepackage[backend=biber,style=numeric,sorting=none]{biblatex}%
\addbibresource{references.bib}%
}{}
\hypersetup{hidelinks}
\IfFileExists{build-meta.tex}{%
\input{build-meta.tex}%
}{%
\newcommand{\BuildCommit}{lokalna}%
}
\newcommand{\DocumentAuthor}{M. Pabiszczak}
\newcommand{\DocumentYear}{2026}
\newcommand{\CardSeries}{freertos-cpp}
\newcommand{\CardNumber}{05}
\newcommand{\CardCount}{16}
\newcommand{\CardSlug}{heap-models}
\newcommand{\CardVersion}{v00.01}
\newcommand{\DocumentUUID}{c456b505-dc5c-4894-b832-bb4c5afd0feb}
\newcommand{\EmptyCheck}{\(\square\)}
\newcommand{\EscAnswerLines}[1][3]{\par\noindent\dotfill\par\noindent\dotfill\par\noindent\dotfill}
\newcommand{\EscWriteRow}[1][2.8em]{\rule{0pt}{#1}}
\setlength{\parindent}{0pt}
\setlength{\parskip}{0.45em}
\setlength{\headheight}{24mm}
\setlength{\headsep}{3mm}
\setlength{\footskip}{8mm}
\setlength{\marginparwidth}{1.5cm}
\setlength{\marginparsep}{0.25cm}
\renewcommand{\arraystretch}{1.22}
% Margin separator lines disabled for layout trial.
\newcommand{\ESCPageResourceHeader}{%
\begingroup%
\setlength{\parskip}{0pt}%
\setlength{\fboxsep}{0pt}%
\setlength{\fboxrule}{0.35pt}%
\setlength{\arrayrulewidth}{0.35pt}%
\noindent\fbox{%
\begin{minipage}[c][23.5mm][c]{\dimexpr\textwidth-2\fboxrule\relax}%
\begin{minipage}[c][23mm][c]{\dimexpr\linewidth-24mm-0.35pt\relax}%
\setlength{\tabcolsep}{0pt}%
\renewcommand{\arraystretch}{0}%
\begin{tabularx}{\linewidth}{@{}p{\dimexpr0.50000000\linewidth-\arrayrulewidth\relax}|p{\dimexpr0.15126050\linewidth-\arrayrulewidth\relax}|X@{}}%
\parbox[c][5.19414mm][c]{\linewidth}{\hspace{0.45mm}{\fontsize{3.2}{3.4}\selectfont\ttfamily\bfseries TITLE}\par\nointerlineskip\vspace{0.12mm}\noindent\makebox[\linewidth][r]{{\fontsize{7.7}{7.9}\selectfont\ttfamily\bfseries Most C++ do heapu, modele i HeapStats}\hspace{0.45mm}}\par} & \parbox[c][5.19414mm][c]{\linewidth}{\hspace{0.45mm}{\fontsize{3.2}{3.4}\selectfont\ttfamily\bfseries VER.}\par\nointerlineskip\vspace{0.12mm}\noindent\makebox[\linewidth][r]{{\fontsize{6.6}{6.8}\selectfont\ttfamily\bfseries v00.01}\hspace{0.45mm}}\par} & \parbox[c][5.19414mm][c]{\linewidth}{\hspace{0.45mm}{\fontsize{3.2}{3.4}\selectfont\ttfamily\bfseries DATETIME}\par\nointerlineskip\vspace{0.12mm}\noindent\makebox[\linewidth][r]{{\fontsize{6.4}{6.6}\selectfont\ttfamily\bfseries 2026-07-19T00:00:00+02:00}\hspace{0.45mm}}\par} \\%
\end{tabularx}%
\par\nointerlineskip%
\hrule height0.35pt%
\nointerlineskip%
\begin{tabularx}{\linewidth}{@{}p{\dimexpr0.50000000\linewidth-\arrayrulewidth\relax}|p{\dimexpr0.25210084\linewidth-\arrayrulewidth\relax}|p{\dimexpr0.14285714\linewidth-\arrayrulewidth\relax}|X@{}}%
\parbox[c][5.19414mm][c]{\linewidth}{\hspace{0.45mm}{\fontsize{3.2}{3.4}\selectfont\ttfamily\bfseries PROJECT}\par\nointerlineskip\vspace{0.12mm}\noindent\makebox[\linewidth][r]{{\fontsize{7.7}{7.9}\selectfont\ttfamily\bfseries Freestanding C++ nad FreeRTOS}\hspace{0.45mm}}\par} & \parbox[c][5.19414mm][c]{\linewidth}{\hspace{0.45mm}{\fontsize{3.2}{3.4}\selectfont\ttfamily\bfseries SERIES}\par\nointerlineskip\vspace{0.12mm}\noindent\makebox[\linewidth][r]{{\fontsize{6.4}{6.6}\selectfont\ttfamily\bfseries FreeRTOS C++}\hspace{0.45mm}}\par} & \parbox[c][5.19414mm][c]{\linewidth}{\hspace{0.45mm}{\fontsize{3.2}{3.4}\selectfont\ttfamily\bfseries CARD}\par\nointerlineskip\vspace{0.12mm}\noindent\makebox[\linewidth][r]{{\fontsize{6.4}{6.6}\selectfont\ttfamily\bfseries 05/16}\hspace{0.45mm}}\par} & \parbox[c][5.19414mm][c]{\linewidth}{\hspace{0.45mm}{\fontsize{3.2}{3.4}\selectfont\ttfamily\bfseries SHEET}\par\nointerlineskip\vspace{0.12mm}\noindent\makebox[\linewidth][r]{{\fontsize{6.4}{6.6}\selectfont\ttfamily\bfseries \thepage/\pageref{LastPage}}\hspace{0.45mm}}\par} \\%
\end{tabularx}%
\par\nointerlineskip%
\hrule height0.35pt%
\nointerlineskip%
\begin{tabularx}{\linewidth}{@{}p{\dimexpr0.05882353\linewidth-\arrayrulewidth\relax}|p{\dimexpr0.05042017\linewidth-\arrayrulewidth\relax}|p{\dimexpr0.14705882\linewidth-\arrayrulewidth\relax}|p{\dimexpr0.09243697\linewidth-\arrayrulewidth\relax}|p{\dimexpr0.07563025\linewidth-\arrayrulewidth\relax}|p{\dimexpr0.07563025\linewidth-\arrayrulewidth\relax}|X@{}}%
\parbox[c][5.19414mm][c]{\linewidth}{\hspace{0.15mm}{\fontsize{2.85}{3}\selectfont\ttfamily\bfseries SUBJ.}\par\nointerlineskip\vspace{0.12mm}\noindent\makebox[\linewidth][r]{{\fontsize{4.45}{4.65}\selectfont\ttfamily\bfseries Inf.}\hspace{0.15mm}}\par} & \parbox[c][5.19414mm][c]{\linewidth}{\hspace{0.15mm}{\fontsize{2.85}{3}\selectfont\ttfamily\bfseries PROG.}\par\nointerlineskip\vspace{0.12mm}\noindent\makebox[\linewidth][r]{{\fontsize{4.45}{4.65}\selectfont\ttfamily\bfseries}\hspace{0.15mm}}\par} & \parbox[c][5.19414mm][c]{\linewidth}{\hspace{0.15mm}{\fontsize{2.85}{3}\selectfont\ttfamily\bfseries CORE}\par\nointerlineskip\vspace{0.12mm}\noindent\makebox[\linewidth][r]{{\fontsize{4.45}{4.65}\selectfont\ttfamily\bfseries}\hspace{0.15mm}}\par} & \parbox[c][5.19414mm][c]{\linewidth}{\hspace{0.15mm}{\fontsize{2.85}{3}\selectfont\ttfamily\bfseries SCOPE}\par\nointerlineskip\vspace{0.12mm}\noindent\makebox[\linewidth][r]{{\fontsize{4.45}{4.65}\selectfont\ttfamily\bfseries}\hspace{0.15mm}}\par} & \parbox[c][5.19414mm][c]{\linewidth}{\hspace{0.15mm}{\fontsize{2.85}{3}\selectfont\ttfamily\bfseries LEVEL}\par\nointerlineskip\vspace{0.12mm}\noindent\makebox[\linewidth][r]{{\fontsize{4.45}{4.65}\selectfont\ttfamily\bfseries}\hspace{0.15mm}}\par} & \parbox[c][5.19414mm][c]{\linewidth}{\hspace{0.15mm}{\fontsize{2.85}{3}\selectfont\ttfamily\bfseries POS.}\par\nointerlineskip\vspace{0.12mm}\noindent\makebox[\linewidth][r]{{\fontsize{4.45}{4.65}\selectfont\ttfamily\bfseries}\hspace{0.15mm}}\par} & \parbox[c][5.19414mm][c]{\linewidth}{\hbox to\linewidth{\hspace{0.35mm}{\fontsize{3.4}{3.75}\selectfont\ttfamily\bfseries GITEA UUID}\hfill{\fontsize{3.4}{3.75}\selectfont\ttfamily c456b505-dc5c-4894-b832-bb4c5afd0feb}\hspace{0.35mm}}\par\nointerlineskip\hbox to\linewidth{\hspace{0.35mm}{\fontsize{3.4}{3.75}\selectfont\ttfamily\bfseries CARD UUID} {\fontsize{3.4}{3.75}\selectfont\ttfamily c456b505-dc5c-4894-b832-bb4c5afd0feb}\hfill{\fontsize{3.4}{3.75}\selectfont\ttfamily\bfseries AUTHOR M. Pabiszczak}\hspace{0.35mm}}} \\%
\end{tabularx}%
\par\nointerlineskip%
\hrule height0.35pt%
\nointerlineskip%
\begin{tabularx}{\linewidth}{@{}X@{}}%
\parbox[c][3.46276mm][c]{\linewidth}{\hspace{0.45mm}{\fontsize{4.5}{4.85}\selectfont\ttfamily\bfseries GITEA} {\fontsize{4.5}{4.85}\selectfont\ttfamily\href{https://zsl-gitea.mpabi.pl/edu-freertos-cpp/lab-rv32i-freertos-heap-models}{\nolinkurl{https://zsl-gitea.mpabi.pl/edu-freertos-cpp/lab-rv32i-freertos-heap-models}}}} \\%
\end{tabularx}%
\par\nointerlineskip%
\hrule height0.35pt%
\nointerlineskip%
\begin{tabularx}{\linewidth}{@{}X@{}}%
\parbox[c][3.46276mm][c]{\linewidth}{\hspace{0.45mm}{\fontsize{4.5}{4.85}\selectfont\ttfamily\bfseries HTML} {\fontsize{4.5}{4.85}\selectfont\ttfamily\href{}{\nolinkurl{}}}} \\%
\end{tabularx}%
\end{minipage}%
\vrule width0.35pt%
\begin{minipage}[c][23mm][c]{24mm}\centering%
{\tiny QR wyłączony}%
\end{minipage}%
\end{minipage}%
}%
\endgroup%
}
\pagestyle{fancy}
\fancyhf{}
\fancyhead[C]{\ESCPageResourceHeader}
\renewcommand{\headrulewidth}{0pt}
\renewcommand{\footrulewidth}{0pt}
\newcommand{\ESCMarginTag}[4]{%
\hspace*{#1}\textcolor{#2}{#3~#4}%
}
\newcommand{\ESCSectionBlockStart}{%
\Needspace{8\baselineskip}%
\par\vspace{0.35em}%
\noindent\textcolor{black!28}{\rule{\textwidth}{0.35pt}}%
\par\vspace{0.15em}%
}
\newcommand{\ESCSectionBlockEnd}{%
\par\vspace{0.25em}%
\noindent\textcolor{black!18}{\rule{\textwidth}{0.25pt}}%
\par\vspace{0.45em}%
}
\newcommand{\ESCTinyStepSeparator}{%
\par\vspace{0.10em}%
\noindent{\color{black!18}\leaders\hbox{\rule{0.60em}{0.22pt}\hspace{0.38em}}\hfill\kern0pt}%
\par\vspace{0.10em}%
}
\newtcolorbox{ESCTaskFrame}[1]{enhanced,breakable,arc=0pt,boxrule=0.35pt,colback=white,colframe=black,boxsep=0pt,left=1.4mm,right=1.4mm,top=0.8mm,bottom=0.8mm,colbacktitle=black!7,coltitle=black,title={\ttfamily\bfseries TASK\quad #1}}
\newtcolorbox{ESCBlockFrame}[1]{enhanced,breakable,arc=0pt,boxrule=0.35pt,colback=white,colframe=black!55,boxsep=0pt,left=1.0mm,right=1.0mm,top=0.6mm,bottom=0.6mm,colbacktitle=black!4,coltitle=black,title={\ttfamily\bfseries BLOCK\quad #1}}
\newtcolorbox{ESCStepFrame}[1]{enhanced,breakable,arc=0pt,boxrule=0.35pt,colback=white,colframe=black!28,boxsep=0pt,left=0.8mm,right=0.8mm,top=0.45mm,bottom=0.45mm,colbacktitle=black!2,coltitle=black,title={\ttfamily STEP\quad #1}}
\newtcolorbox{ESCConclusionFrame}{enhanced,breakable,arc=0pt,boxrule=0.45pt,colback=blue!2,colframe=blue!45!black,boxsep=0pt,left=1.2mm,right=1.2mm,top=0.7mm,bottom=0.7mm,colbacktitle=blue!7,coltitle=black,title={\ttfamily\bfseries WNIOSEK}}
\newcommand{\ESCLearningTreeWidget}{%
\reversemarginpar
\marginnote[%
\begin{minipage}{\marginparwidth}%
\raggedright
{\fontsize{3.55}{3.95}\selectfont\ttfamily
\begin{minipage}[t]{\marginparwidth}%
\raggedright
{\bfseries\textcolor{black!65}{TECH}\par}%
\vspace{0.08em}%
\hspace*{0.00em}\textcolor{red}{WE~01}\textcolor{black!48}{}\par%
\hspace*{0.28em}\textcolor{orange!85!black}{EK~LOCAL~DBG.HEAP}\textcolor{black!48}{\pdftooltip[width=\textwidth]{.01}{Koreluje adresy, statystyki, nagłówki bloków i symbole new/delete.}}\par%
\hspace*{0.54em}\textcolor{blue!70!black}{KW~LOCAL~DBG.HEAP}\textcolor{black!48}{\pdftooltip[width=\textwidth]{.01}{Pokazuje failure, koalescencję, retry, 3/3/0 i historyczne minimum-ever.}}\par%
\end{minipage}%
}%
\end{minipage}%
]{}
\normalmarginpar
\marginnote{%
\begin{minipage}{\marginparwidth}%
\raggedright
{\fontsize{3.55}{3.95}\selectfont\ttfamily
\hspace*{0.06cm}%
\begin{minipage}[t]{\dimexpr\marginparwidth-0.06cm\relax}%
\raggedright
{\bfseries\textcolor{black!65}{OG}\par}%
\vspace{0.08em}%
\hspace*{0.00em}\textcolor{red}{WE~01}\textcolor{black!48}{}\par%
\hspace*{0.28em}\textcolor{green!50!black}{EN~LOCAL~EN~MEM.POLICY}\textcolor{black!48}{\pdftooltip[width=\textwidth]{.01}{Dobiera model i interpretuje current, largest oraz minimum-ever.}}\par%
\hspace*{0.54em}\textcolor{blue!70!black}{KW~LOCAL~KW~MEM.POLICY}\textcolor{black!48}{\pdftooltip[width=\textwidth]{.01}{Uzasadnia heap\_1, heap\_4 i heap\_5 dla trzech scenariuszy oraz nie myli total z largest.}}\par%
\end{minipage}%
}%
\end{minipage}%
}
}
\begin{document}
\sloppy
\vspace{1.0em}
\noindent{\Large\bfseries Cel karty}\par
\vspace{0.35em}
Uczeń wybiera model heapu, śledzi kompletny most C++ i dowodzi na Hazard3, że suma wolnych bajtów nie gwarantuje jednego wystarczająco dużego bloku.
\vspace{0.8em}
\noindent\textcolor{black!25}{\rule{\textwidth}{0.35pt}}
\vspace{0.7em}
\noindent{\Large\bfseries Zakres karty}\par
\vspace{0.35em}
Eksperyment linkuje wyłącznie prawdziwy \texttt{heap\_4.c}. \texttt{HeapStats} i \texttt{HeapWatermark} są tylko-odczytowymi wartościami; runtime-selected resource oraz typed allocator należą do K06.
\vspace{0.8em}
\noindent\textcolor{black!25}{\rule{\textwidth}{0.35pt}}
\clearpage
\ESCSectionBlockStart
\section{Wybór heap\_1--heap\_5}
\reversemarginpar
\marginnote[%
\begin{minipage}{\marginparwidth}%
\raggedright
{\fontsize{3.55}{3.95}\selectfont\ttfamily
\begin{minipage}[t]{\marginparwidth}%
\raggedright
{\bfseries\textcolor{black!65}{TECH}\par}%
\vspace{0.08em}%
\hspace*{0.00em}\textcolor{red}{WE~01}\textcolor{black!48}{}\par%
\end{minipage}%
}%
\end{minipage}%
]{}[-3.1em]
\normalmarginpar
\marginnote{%
\begin{minipage}{\marginparwidth}%
\raggedright
{\fontsize{3.55}{3.95}\selectfont\ttfamily
\hspace*{0.06cm}%
\begin{minipage}[t]{\dimexpr\marginparwidth-0.06cm\relax}%
\raggedright
{\bfseries\textcolor{black!65}{OG}\par}%
\vspace{0.08em}%
\hspace*{0.00em}\textcolor{red}{WE~01}\textcolor{black!48}{}\par%
\end{minipage}%
}%
\end{minipage}%
}[-3.1em]
\begingroup
\scriptsize\ttfamily\color{black!60}\sloppy
\noindent drzewka: \pdftooltip[width=\textwidth]{D1}{K05.WE01.OG.LOCAL.MEM.POLICY.01 | WE 01: Modele heapu i dowód fragmentacji. Dobranie i\textCR zbadanie polityki dynamicznej pamięci FreeRTOS dla C++. | EN LOCAL MEM.POLICY.01: Dobiera\textCR model i interpretuje current, largest oraz minimum-ever. | KW LOCAL MEM.POLICY.01: Uzasadnia\textCR heap\_1, heap\_4 i heap\_5 dla trzech scenariuszy oraz nie myli total z largest.}\par
\vspace{0.10em}%
\noindent K1: Uzasadnij heap\_1, heap\_4 i heap\_5 dla trzech wdrożeń.\quad D1\par
\ESCTinyStepSeparator
\noindent K2: Wyjaśnij zależność heap\_3 od libc i linkera.\quad D1\par
\par\vspace{0.18em}%
\endgroup
Porównaj możliwość free, koalescencję oraz źródło/regiony pamięci. Wybierz heap dla startup-only, jednej areny z delete i dwóch rozłącznych banków RAM.
\ESCSectionBlockEnd
\ESCSectionBlockStart
\section{Kompletny most C++}
\reversemarginpar
\marginnote[%
\begin{minipage}{\marginparwidth}%
\raggedright
{\fontsize{3.55}{3.95}\selectfont\ttfamily
\begin{minipage}[t]{\marginparwidth}%
\raggedright
{\bfseries\textcolor{black!65}{TECH}\par}%
\vspace{0.08em}%
\hspace*{0.00em}\textcolor{red}{WE~01}\textcolor{black!48}{}\par%
\end{minipage}%
}%
\end{minipage}%
]{}[-3.1em]
\normalmarginpar
\marginnote{%
\begin{minipage}{\marginparwidth}%
\raggedright
{\fontsize{3.55}{3.95}\selectfont\ttfamily
\hspace*{0.06cm}%
\begin{minipage}[t]{\dimexpr\marginparwidth-0.06cm\relax}%
\raggedright
{\bfseries\textcolor{black!65}{OG}\par}%
\vspace{0.08em}%
\hspace*{0.00em}\textcolor{red}{WE~01}\textcolor{black!48}{}\par%
\end{minipage}%
}%
\end{minipage}%
}[-3.1em]
\begingroup
\scriptsize\ttfamily\color{black!60}\sloppy
\noindent drzewka: \pdftooltip[width=\textwidth]{D1}{K05.WE01.TECH.LOCAL.DBG.HEAP.01 | WE 01: Modele heapu i dowód fragmentacji. Dobranie i\textCR zbadanie polityki dynamicznej pamięci FreeRTOS dla C++. | EK LOCAL DBG.HEAP.01: Koreluje\textCR adresy, statystyki, nagłówki bloków i symbole new/delete. | KW LOCAL DBG.HEAP.01: Pokazuje\textCR failure, koalescencję, retry, 3/3/0 i historyczne minimum-ever.}\par
\vspace{0.10em}%
\noindent K1: Potwierdź sześć symboli alokacji/dealokacji w ELF.\quad D1\par
\ESCTinyStepSeparator
\noindent K2: Rozdziel fail-fast new od kontrolowanego raw probe.\quad D1\par
\par\vspace{0.18em}%
\endgroup
Odszukaj scalar/array new oraz sized/unsized scalar/array delete. Zwykłe new jest fail-fast; raw pvPortMalloc pozostaje fallible.
\ESCSectionBlockEnd
\ESCSectionBlockStart
\section{Fragmentacja, koalescencja i retry}
\reversemarginpar
\marginnote[%
\begin{minipage}{\marginparwidth}%
\raggedright
{\fontsize{3.55}{3.95}\selectfont\ttfamily
\begin{minipage}[t]{\marginparwidth}%
\raggedright
{\bfseries\textcolor{black!65}{TECH}\par}%
\vspace{0.08em}%
\hspace*{0.00em}\textcolor{red}{WE~01}\textcolor{black!48}{}\par%
\end{minipage}%
}%
\end{minipage}%
]{}[-3.1em]
\normalmarginpar
\marginnote{%
\begin{minipage}{\marginparwidth}%
\raggedright
{\fontsize{3.55}{3.95}\selectfont\ttfamily
\hspace*{0.06cm}%
\begin{minipage}[t]{\dimexpr\marginparwidth-0.06cm\relax}%
\raggedright
{\bfseries\textcolor{black!65}{OG}\par}%
\vspace{0.08em}%
\hspace*{0.00em}\textcolor{red}{WE~01}\textcolor{black!48}{}\par%
\end{minipage}%
}%
\end{minipage}%
}[-3.1em]
\begingroup
\scriptsize\ttfamily\color{black!60}\sloppy
\noindent drzewka: \pdftooltip[width=\textwidth]{D1}{K05.WE01.TECH.LOCAL.DBG.HEAP.01 | WE 01: Modele heapu i dowód fragmentacji. Dobranie i\textCR zbadanie polityki dynamicznej pamięci FreeRTOS dla C++. | EK LOCAL DBG.HEAP.01: Koreluje\textCR adresy, statystyki, nagłówki bloków i symbole new/delete. | KW LOCAL DBG.HEAP.01: Pokazuje\textCR failure, koalescencję, retry, 3/3/0 i historyczne minimum-ever.}\par
\vspace{0.10em}%
\noindent K1: Zapisz dwa free blocks oraz relację request między largest i total.\quad D1\par
\ESCTinyStepSeparator
\noindent K2: Pokaż jeden blok po free B i udany retry.\quad D1\par
\par\vspace{0.18em}%
\endgroup
Zwolnij A i C wokół żywego B. Udowodnij largest < request < total oraz failure. Zwolnij B i ponów identyczne żądanie po koalescencji.
\ESCSectionBlockEnd
\ESCSectionBlockStart
\section{Watermark zachowuje historię}
\reversemarginpar
\marginnote[%
\begin{minipage}{\marginparwidth}%
\raggedright
{\fontsize{3.55}{3.95}\selectfont\ttfamily
\begin{minipage}[t]{\marginparwidth}%
\raggedright
{\bfseries\textcolor{black!65}{TECH}\par}%
\vspace{0.08em}%
\hspace*{0.00em}\textcolor{red}{WE~01}\textcolor{black!48}{}\par%
\end{minipage}%
}%
\end{minipage}%
]{}[-3.1em]
\normalmarginpar
\marginnote{%
\begin{minipage}{\marginparwidth}%
\raggedright
{\fontsize{3.55}{3.95}\selectfont\ttfamily
\hspace*{0.06cm}%
\begin{minipage}[t]{\dimexpr\marginparwidth-0.06cm\relax}%
\raggedright
{\bfseries\textcolor{black!65}{OG}\par}%
\vspace{0.08em}%
\hspace*{0.00em}\textcolor{red}{WE~01}\textcolor{black!48}{}\par%
\end{minipage}%
}%
\end{minipage}%
}[-3.1em]
\begingroup
\scriptsize\ttfamily\color{black!60}\sloppy
\noindent drzewka: \pdftooltip[width=\textwidth]{D1}{K05.WE01.OG.LOCAL.MEM.POLICY.01 | WE 01: Modele heapu i dowód fragmentacji. Dobranie i\textCR zbadanie polityki dynamicznej pamięci FreeRTOS dla C++. | EN LOCAL MEM.POLICY.01: Dobiera\textCR model i interpretuje current, largest oraz minimum-ever. | KW LOCAL MEM.POLICY.01: Uzasadnia\textCR heap\_1, heap\_4 i heap\_5 dla trzech scenariuszy oraz nie myli total z largest.}\par
\vspace{0.10em}%
\noindent K1: Porównaj final current z minimum-ever i wylicz peak.\quad D1\par
\par\vspace{0.18em}%
\endgroup
Po finalnym free current wraca do baseline, ale minimum-ever pozostaje historycznym minimum. Wylicz peak = baseline - minimum-ever.
\ESCSectionBlockEnd
\end{document}
+273
View File
@@ -0,0 +1,273 @@
\documentclass[10pt]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[polish]{babel}
\usepackage[a4paper,margin=1.55cm]{geometry}
\usepackage{array,tabularx,booktabs}
\usepackage{amsmath,amssymb}
\usepackage{xcolor,listings}
\usepackage{hyperref,fancyhdr,lastpage,enumitem}
\definecolor{accent}{HTML}{16324A}
\definecolor{accentlight}{HTML}{EEF3F7}
\definecolor{rulegray}{HTML}{D7DEE5}
\hypersetup{colorlinks=true,linkcolor=accent,urlcolor=blue}
\IfFileExists{build-meta.tex}{\input{build-meta.tex}}{\newcommand{\BuildCommit}{local}}
\newcommand{\PublisherDomain}{mpabi}
\newcommand{\CardArea}{inf}
\newcommand{\CardSeries}{freertos-cpp}
\newcommand{\CardNumber}{05}
\newcommand{\CardCount}{16}
\newcommand{\CardSlug}{heap-models}
\newcommand{\CardVersion}{v00.01}
\newcommand{\DocumentUUID}{c456b505-dc5c-4894-b832-bb4c5afd0feb}
\newcommand{\blank}[1]{\rule{#1}{.2pt}}
\lstset{
language=C++,basicstyle=\ttfamily\scriptsize,columns=fullflexible,
keepspaces=true,frame=single,breaklines=true,showstringspaces=false,
numbers=none,backgroundcolor=\color{accentlight},rulecolor=\color{rulegray}
}
\pagestyle{fancy}
\fancyhf{}
\lhead{\textbf{K05 · FreeRTOS C++ · heap}}
\rhead{\small L04 · modele, most i statystyki}
\lfoot{\scriptsize commit \BuildCommit}
\cfoot{\scriptsize \thepage/\pageref{LastPage}}
\rfoot{\scriptsize V11.3.0 / \CardVersion}
\setlength{\headheight}{14pt}
\setlength{\footskip}{19pt}
\setlist[itemize]{nosep,leftmargin=1.45em}
\setlist[enumerate]{nosep,leftmargin=1.65em}
\begin{document}
\sloppy
\begin{center}
{\LARGE\bfseries Most C++ do heapu, modele i \texttt{HeapStats}}\par
\vspace{.25em}
{\large suma wolnych bajtów nie jest największym blokiem}\par
\end{center}
\noindent\begin{tabularx}{\textwidth}{@{}p{1.65cm}Xp{1.55cm}X@{}}
\toprule
Karta & K05 / \CardCount & Czas & 30 minut \\
Platforma & Hazard3 / RV32I & Język & freestanding C++17 \\
Allocator & prawdziwy \texttt{heap\_4.c} & Kernel & V11.3.0, bez zmian \\
Wersja & \CardVersion & UUID karty & \texttt{c456b505-...} \\
\bottomrule
\end{tabularx}
\section*{Trzy pytania, jeden eksperyment}
\begin{enumerate}
\item Która polityka \texttt{heap\_1...heap\_5} pasuje do topologii pamięci?
\item Czy każdy wariant \texttt{new/delete} trafia do jednego heapu FreeRTOS?
\item Czy bieżące free, największy blok i minimum-ever dowodzą tego samego?
\end{enumerate}
\noindent\fcolorbox{accent}{accentlight}{%
\begin{minipage}{.94\textwidth}
\textbf{Inwariant K05.} Każdy żywy blok ma właściciela, a każda decyzja o
pojemności używa co najmniej pary: suma wolnych bajtów i największy wolny blok.
Minimum-ever jest historią i nie rośnie po zwolnieniu pamięci.
\end{minipage}}
\section*{Plan 30 minut}
\noindent\begin{tabularx}{\textwidth}{@{}p{1.35cm}p{3.0cm}X@{}}
\toprule
Czas & Tryb & Dowód ucznia \\
\midrule
0--5 & wybór modelu & heap dla trzech scenariuszy \\
5--9 & most C++ & komplet scalar/array, sized/unsized \\
9--14 & predykcja & układ A--B--C i dwie dziury po free \\
14--21 & fragmentacja & largest $<$ request $<$ total, wynik NULL \\
21--26 & koalescencja & jedno free, identyczny request działa \\
26--30 & historia & current wraca, minimum-ever zostaje \\
\bottomrule
\end{tabularx}
\section*{Najpierw wybierz}
Tylko startup, brak free: \blank{2cm}\quad Jedna arena + delete:
\blank{2cm}\quad Dwa rozłączne banki RAM: \blank{2cm}
\newpage
\section{Pięć modeli, ale jeden w obrazie programu}
\noindent\begin{tabularx}{\textwidth}{@{}p{1.55cm}p{1.55cm}p{2.2cm}X@{}}
\toprule
Model & Free & Koalescencja & Kontrakt / typowe użycie \\
\midrule
\texttt{heap\_1} & nie & nie dotyczy & monotoniczna arena; alokuj raz i nie zwalniaj \\
\texttt{heap\_2} & tak & nie & odzyskuje bloki, lecz sąsiednie dziury pozostają osobne \\
\texttt{heap\_3} & libc & zależy od libc & deleguje do \texttt{malloc/free}; wymaga heapu linkera \\
\texttt{heap\_4} & tak & sąsiednich & jedna arena FreeRTOS; wybór tej serii na Hazard3 \\
\texttt{heap\_5} & tak & w regionach & wiele regionów zdefiniowanych przed pierwszą alokacją \\
\bottomrule
\end{tabularx}
\textbf{Nie łączymy implementacji.} Do obrazu linkujemy jeden plik, który
definiuje \texttt{pvPortMalloc} i \texttt{vPortFree}. Most C++ zmienia składnię,
nie politykę wybranego allocatora.
\subsection*{Uzasadnij trzy wdrożenia}
\begin{enumerate}
\item Wszystkie obiekty powstają przed schedulerem i nigdy nie są usuwane:
model \blank{2cm}, ponieważ \blank{9cm}.
\item Zadania i kolejki powstają/nikną w jednej arenie RAM:
model \blank{2cm}, ponieważ \blank{9cm}.
\item Dwa rozłączne banki RAM mają zasilać jeden allocator:
model \blank{2cm}, ponieważ \blank{9cm}.
\end{enumerate}
\section{Kompletny most C++}
\begin{lstlisting}
void* operator new(size_t n); void* operator new[](size_t n);
void operator delete(void* p) noexcept;
void operator delete[](void* p) noexcept;
void operator delete(void* p, size_t) noexcept;
void operator delete[](void* p, size_t) noexcept;
\end{lstlisting}
\begin{center}
\texttt{new/new[] -> pvPortMalloc}\qquad
\texttt{delete/delete[] -> vPortFree}
\end{center}
W profilu bez wyjątków zwykłe \texttt{new} jest \textbf{fail-fast}. Próba
kontrolowanej porażki używa jawnie \texttt{pvPortMalloc} i sprawdza
\texttt{nullptr}; nie zmienia kontraktu ordinary new.
\subsection*{Dlaczego sized delete też musi istnieć?}
Kompilator może wybrać wariant z drugim argumentem rozmiaru. Brak definicji
oznacza niekompletny most albo zależność od niedostępnego runtime. W ELF
zaznacz sześć znalezionych symboli: \blank{10cm}
\newpage
\section{Eksperyment: total wystarcza, blok nie}
\begin{center}
\texttt{baseline: [ FREE ......................................... ]}\\[.4em]
\texttt{allocate: [ A 2K ][ B 4K ][ C 2K ][ FREE ............... ]}\\[.4em]
\texttt{free A,C: [ FREE ][ B LIVE ][ FREE + trailing free ...... ]}
\end{center}
Po zwolnieniu A i C blok B nadal rozdziela wolne obszary. \texttt{heap\_4}
scala C z końcowym free, ale nie może scalić przez żywy B.
\noindent\begin{tabularx}{\textwidth}{@{}p{4.9cm}p{3.2cm}X@{}}
\toprule
Wielkość & Predykcja & Odczyt Hazard3 \\
\midrule
\texttt{available\_bytes} & \blank{2.6cm} & \blank{4cm} \\
\texttt{largest\_free\_block} & \blank{2.6cm} & \blank{4cm} \\
\texttt{free\_blocks} & \blank{2.6cm} & \blank{4cm} \\
\texttt{request = largest + 1} & \blank{2.6cm} & \blank{4cm} \\
wynik pierwszej próby & \blank{2.6cm} & \blank{4cm} \\
\bottomrule
\end{tabularx}
\section*{Relacja, nie przypadkowe liczby}
\begin{center}
\fbox{\texttt{largest < request < available} \quad i mimo tego \quad
\texttt{result == nullptr}}
\end{center}
Wyjaśnienie: \blank{14cm}\\[1.1em]
\blank{16cm}
\section*{Zwolnij B i ponów identyczne żądanie}
\begin{center}
\texttt{free B: [ ONE COALESCED FREE BLOCK ...................... ]}
\end{center}
Wtedy wymagamy:
\begin{itemize}
\item \texttt{free\_blocks ==} \blank{1.5cm};
\item \texttt{largest == available == baseline}: \blank{5cm};
\item ponowienie \emph{tego samego} request: \blank{4cm};
\item adres retry leży w \texttt{ucHeap}: \blank{4cm}.
\end{itemize}
\section*{Nagłówek i wyrównanie też kosztują}
Statystyka największego wolnego bloku opisuje blok allocatora. Żądany payload
potrzebuje jeszcze wyrównanego nagłówka. Dlatego nie zamieniaj pola
\texttt{largest} w bezwarunkową gwarancję payloadu tej samej wielkości.
\newpage
\section{Siedem checkpointów i historia minimum-ever}
\begin{lstlisting}[language=bash]
make check
riscv64-unknown-elf-gdb build/task01_heap_models/prog.elf
b heap_models_debug_checkpoint
\end{lstlisting}
\noindent\begin{tabularx}{\textwidth}{@{}p{1.05cm}p{3.75cm}X@{}}
\toprule
STOP & Stan & Obowiązkowy dowód \\
\midrule
1 & baseline & jedno free; zapisz current i minimum-ever \\
2 & A+B+C żywe & trzy adresy; free spada; payload zachowany \\
3 & A/C zwolnione & dwa free; total $>$ largest \\
4 & kontrolowany fail & request między largest i total; alloc count bez zmiany \\
5 & B zwolnione & jeden blok; largest=current=baseline \\
6 & retry żywe & ten sam request działa; min-ever osiąga nowe minimum \\
7 & retry zwolnione & current=baseline, minimum-ever nadal niższe \\
\bottomrule
\end{tabularx}
\subsection*{Minimalny zestaw GDB}
\begin{lstlisting}
p g_baseline_stats
p g_after_alloc_stats
p g_fragmented_stats
p g_after_failure_stats
p g_coalesced_stats
p g_after_retry_stats
p g_final_stats
p g_cpp_allocation_addresses
p g_cpp_deallocation_addresses
p g_peak_bytes_used
p g_heap_models_pass
\end{lstlisting}
\section*{Current kontra watermark}
\begin{tabularx}{\textwidth}{@{}p{5.4cm}X@{}}
\toprule
Warunek końcowy & Odczyt \\
\midrule
\texttt{final.available == baseline.available} & \blank{6cm} \\
\texttt{final.minimum\_ever < final.available} & \blank{6cm} \\
\texttt{peak = baseline - minimum\_ever} & \blank{6cm} \\
\texttt{alloc/free/live == 3/3/0} dla C++ & \blank{6cm} \\
kolejność zwolnień adresów = A,C,B & \blank{6cm} \\
\texttt{pass == 1} & \blank{6cm} \\
\bottomrule
\end{tabularx}
\section*{Wyjście}
\begin{enumerate}
\item Dlaczego 12 KB total free nie obiecuje jednego bloku 10 KB?\\[.8em]
\item Co zmieniło zwolnienie B, skoro suma free też tylko wzrosła?\\[.8em]
\item Dlaczego minimum-ever nie wróciło wraz z current free?\\[.8em]
\item Dlaczego \texttt{heap\_3} nie jest samowystarczalnym wyborem freestanding?\\[.8em]
\end{enumerate}
\vfill
\noindent\textbf{Następna karta K06:} nie-wirtualny \texttt{MemoryResource},
\texttt{HeapResource}, arena statyczna i typowany \texttt{FreeRtosAllocator<T>}.
\end{document}