feat: add lab-rv32i-freertos-allocator-resource card

This commit is contained in:
user
2026-07-21 19:13:55 +02:00
commit 5432095596
65 changed files with 34038 additions and 0 deletions
+106
View File
@@ -0,0 +1,106 @@
# K06 — MemoryResource and FreeRtosAllocator<T>
## Position
- Series: FreeRTOS C++
- Lesson: L05, card K06
- Duration: 30 minutes
- Runtime: FreeRTOS `heap_4.c` plus a 256-byte `.bss` arena on Hazard3
- C++ mode: freestanding C++17, no exceptions, RTTI, vtables or hosted allocator
K05 selected and measured one kernel heap. K06 adds an explicit runtime
resource boundary so identical typed code can use either that heap or caller
owned static storage.
## Outcome
After 30 minutes the student can draw the three-word resource object, explain
why it is not virtual inheritance, implement overflow-safe `count*sizeof(T)`,
classify addresses by storage domain, and state the different release policies
of a general heap and monotonic arena.
## Lesson plan — 30 minutes
| Time | Mode | Evidence |
| --- | --- | --- |
| 05 | contract | draw context + allocate/deallocate functions |
| 510 | typed count | complete and justify the overflow guard |
| 1016 | two resources | allocate 16 `uint32_t` values from heap and arena |
| 1621 | address proof | classify `ucHeap` versus `.bss`; check alignment |
| 2126 | failure | overflow and capacity failures change no storage state |
| 2630 | release | compare heap free, arena no-op deallocate and reset |
## Runtime dispatch without vtable
```cpp
struct MemoryResource {
void* context;
void* (*allocate)(void*, size_t, size_t) noexcept;
void (*deallocate)(void*, void*, size_t, size_t) noexcept;
};
```
The provider owns state; the view stores a non-owning context. `HeapResource`
counts attempts and delegates to FreeRTOS. `StaticArenaResource` stores base,
capacity and current offset. The ELF must have no vtable/typeinfo.
## Typed overflow contract
For `T` and `count`:
```text
count == 0 -> nullptr
count > SIZE_MAX / sizeof(T) -> nullptr, resource not called
otherwise bytes=count*sizeof(T) -> resource.allocate(bytes, alignof(T))
```
The failure must not wrap to a small allocation. Both resource counters and
storage state are captured before and after the overflow request.
## Canonical experiment
```text
HeapResource --MemoryResource--> FreeRtosAllocator<uint32_t> -> 16 values
address inside ucHeap; deallocate -> baseline immediately
StaticArenaResource --MemoryResource--> same typed allocator -> 16 values
address inside g_static_arena_storage (.bss)
deallocate -> used remains 64
reset -> used becomes 0
```
Both addresses satisfy `address % alignof(uint32_t) == 0` and both buffers
produce the predicted sums.
## Stable evidence
| Evidence | Required relation |
| --- | --- |
| resource representation | context and function pointers are non-null; allocate functions differ |
| heap address | lies inside `ucHeap`, aligned for `uint32_t` |
| arena address | lies in global arena range, outside `ucHeap`, aligned |
| overflow | both return null before provider failure counters increase |
| capacity failure | heap available and arena used remain unchanged |
| heap policy | successful=1, failed=1, deallocations=1; final free=baseline |
| arena policy | successful=1, failed=1; used 64 after deallocate, 0 after reset |
## Main traps
1. Multiply only after the division guard; detecting overflow after wrapping is
too late.
2. A resource view does not own its context; provider lifetime must dominate.
3. Arena `deallocate` is not heap free. Reset invalidates all arena allocations
at once and therefore needs an external lifetime boundary.
4. An alignment greater than the provider guarantee must fail explicitly.
5. This fallible allocator is not ordinary `new` and is not advertised as a
complete hosted/STL allocator.
## Acceptance
- host ASan/UBSan test validates alignment, overflow and no-op/reset behavior;
- `MemoryResource` occupies three pointers and all resource classes are
non-polymorphic;
- ABI has no vtable, RTTI, unwind, dynamic initializer or global new/delete;
- Hazard3 proves two storage domains and identical 16-element operations;
- all failure and release relations pass at checkpoint 7.
+344
View File
@@ -0,0 +1,344 @@
% 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}{06}
\newcommand{\CardCount}{16}
\newcommand{\CardSlug}{allocator-resource}
\newcommand{\CardVersion}{v00.01}
\newcommand{\DocumentUUID}{1af48a2e-8564-4e18-8115-b2c0208169d6}
\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 MemoryResource i FreeRtosAllocator<T>}\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 06/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 1af48a2e-8564-4e18-8115-b2c0208169d6}\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 1af48a2e-8564-4e18-8115-b2c0208169d6}\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-allocator-resource}{\nolinkurl{https://zsl-gitea.mpabi.pl/edu-freertos-cpp/lab-rv32i-freertos-allocator-resource}}}} \\%
\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~MEM.ALLOC}\textcolor{black!48}{\pdftooltip[width=\textwidth]{.01}{Bada typed allocation, adresy, alignment i failure state.}}\par%
\hspace*{0.54em}\textcolor{blue!70!black}{KW~LOCAL~MEM.ALLOC}\textcolor{black!48}{\pdftooltip[width=\textwidth]{.01}{Pokazuje dwa storage domains, guard przed mnożeniem i niezmienione available/used.}}\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.RESOURCE}\textcolor{black!48}{\pdftooltip[width=\textwidth]{.01}{Analizuje ownership resource view i politykę release/reset.}}\par%
\hspace*{0.54em}\textcolor{blue!70!black}{KW~LOCAL~KW~MEM.RESOURCE}\textcolor{black!48}{\pdftooltip[width=\textwidth]{.01}{Uzasadnia provider lifetime, arena no-op deallocate i zbiorczy reset.}}\par%
\end{minipage}%
}%
\end{minipage}%
}
}
\begin{document}
\sloppy
\vspace{1.0em}
\noindent{\Large\bfseries Cel karty}\par
\vspace{0.35em}
Uczeń używa jednego typed allocatora nad heapem i areną, klasyfikuje adresy oraz dowodzi, że overflow i capacity failure nie zmieniają stanu storage.
\vspace{0.8em}
\noindent\textcolor{black!25}{\rule{\textwidth}{0.35pt}}
\vspace{0.7em}
\noindent{\Large\bfseries Zakres karty}\par
\vspace{0.35em}
Resource ma context i dwa function pointers, bez vtable. Arena jest monotoniczna i resetowana zbiorczo; karta nie deklaruje zgodności z hosted STL ani automatycznego czasu życia obiektów.
\vspace{0.8em}
\noindent\textcolor{black!25}{\rule{\textwidth}{0.35pt}}
\clearpage
\ESCSectionBlockStart
\section{Resource bez wirtualności}
\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}{K06.WE01.OG.LOCAL.MEM.RESOURCE.01 | WE 01: Resource i typed allocator. Zaprojektowanie\textCR jawnego, fallible i runtime-selected źródła pamięci dla typów. | EN LOCAL MEM.RESOURCE.01:\textCR Analizuje ownership resource view i politykę release/reset. | KW LOCAL MEM.RESOURCE.01:\textCR Uzasadnia provider lifetime, arena no-op deallocate i zbiorczy reset.}\par
\vspace{0.10em}%
\noindent K1: Zapisz context i dwa różne adresy funkcji allocate.\quad D1\par
\ESCTinyStepSeparator
\noindent K2: Potwierdź brak vtable/typeinfo w ELF.\quad D1\par
\par\vspace{0.18em}%
\endgroup
Narysuj context oraz allocate/deallocate function pointers. Provider posiada stan, a MemoryResource jest nieposiadającym widokiem.
\ESCSectionBlockEnd
\ESCSectionBlockStart
\section{Overflow-safe FreeRtosAllocator<T>}
\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}{K06.WE01.TECH.LOCAL.MEM.ALLOC.01 | WE 01: Resource i typed allocator. Zaprojektowanie\textCR jawnego, fallible i runtime-selected źródła pamięci dla typów. | EK LOCAL MEM.ALLOC.01: Bada\textCR typed allocation, adresy, alignment i failure state. | KW LOCAL MEM.ALLOC.01: Pokazuje dwa\textCR storage domains, guard przed mnożeniem i niezmienione available/used.}\par
\vspace{0.10em}%
\noindent K1: Uzupełnij guard i udowodnij brak wywołania providera przy overflow.\quad D1\par
\ESCTinyStepSeparator
\noindent K2: Sprawdź niezmienione available/used po capacity failure.\quad D1\par
\par\vspace{0.18em}%
\endgroup
Sprawdź count > SIZE_MAX/sizeof(T) przed mnożeniem, potem przekaż bytes i alignof(T) do resource.
\ESCSectionBlockEnd
\ESCSectionBlockStart
\section{Heap kontra arena}
\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}{K06.WE01.TECH.LOCAL.MEM.ALLOC.01 | WE 01: Resource i typed allocator. Zaprojektowanie\textCR jawnego, fallible i runtime-selected źródła pamięci dla typów. | EK LOCAL MEM.ALLOC.01: Bada\textCR typed allocation, adresy, alignment i failure state. | KW LOCAL MEM.ALLOC.01: Pokazuje dwa\textCR storage domains, guard przed mnożeniem i niezmienione available/used.} \pdftooltip[width=\textwidth]{D2}{K06.WE01.OG.LOCAL.MEM.RESOURCE.01 | WE 01: Resource i typed allocator. Zaprojektowanie\textCR jawnego, fallible i runtime-selected źródła pamięci dla typów. | EN LOCAL MEM.RESOURCE.01:\textCR Analizuje ownership resource view i politykę release/reset. | KW LOCAL MEM.RESOURCE.01:\textCR Uzasadnia provider lifetime, arena no-op deallocate i zbiorczy reset.}\par
\vspace{0.10em}%
\noindent K1: Pokaż heap address w ucHeap i arena address w .bss.\quad D1\par
\ESCTinyStepSeparator
\noindent K2: Pokaż arena used 64, 64, 0 po allocate/deallocate/reset.\quad D2\par
\par\vspace{0.18em}%
\endgroup
Przydziel po 16 uint32_t, sprawdź zakresy i alignment, a następnie porównaj natychmiastowy heap free z arena deallocate i reset.
\ESCSectionBlockEnd
\end{document}
+274
View File
@@ -0,0 +1,274 @@
\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}{06}
\newcommand{\CardCount}{16}
\newcommand{\CardSlug}{allocator-resource}
\newcommand{\CardVersion}{v00.01}
\newcommand{\DocumentUUID}{1af48a2e-8564-4e18-8115-b2c0208169d6}
\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{K06 · FreeRTOS C++ · resource}}
\rhead{\small L05 · arena i typed allocator}
\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 \texttt{MemoryResource} i \texttt{FreeRtosAllocator<T>}}\par
\vspace{.25em}
{\large wybór storage w runtime bez vtable i bez przepełnienia}\par
\end{center}
\noindent\begin{tabularx}{\textwidth}{@{}p{1.65cm}Xp{1.55cm}X@{}}
\toprule
Karta & K06 / \CardCount & Czas & 30 minut \\
Platforma & Hazard3 / RV32I & Język & freestanding C++17 \\
Zasoby & heap + arena 256 B & Dispatch & context + 2 funkcje \\
Wersja & \CardVersion & UUID karty & \texttt{1af48a2e-...} \\
\bottomrule
\end{tabularx}
\section*{Jedna operacja typowana, dwie polityki}
Ten sam \texttt{FreeRtosAllocator<uint32\_t>} rezerwuje 16 elementów z:
\begin{itemize}
\item \texttt{HeapResource}: \texttt{pvPortMalloc/vPortFree}, pojedyncze free;
\item \texttt{StaticArenaResource}: bufor w \texttt{.bss}, liniowy offset,
pojedyncze deallocate nic nie robi, odzyskanie przez \texttt{reset()}.
\end{itemize}
\noindent\fcolorbox{accent}{accentlight}{%
\begin{minipage}{.94\textwidth}
\textbf{Kontrakt K06.} Przed \texttt{count*sizeof(T)} sprawdzamy dzielenie.
Porażka nie zmienia dostępnej pamięci ani offsetu. Widok zasobu nie posiada
kontekstu; provider musi żyć dłużej niż allocator.
\end{minipage}}
\section*{Plan 30 minut}
\noindent\begin{tabularx}{\textwidth}{@{}p{1.35cm}p{3.1cm}X@{}}
\toprule
Czas & Tryb & Dowód \\
\midrule
0--5 & kontrakt & trzy słowa: context, allocate, deallocate \\
5--10 & arytmetyka & guard przed mnożeniem count i sizeof(T) \\
10--16 & alokacja & 16 uint32 z heapu i 16 z areny \\
16--21 & adresy & ucHeap kontra globalny bufor .bss, alignment \\
21--26 & failure & overflow i capacity nie zmieniają storage \\
26--30 & release & heap free kontra arena deallocate/reset \\
\bottomrule
\end{tabularx}
\section*{Predykcja}
Rozmiar 16 elementów \texttt{uint32\_t}: \blank{2cm} B. Po arena-deallocate
\texttt{used}=\blank{2cm}; po reset \texttt{used}=\blank{2cm}.
\newpage
\section{Resource to wartość, nie hierarchia klas}
\begin{lstlisting}
class MemoryResource final {
void* context_;
void* (*allocate_)(void*, size_t, size_t) noexcept;
void (*deallocate_)(void*, void*, size_t, size_t) noexcept;
};
\end{lstlisting}
\begin{center}
\texttt{allocator -> MemoryResource -> function(context, bytes, alignment)}
\end{center}
\noindent\begin{tabularx}{\textwidth}{@{}p{4.0cm}p{4.0cm}X@{}}
\toprule
Element & Właściciel & Co sprawdzamy \\
\midrule
\texttt{MemoryResource} & nikt; non-owning view & 3 wskaźniki, bez vtable \\
\texttt{HeapResource} & liczniki providera & alignment $\le$ gwarancja portu \\
\texttt{StaticArenaResource} & bufor przekazany przez caller & base, capacity, used \\
\texttt{FreeRtosAllocator<T>} & nikt; kopiuje view & count, overflow, alignof(T) \\
\bottomrule
\end{tabularx}
Wpisz odczyty z checkpointu 1:
\noindent\begin{tabularx}{\textwidth}{@{}p{5.5cm}X@{}}
\toprule
Pole & Adres \\
\midrule
heap context & \blank{7cm} \\
arena context & \blank{7cm} \\
heap allocate function & \blank{7cm} \\
arena allocate function & \blank{7cm} \\
\bottomrule
\end{tabularx}
Funkcje allocate powinny być różne, ale kod wywołujący typed allocator jest
ten sam. Koszt dispatch to jawne pośrednie wywołanie, nie wirtualny obiekt.
\section{Guard mnożenia przed mnożeniem}
Uzupełnij:
\begin{lstlisting}
T* try_allocate(size_t count) const noexcept {
if (count == 0 || count > ________________________) {
return nullptr;
}
const size_t bytes = _____________________________;
return static_cast<T*>(resource.allocate_bytes(
bytes, ___________________));
}
\end{lstlisting}
\textbf{Dlaczego test po mnożeniu jest błędny?} Gdy wynik zawinie się do małej
liczby, allocator może zwrócić za mały, pozornie poprawny blok. W tej karcie
overflow nie wywołuje nawet funkcji providera.
\subsection*{Dwie klasy porażki}
\begin{enumerate}
\item \textbf{Arithmetic rejection}: count nie daje się bezpiecznie
przeliczyć; context nie jest dotykany.
\item \textbf{Capacity rejection}: liczba bajtów jest poprawna, ale provider
nie ma miejsca; zwraca \texttt{nullptr} i nie przesuwa storage.
\end{enumerate}
\newpage
\section{Ten sam bufor logiczny, dwa obszary adresowe}
\begin{center}
\texttt{HeapResource -> [16 * uint32] inside ucHeap}\\[.5em]
\texttt{ArenaResource -> [16 * uint32] inside g\_static\_arena\_storage}
\end{center}
\noindent\begin{tabularx}{\textwidth}{@{}p{4.7cm}p{3.4cm}X@{}}
\toprule
Dowód & Heap & Arena \\
\midrule
adres & \blank{3cm} & \blank{3cm} \\
zakres pamięci & \blank{3cm} & \blank{3cm} \\
\texttt{address \% alignof(uint32\_t)} & \blank{3cm} & \blank{3cm} \\
liczba elementów / bajtów & \blank{3cm} & \blank{3cm} \\
suma wpisanych wartości & \blank{3cm} & \blank{3cm} \\
\bottomrule
\end{tabularx}
\section*{Porażka ma zostawić stan storage bez zmian}
\begin{tabularx}{\textwidth}{@{}p{5.2cm}p{4.0cm}X@{}}
\toprule
Próba & Stan przed & Stan po \\
\midrule
overflow count dla heap allocator & free=\blank{2cm} & free=\blank{2cm} \\
overflow count dla arena allocator & used=\blank{2cm} & used=\blank{2cm} \\
za duży poprawny byte request heap & free=\blank{2cm} & free=\blank{2cm} \\
za duży poprawny byte request arena & used=\blank{2cm} & used=\blank{2cm} \\
\bottomrule
\end{tabularx}
Przy overflow provider failure count też się nie zmienia, bo wywołanie zostaje
odrzucone wcześniej. Przy capacity failure może wzrosnąć licznik nieudanych
\emph{prób}, ale ilość zajętej pamięci pozostaje taka sama.
\section*{Dwie polityki zwalniania}
\begin{center}
\begin{tabular}{c|c|c|c}
& po allocate & po deallocate & po reset \\
\hline
heap current used & 64+metadata & 0 względem baseline & nie dotyczy \\
arena used & 64 & \textbf{64} & \textbf{0}
\end{tabular}
\end{center}
Dlaczego arena nie może zwolnić „środkowego” bloku przez samo cofnięcie
offsetu? \blank{13cm}\\[1em]\blank{16cm}
Reset jest operacją zbiorczą. Wolno go wykonać dopiero, gdy żaden żywy obiekt
nie używa adresów z areny.
\newpage
\section{Hazard3/GDB: siedem checkpointów}
\begin{lstlisting}[language=bash]
make check
riscv64-unknown-elf-gdb build/task01_allocator_resource/prog.elf
b allocator_resource_debug_checkpoint
\end{lstlisting}
\noindent\begin{tabularx}{\textwidth}{@{}p{1cm}p{4.0cm}X@{}}
\toprule
STOP & Stan & Wymagany dowód \\
\midrule
1 & dwa resource views & context i function pointers zapisane \\
2 & dwa bufory żywe & heap w ucHeap, arena w .bss, alignment i sumy \\
3 & overflow rejected & oba nullptr; provider/storage bez zmian \\
4 & capacity rejected & oba nullptr; available/used bez zmian \\
5 & heap deallocated & heap current free wraca do baseline \\
6 & arena deallocated & arena used nadal 64 \\
7 & arena reset & arena used 0; liczniki i pass=1 \\
\bottomrule
\end{tabularx}
\subsection*{Odczyty}
\begin{lstlisting}
p/x g_heap_address
p/x g_arena_address
p/x g_arena_storage_begin
p/x g_arena_storage_end
p g_heap_after_capacity_failure
p g_arena_used_after_allocation
p g_arena_used_after_deallocate
p g_arena_used_after_reset
p g_heap_successful_resource_allocations
p g_heap_failed_resource_allocations
p g_arena_successful_resource_allocations
p g_arena_failed_resource_allocations
p g_allocator_resource_pass
\end{lstlisting}
\section*{Zaliczenie}
\begin{itemize}
\item $\square$ rysuję 3-słowowy resource i nie nazywam go vtable;
\item $\square$ stosuję \texttt{count > SIZE\_MAX/sizeof(T)} przed mnożeniem;
\item $\square$ klasyfikuję heap address i arena address po zakresach;
\item $\square$ pokazuję niezmieniony storage po obu rodzajach failure;
\item $\square$ odróżniam heap free, arena deallocate i arena reset;
\item $\square$ wiem, że view nie posiada providera ani bufora.
\end{itemize}
\section*{Wyjście}
Dlaczego \texttt{reset()} nie może być ukryty w destruktorze dowolnego
allocatora? \blank{12cm}\\[1em]
Co musiałoby żyć dłużej: \texttt{FreeRtosAllocator<T>} czy jego provider?
\\[.4em]\blank{8cm}
\vfill
\noindent\textbf{Następna karta K07:} posiadający obiekt taska, jawne
\texttt{start()}, stabilny kontekst i statyczny trampoline C $\rightarrow$ C++.
\end{document}