feat: add lab-rv32i-freertos-heap-models card
This commit is contained in:
@@ -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 |
|
||||
| --- | --- | --- |
|
||||
| 0–5 | choose policy | justify heap scheme for three deployments |
|
||||
| 5–9 | bridge | trace `new[] -> pvPortMalloc` and `delete[] -> vPortFree` |
|
||||
| 9–14 | predict | draw A/B/C blocks and predicted stats after freeing A/C |
|
||||
| 14–21 | Hazard3 | prove `request < total`, `request > largest`, failure |
|
||||
| 21–26 | coalescence | free B; retry same request; inspect one free block |
|
||||
| 26–30 | 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.
|
||||
|
||||
@@ -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
@@ -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}
|
||||
BIN
Binary file not shown.
Reference in New Issue
Block a user