diff options
-rw-r--r-- | content/2023-01-14-xpost-matcha-threads/gen-svg.sh | 3 | ||||
-rw-r--r-- | content/2023-01-14-xpost-matcha-threads/index.md (renamed from content/2023-01-14-xpost-matcha-threads.md) | 18 | ||||
-rw-r--r-- | content/2023-01-14-xpost-matcha-threads/os-vs-user-threads.drawio | 184 | ||||
-rw-r--r-- | content/2023-01-14-xpost-matcha-threads/os-vs-user-threads.svg | 3 | ||||
-rw-r--r-- | content/2024-04-24-fn-wrapper-macro-magic/index.md | 105 |
5 files changed, 288 insertions, 25 deletions
diff --git a/content/2023-01-14-xpost-matcha-threads/gen-svg.sh b/content/2023-01-14-xpost-matcha-threads/gen-svg.sh new file mode 100644 index 0000000..365e243 --- /dev/null +++ b/content/2023-01-14-xpost-matcha-threads/gen-svg.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +drawio -x -f svg -t --svg-theme dark -o os-vs-user-threads.svg os-vs-user-threads.drawio diff --git a/content/2023-01-14-xpost-matcha-threads.md b/content/2023-01-14-xpost-matcha-threads/index.md index 9500300..3456b09 100644 --- a/content/2023-01-14-xpost-matcha-threads.md +++ b/content/2023-01-14-xpost-matcha-threads/index.md @@ -66,6 +66,24 @@ Implementations for different ISAs are available here: - [armv7a][yield-arm] - [riscv64][yield-rv64] +## Appendix: os-level vs user-level threading + +The figure below depicts *os-level* threading (left) vs *user-level* threading +(right). + +The main difference is that in the case of user-level threading, the operating +system (os) does not now anything about the user threads. In the concrete +example, only a **single** user thread can run at any given time, whereas in +the case of os-level threading, all threads can run truly parallel. + +When a user-level thread is scheduled, the *stack-pointer* (sp) of the os +thread is adjusted to the user threads' stack. For the example below, if the +user thread **A** is scheduled (yielded to), the stack-pointer for the os +thread **S** is switched to the **stack A**. Once the user thread yields back +to the scheduler, the stack-pointer is switched back to **stack S**. + +<img src="os-vs-user-threads.svg"> + [matcha]: https://github.com/johannst/matcha-threads [yield-x86]: https://github.com/johannst/matcha-threads/blob/master/lib/arch/x86_64/yield.s [yield-arm]: https://github.com/johannst/matcha-threads/blob/master/lib/arch/arm/yield.s diff --git a/content/2023-01-14-xpost-matcha-threads/os-vs-user-threads.drawio b/content/2023-01-14-xpost-matcha-threads/os-vs-user-threads.drawio new file mode 100644 index 0000000..d927873 --- /dev/null +++ b/content/2023-01-14-xpost-matcha-threads/os-vs-user-threads.drawio @@ -0,0 +1,184 @@ +<mxfile host="Electron" modified="2024-04-28T17:23:14.014Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/23.1.5 Chrome/120.0.6099.109 Electron/28.1.0 Safari/537.36" etag="TuK57NxBkEhxkh0WYATU" version="23.1.5" type="device"> + <diagram name="Page-1" id="eupsqoG42ICuPfNcTmHv"> + <mxGraphModel dx="231" dy="139" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0"> + <root> + <mxCell id="0" /> + <mxCell id="1" parent="0" /> + <mxCell id="6WErTb2tg34p5fqduLaV-2" value="" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=monospace;fillColor=none;" parent="1" vertex="1"> + <mxGeometry x="360" y="290" width="120" height="260" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-3" value="<font>process address space</font>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=monospace;" parent="1" vertex="1"> + <mxGeometry x="360" y="250" width="120" height="30" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-7" value="stack A" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=monospace;strokeColor=#50fa7b;fillColor=none;" parent="1" vertex="1"> + <mxGeometry x="360" y="320" width="120" height="40" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-8" value="stack B" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=monospace;strokeColor=#55FFFF;fillColor=none;" parent="1" vertex="1"> + <mxGeometry x="360" y="400" width="120" height="40" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-9" value="stack C" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=monospace;strokeColor=#FF55FF;fillColor=none;" parent="1" vertex="1"> + <mxGeometry x="360" y="480" width="120" height="40" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-17" value="" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=monospace;fillColor=none;" parent="1" vertex="1"> + <mxGeometry x="820" y="290" width="120" height="260" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-18" value="<font>process address space</font>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=monospace;" parent="1" vertex="1"> + <mxGeometry x="820" y="250" width="120" height="30" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-20" value="stack S" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=monospace;strokeColor=#ffffff;fillColor=none;" parent="1" vertex="1"> + <mxGeometry x="820" y="500" width="120" height="40" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-21" value="stack A" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=monospace;strokeColor=#50FA7B;fillColor=none;" parent="1" vertex="1"> + <mxGeometry x="820" y="320" width="120" height="40" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-22" value="stack C" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=monospace;strokeColor=#FF55FF;fillColor=none;" parent="1" vertex="1"> + <mxGeometry x="820" y="440" width="120" height="40" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-23" value="<font size="1"><i style="font-size: 8px;">user thread</i></font>" style="text;html=1;align=left;verticalAlign=bottom;whiteSpace=wrap;rounded=0;fontFamily=monospace;" parent="1" vertex="1"> + <mxGeometry x="560" y="410" width="60" height="10" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-28" value="stack B" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=monospace;strokeColor=#55FFFF;fillColor=none;" parent="1" vertex="1"> + <mxGeometry x="820" y="380" width="120" height="40" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-29" value="<font>thread<br>S<br></font>" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=monospace;strokeColor=#ffffff;fillColor=none;" parent="1" vertex="1"> + <mxGeometry x="560" y="500" width="220" height="40" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-30" value="<font size="1"><i style="font-size: 8px;">OS thread</i></font>" style="text;html=1;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=monospace;" parent="1" vertex="1"> + <mxGeometry x="560" y="540" width="50" height="10" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-31" value="<font size="1"><i style="font-size: 8px;">user thread</i></font>" style="text;html=1;align=left;verticalAlign=bottom;whiteSpace=wrap;rounded=0;fontFamily=monospace;" parent="1" vertex="1"> + <mxGeometry x="640" y="410" width="60" height="10" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-32" value="<font size="1"><i style="font-size: 8px;">user thread</i></font>" style="text;html=1;align=left;verticalAlign=bottom;whiteSpace=wrap;rounded=0;fontFamily=monospace;" parent="1" vertex="1"> + <mxGeometry x="720" y="410" width="60" height="10" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-38" value="" style="endArrow=blockThin;html=1;rounded=0;startSize=0;entryX=0.167;entryY=1;entryDx=0;entryDy=0;entryPerimeter=0;endFill=1;" parent="1" target="6WErTb2tg34p5fqduLaV-19" edge="1"> + <mxGeometry width="50" height="50" relative="1" as="geometry"> + <mxPoint x="570" y="500" as="sourcePoint" /> + <mxPoint x="570" y="470" as="targetPoint" /> + </mxGeometry> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-39" value="" style="endArrow=blockThin;html=1;rounded=0;startSize=0;entryX=0.167;entryY=1;entryDx=0;entryDy=0;entryPerimeter=0;endFill=1;" parent="1" edge="1"> + <mxGeometry width="50" height="50" relative="1" as="geometry"> + <mxPoint x="609.9985074626868" y="460" as="sourcePoint" /> + <mxPoint x="609.9985074626868" y="500" as="targetPoint" /> + </mxGeometry> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-41" value="<font size="1"><i style="font-size: 8px;">yield</i></font>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=monospace;" parent="1" vertex="1"> + <mxGeometry x="575" y="470" width="30" height="20" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-42" value="" style="endArrow=blockThin;html=1;rounded=0;startSize=0;entryX=0.167;entryY=1;entryDx=0;entryDy=0;entryPerimeter=0;endFill=1;" parent="1" edge="1"> + <mxGeometry width="50" height="50" relative="1" as="geometry"> + <mxPoint x="649.89" y="500" as="sourcePoint" /> + <mxPoint x="649.89" y="460" as="targetPoint" /> + </mxGeometry> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-43" value="" style="endArrow=blockThin;html=1;rounded=0;startSize=0;entryX=0.167;entryY=1;entryDx=0;entryDy=0;entryPerimeter=0;endFill=1;" parent="1" edge="1"> + <mxGeometry width="50" height="50" relative="1" as="geometry"> + <mxPoint x="689.8885074626868" y="460" as="sourcePoint" /> + <mxPoint x="689.8885074626868" y="500" as="targetPoint" /> + </mxGeometry> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-44" value="<font size="1"><i style="font-size: 8px;">yield</i></font>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=monospace;" parent="1" vertex="1"> + <mxGeometry x="654.89" y="470" width="30" height="20" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-45" value="" style="endArrow=blockThin;html=1;rounded=0;startSize=0;entryX=0.167;entryY=1;entryDx=0;entryDy=0;entryPerimeter=0;endFill=1;" parent="1" edge="1"> + <mxGeometry width="50" height="50" relative="1" as="geometry"> + <mxPoint x="729.89" y="500" as="sourcePoint" /> + <mxPoint x="729.89" y="460" as="targetPoint" /> + </mxGeometry> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-46" value="" style="endArrow=blockThin;html=1;rounded=0;startSize=0;entryX=0.167;entryY=1;entryDx=0;entryDy=0;entryPerimeter=0;endFill=1;" parent="1" edge="1"> + <mxGeometry width="50" height="50" relative="1" as="geometry"> + <mxPoint x="769.8885074626868" y="460" as="sourcePoint" /> + <mxPoint x="769.8885074626868" y="500" as="targetPoint" /> + </mxGeometry> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-47" value="<font size="1"><i style="font-size: 8px;">yield</i></font>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=monospace;" parent="1" vertex="1"> + <mxGeometry x="734.89" y="470" width="30" height="20" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-19" value="<font>thread<br>A</font>" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=monospace;strokeColor=#50fa7b;fillColor=none;" parent="1" vertex="1"> + <mxGeometry x="560" y="420" width="60" height="40" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-24" value="<font>thread<br>B<br></font>" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=monospace;strokeColor=#55FFFF;fillColor=none;" parent="1" vertex="1"> + <mxGeometry x="640" y="420" width="60" height="40" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-26" value="<font>thread<br>C<br></font>" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=monospace;strokeColor=#FF55FF;fillColor=none;" parent="1" vertex="1"> + <mxGeometry x="720" y="420" width="60" height="40" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-51" value="" style="endArrow=blockThin;html=1;rounded=0;startSize=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;endFill=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="6WErTb2tg34p5fqduLaV-5" target="6WErTb2tg34p5fqduLaV-7" edge="1"> + <mxGeometry width="50" height="50" relative="1" as="geometry"> + <mxPoint x="659.9985074626868" y="370" as="sourcePoint" /> + <mxPoint x="659.9985074626868" y="410" as="targetPoint" /> + </mxGeometry> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-52" value="" style="endArrow=blockThin;html=1;rounded=0;startSize=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;endFill=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" edge="1"> + <mxGeometry width="50" height="50" relative="1" as="geometry"> + <mxPoint x="320" y="420" as="sourcePoint" /> + <mxPoint x="360" y="420" as="targetPoint" /> + </mxGeometry> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-53" value="" style="endArrow=blockThin;html=1;rounded=0;startSize=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;endFill=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" edge="1"> + <mxGeometry width="50" height="50" relative="1" as="geometry"> + <mxPoint x="320" y="500" as="sourcePoint" /> + <mxPoint x="360" y="500" as="targetPoint" /> + </mxGeometry> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-5" value="<font>thread<br>A</font>" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=monospace;strokeColor=#50fa7b;fillColor=none;" parent="1" vertex="1"> + <mxGeometry x="260" y="320" width="60" height="40" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-10" value="<font size="1"><i style="font-size: 8px;">OS thread</i></font>" style="text;html=1;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=monospace;" parent="1" vertex="1"> + <mxGeometry x="260" y="360" width="50" height="10" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-11" value="<font>thread<br>B<br></font>" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=monospace;strokeColor=#55FFFF;fillColor=none;" parent="1" vertex="1"> + <mxGeometry x="260" y="400" width="60" height="40" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-12" value="<font size="1"><i style="font-size: 8px;">OS thread</i></font>" style="text;html=1;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=monospace;" parent="1" vertex="1"> + <mxGeometry x="260" y="440" width="50" height="10" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-13" value="<font>thread<br>C<br></font>" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=monospace;strokeColor=#FF55FF;fillColor=none;" parent="1" vertex="1"> + <mxGeometry x="260" y="480" width="60" height="40" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-14" value="<font size="1"><i style="font-size: 8px;">OS thread</i></font>" style="text;html=1;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=monospace;" parent="1" vertex="1"> + <mxGeometry x="260" y="520" width="50" height="10" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-54" value="<font size="1"><i style="font-size: 8px;">sp</i></font>" style="text;html=1;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=monospace;" parent="1" vertex="1"> + <mxGeometry x="320" y="340" width="20" height="10" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-55" value="<font size="1"><i style="font-size: 8px;">sp</i></font>" style="text;html=1;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=monospace;" parent="1" vertex="1"> + <mxGeometry x="320" y="420" width="20" height="10" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-56" value="<font size="1"><i style="font-size: 8px;">sp</i></font>" style="text;html=1;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=monospace;" parent="1" vertex="1"> + <mxGeometry x="320" y="500" width="20" height="10" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-59" value="<font size="1"><i style="font-size: 8px;">sp</i></font>" style="text;html=1;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=monospace;" parent="1" vertex="1"> + <mxGeometry x="780" y="520" width="20" height="10" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-60" value="" style="endArrow=none;dashed=1;html=1;dashPattern=1 3;strokeWidth=2;rounded=0;fillColor=#76608a;strokeColor=#B3B3B3;" parent="1" edge="1"> + <mxGeometry width="50" height="50" relative="1" as="geometry"> + <mxPoint x="520" y="560" as="sourcePoint" /> + <mxPoint x="520" y="240" as="targetPoint" /> + </mxGeometry> + </mxCell> + <mxCell id="iekysqo_5NKT5N1MqhNL-1" value="" style="endArrow=blockThin;html=1;rounded=0;startSize=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;endFill=1;exitX=1;exitY=0;exitDx=0;exitDy=0;edgeStyle=orthogonalEdgeStyle;dashed=1;strokeColor=#50FA7B;" parent="1" source="6WErTb2tg34p5fqduLaV-59" target="6WErTb2tg34p5fqduLaV-21" edge="1"> + <mxGeometry width="50" height="50" relative="1" as="geometry"> + <mxPoint x="790" y="530" as="sourcePoint" /> + <mxPoint x="830" y="530" as="targetPoint" /> + <Array as="points"> + <mxPoint x="800" y="340" /> + </Array> + </mxGeometry> + </mxCell> + <mxCell id="iekysqo_5NKT5N1MqhNL-2" value="<font size="1"><i style="font-size: 8px;">sp when yielding to A</i></font>" style="text;html=1;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontFamily=monospace;horizontal=0;" parent="1" vertex="1"> + <mxGeometry x="800" y="390" width="10" height="120" as="geometry" /> + </mxCell> + <mxCell id="6WErTb2tg34p5fqduLaV-58" value="" style="endArrow=blockThin;html=1;rounded=0;startSize=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;endFill=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" edge="1"> + <mxGeometry width="50" height="50" relative="1" as="geometry"> + <mxPoint x="780" y="520" as="sourcePoint" /> + <mxPoint x="820" y="520" as="targetPoint" /> + </mxGeometry> + </mxCell> + </root> + </mxGraphModel> + </diagram> +</mxfile> diff --git a/content/2023-01-14-xpost-matcha-threads/os-vs-user-threads.svg b/content/2023-01-14-xpost-matcha-threads/os-vs-user-threads.svg new file mode 100644 index 0000000..4ce2798 --- /dev/null +++ b/content/2023-01-14-xpost-matcha-threads/os-vs-user-threads.svg @@ -0,0 +1,3 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="681px" height="323px" viewBox="-0.5 -0.5 681 323"><defs/><g><rect x="100" y="51" width="120" height="260" fill="none" stroke="rgb(240, 240, 240)" pointer-events="all"/><rect x="100" y="11" width="120" height="30" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 26px; margin-left: 101px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: monospace; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font>process address space</font></div></div></div></foreignObject><text x="160" y="30" fill="rgb(240, 240, 240)" font-family="monospace" font-size="12px" text-anchor="middle">process address space</text></switch></g><rect x="100" y="81" width="120" height="40" fill="none" stroke="#50fa7b" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 101px; margin-left: 101px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: monospace; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">stack A</div></div></div></foreignObject><text x="160" y="105" fill="rgb(240, 240, 240)" font-family="monospace" font-size="12px" text-anchor="middle">stack A</text></switch></g><rect x="100" y="161" width="120" height="40" fill="none" stroke="#55ffff" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 181px; margin-left: 101px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: monospace; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">stack B</div></div></div></foreignObject><text x="160" y="185" fill="rgb(240, 240, 240)" font-family="monospace" font-size="12px" text-anchor="middle">stack B</text></switch></g><rect x="100" y="241" width="120" height="40" fill="none" stroke="#ff55ff" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 261px; margin-left: 101px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: monospace; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">stack C</div></div></div></foreignObject><text x="160" y="265" fill="rgb(240, 240, 240)" font-family="monospace" font-size="12px" text-anchor="middle">stack C</text></switch></g><rect x="560" y="51" width="120" height="260" fill="none" stroke="rgb(240, 240, 240)" pointer-events="all"/><rect x="560" y="11" width="120" height="30" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 26px; margin-left: 561px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: monospace; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font>process address space</font></div></div></div></foreignObject><text x="620" y="30" fill="rgb(240, 240, 240)" font-family="monospace" font-size="12px" text-anchor="middle">process address space</text></switch></g><rect x="560" y="261" width="120" height="40" fill="none" stroke="#ffffff" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 281px; margin-left: 561px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: monospace; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">stack S</div></div></div></foreignObject><text x="620" y="285" fill="rgb(240, 240, 240)" font-family="monospace" font-size="12px" text-anchor="middle">stack S</text></switch></g><rect x="560" y="81" width="120" height="40" fill="none" stroke="#50fa7b" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 101px; margin-left: 561px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: monospace; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">stack A</div></div></div></foreignObject><text x="620" y="105" fill="rgb(240, 240, 240)" font-family="monospace" font-size="12px" text-anchor="middle">stack A</text></switch></g><rect x="560" y="201" width="120" height="40" fill="none" stroke="#ff55ff" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 221px; margin-left: 561px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: monospace; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">stack C</div></div></div></foreignObject><text x="620" y="225" fill="rgb(240, 240, 240)" font-family="monospace" font-size="12px" text-anchor="middle">stack C</text></switch></g><rect x="300" y="171" width="60" height="10" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-start; width: 58px; height: 1px; padding-top: 178px; margin-left: 302px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: monospace; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font size="1"><i style="font-size: 8px;">user thread</i></font></div></div></div></foreignObject><text x="302" y="178" fill="rgb(240, 240, 240)" font-family="monospace" font-size="12px">user thread</text></switch></g><rect x="560" y="141" width="120" height="40" fill="none" stroke="#55ffff" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 161px; margin-left: 561px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: monospace; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">stack B</div></div></div></foreignObject><text x="620" y="165" fill="rgb(240, 240, 240)" font-family="monospace" font-size="12px" text-anchor="middle">stack B</text></switch></g><rect x="300" y="261" width="220" height="40" fill="none" stroke="#ffffff" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 218px; height: 1px; padding-top: 281px; margin-left: 301px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: monospace; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font>thread<br />S<br /></font></div></div></div></foreignObject><text x="410" y="285" fill="rgb(240, 240, 240)" font-family="monospace" font-size="12px" text-anchor="middle">thread...</text></switch></g><rect x="300" y="301" width="50" height="10" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 48px; height: 1px; padding-top: 306px; margin-left: 302px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: monospace; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font size="1"><i style="font-size: 8px;">OS thread</i></font></div></div></div></foreignObject><text x="302" y="310" fill="rgb(240, 240, 240)" font-family="monospace" font-size="12px">OS thread</text></switch></g><rect x="380" y="171" width="60" height="10" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-start; width: 58px; height: 1px; padding-top: 178px; margin-left: 382px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: monospace; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font size="1"><i style="font-size: 8px;">user thread</i></font></div></div></div></foreignObject><text x="382" y="178" fill="rgb(240, 240, 240)" font-family="monospace" font-size="12px">user thread</text></switch></g><rect x="460" y="171" width="60" height="10" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-start; width: 58px; height: 1px; padding-top: 178px; margin-left: 462px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: monospace; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font size="1"><i style="font-size: 8px;">user thread</i></font></div></div></div></foreignObject><text x="462" y="178" fill="rgb(240, 240, 240)" font-family="monospace" font-size="12px">user thread</text></switch></g><path d="M 310 261 L 310.02 229.12" fill="none" stroke="rgb(240, 240, 240)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 310.02 222.12 L 312.35 229.12 L 307.68 229.12 Z" fill="rgb(240, 240, 240)" stroke="rgb(240, 240, 240)" stroke-miterlimit="10" pointer-events="all"/><path d="M 350 221 L 350 252.88" fill="none" stroke="rgb(240, 240, 240)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 350 259.88 L 347.67 252.88 L 352.33 252.88 Z" fill="rgb(240, 240, 240)" stroke="rgb(240, 240, 240)" stroke-miterlimit="10" pointer-events="all"/><rect x="315" y="231" width="30" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 28px; height: 1px; padding-top: 241px; margin-left: 316px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: monospace; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font size="1"><i style="font-size: 8px;">yield</i></font></div></div></div></foreignObject><text x="330" y="245" fill="rgb(240, 240, 240)" font-family="monospace" font-size="12px" text-anchor="middle">yield</text></switch></g><path d="M 389.89 261 L 389.89 229.12" fill="none" stroke="rgb(240, 240, 240)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 389.89 222.12 L 392.22 229.12 L 387.56 229.12 Z" fill="rgb(240, 240, 240)" stroke="rgb(240, 240, 240)" stroke-miterlimit="10" pointer-events="all"/><path d="M 429.89 221 L 429.89 252.88" fill="none" stroke="rgb(240, 240, 240)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 429.89 259.88 L 427.56 252.88 L 432.22 252.88 Z" fill="rgb(240, 240, 240)" stroke="rgb(240, 240, 240)" stroke-miterlimit="10" pointer-events="all"/><rect x="394.89" y="231" width="30" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 28px; height: 1px; padding-top: 241px; margin-left: 396px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: monospace; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font size="1"><i style="font-size: 8px;">yield</i></font></div></div></div></foreignObject><text x="410" y="245" fill="rgb(240, 240, 240)" font-family="monospace" font-size="12px" text-anchor="middle">yield</text></switch></g><path d="M 469.89 261 L 469.89 229.12" fill="none" stroke="rgb(240, 240, 240)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 469.89 222.12 L 472.22 229.12 L 467.56 229.12 Z" fill="rgb(240, 240, 240)" stroke="rgb(240, 240, 240)" stroke-miterlimit="10" pointer-events="all"/><path d="M 509.89 221 L 509.89 252.88" fill="none" stroke="rgb(240, 240, 240)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 509.89 259.88 L 507.56 252.88 L 512.22 252.88 Z" fill="rgb(240, 240, 240)" stroke="rgb(240, 240, 240)" stroke-miterlimit="10" pointer-events="all"/><rect x="474.89" y="231" width="30" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 28px; height: 1px; padding-top: 241px; margin-left: 476px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: monospace; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font size="1"><i style="font-size: 8px;">yield</i></font></div></div></div></foreignObject><text x="490" y="245" fill="rgb(240, 240, 240)" font-family="monospace" font-size="12px" text-anchor="middle">yield</text></switch></g><rect x="300" y="181" width="60" height="40" fill="none" stroke="#50fa7b" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 201px; margin-left: 301px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: monospace; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font>thread<br />A</font></div></div></div></foreignObject><text x="330" y="205" fill="rgb(240, 240, 240)" font-family="monospace" font-size="12px" text-anchor="middle">thread...</text></switch></g><rect x="380" y="181" width="60" height="40" fill="none" stroke="#55ffff" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 201px; margin-left: 381px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: monospace; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font>thread<br />B<br /></font></div></div></div></foreignObject><text x="410" y="205" fill="rgb(240, 240, 240)" font-family="monospace" font-size="12px" text-anchor="middle">thread...</text></switch></g><rect x="460" y="181" width="60" height="40" fill="none" stroke="#ff55ff" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 201px; margin-left: 461px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: monospace; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font>thread<br />C<br /></font></div></div></div></foreignObject><text x="490" y="205" fill="rgb(240, 240, 240)" font-family="monospace" font-size="12px" text-anchor="middle">thread...</text></switch></g><path d="M 60 101 L 91.88 101" fill="none" stroke="rgb(240, 240, 240)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 98.88 101 L 91.88 103.33 L 91.88 98.67 Z" fill="rgb(240, 240, 240)" stroke="rgb(240, 240, 240)" stroke-miterlimit="10" pointer-events="all"/><path d="M 60 181 L 91.88 181" fill="none" stroke="rgb(240, 240, 240)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 98.88 181 L 91.88 183.33 L 91.88 178.67 Z" fill="rgb(240, 240, 240)" stroke="rgb(240, 240, 240)" stroke-miterlimit="10" pointer-events="all"/><path d="M 60 261 L 91.88 261" fill="none" stroke="rgb(240, 240, 240)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 98.88 261 L 91.88 263.33 L 91.88 258.67 Z" fill="rgb(240, 240, 240)" stroke="rgb(240, 240, 240)" stroke-miterlimit="10" pointer-events="all"/><rect x="0" y="81" width="60" height="40" fill="none" stroke="#50fa7b" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 101px; margin-left: 1px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: monospace; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font>thread<br />A</font></div></div></div></foreignObject><text x="30" y="105" fill="rgb(240, 240, 240)" font-family="monospace" font-size="12px" text-anchor="middle">thread...</text></switch></g><rect x="0" y="121" width="50" height="10" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 48px; height: 1px; padding-top: 126px; margin-left: 2px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: monospace; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font size="1"><i style="font-size: 8px;">OS thread</i></font></div></div></div></foreignObject><text x="2" y="130" fill="rgb(240, 240, 240)" font-family="monospace" font-size="12px">OS thread</text></switch></g><rect x="0" y="161" width="60" height="40" fill="none" stroke="#55ffff" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 181px; margin-left: 1px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: monospace; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font>thread<br />B<br /></font></div></div></div></foreignObject><text x="30" y="185" fill="rgb(240, 240, 240)" font-family="monospace" font-size="12px" text-anchor="middle">thread...</text></switch></g><rect x="0" y="201" width="50" height="10" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 48px; height: 1px; padding-top: 206px; margin-left: 2px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: monospace; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font size="1"><i style="font-size: 8px;">OS thread</i></font></div></div></div></foreignObject><text x="2" y="210" fill="rgb(240, 240, 240)" font-family="monospace" font-size="12px">OS thread</text></switch></g><rect x="0" y="241" width="60" height="40" fill="none" stroke="#ff55ff" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 261px; margin-left: 1px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: monospace; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font>thread<br />C<br /></font></div></div></div></foreignObject><text x="30" y="265" fill="rgb(240, 240, 240)" font-family="monospace" font-size="12px" text-anchor="middle">thread...</text></switch></g><rect x="0" y="281" width="50" height="10" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 48px; height: 1px; padding-top: 286px; margin-left: 2px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: monospace; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font size="1"><i style="font-size: 8px;">OS thread</i></font></div></div></div></foreignObject><text x="2" y="290" fill="rgb(240, 240, 240)" font-family="monospace" font-size="12px">OS thread</text></switch></g><rect x="60" y="101" width="20" height="10" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 18px; height: 1px; padding-top: 106px; margin-left: 62px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: monospace; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font size="1"><i style="font-size: 8px;">sp</i></font></div></div></div></foreignObject><text x="62" y="110" fill="rgb(240, 240, 240)" font-family="monospace" font-size="12px">sp</text></switch></g><rect x="60" y="181" width="20" height="10" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 18px; height: 1px; padding-top: 186px; margin-left: 62px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: monospace; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font size="1"><i style="font-size: 8px;">sp</i></font></div></div></div></foreignObject><text x="62" y="190" fill="rgb(240, 240, 240)" font-family="monospace" font-size="12px">sp</text></switch></g><rect x="60" y="261" width="20" height="10" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 18px; height: 1px; padding-top: 266px; margin-left: 62px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: monospace; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font size="1"><i style="font-size: 8px;">sp</i></font></div></div></div></foreignObject><text x="62" y="270" fill="rgb(240, 240, 240)" font-family="monospace" font-size="12px">sp</text></switch></g><rect x="520" y="281" width="20" height="10" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 18px; height: 1px; padding-top: 286px; margin-left: 522px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: monospace; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font size="1"><i style="font-size: 8px;">sp</i></font></div></div></div></foreignObject><text x="522" y="290" fill="rgb(240, 240, 240)" font-family="monospace" font-size="12px">sp</text></switch></g><path d="M 260 321 L 260 1" fill="none" stroke="#b3b3b3" stroke-width="2" stroke-miterlimit="10" stroke-dasharray="2 6" pointer-events="stroke"/><path d="M 540 281 L 540 101 L 551.88 101" fill="none" stroke="#50fa7b" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><path d="M 558.88 101 L 551.88 103.33 L 551.88 98.67 Z" fill="#50fa7b" stroke="#50fa7b" stroke-miterlimit="10" pointer-events="all"/><rect x="540" y="151" width="10" height="120" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)rotate(-90 545 269)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 118px; height: 1px; padding-top: 269px; margin-left: 545px;"><div data-drawio-colors="color: rgb(240, 240, 240); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: monospace; color: rgb(240, 240, 240); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font size="1"><i style="font-size: 8px;">sp when yielding to A</i></font></div></div></div></foreignObject><text x="545" y="273" fill="rgb(240, 240, 240)" font-family="monospace" font-size="12px">sp when yielding to A</text></switch></g><path d="M 520 281 L 551.88 281" fill="none" stroke="rgb(240, 240, 240)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 558.88 281 L 551.88 283.33 L 551.88 278.67 Z" fill="rgb(240, 240, 240)" stroke="rgb(240, 240, 240)" stroke-miterlimit="10" pointer-events="all"/></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.drawio.com/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
\ No newline at end of file diff --git a/content/2024-04-24-fn-wrapper-macro-magic/index.md b/content/2024-04-24-fn-wrapper-macro-magic/index.md index fe45614..708336b 100644 --- a/content/2024-04-24-fn-wrapper-macro-magic/index.md +++ b/content/2024-04-24-fn-wrapper-macro-magic/index.md @@ -6,25 +6,23 @@ tags = ["c++"] +++ **Short disclaimer at front**. -This post discusses about c/cpp macros, which in general, I try to use as -little as possible or avoid at all. However, they have their application and -can be useful. -All I want to say is, use the right amount of macros for the corresponding -context and think about your colleagues if used in production. :^) +This post discusses about c/cpp macros, which I generally try to minimize or +avoid altogether. However, they do have their applications and can be useful. +All I want to say is, use the right amount of macros for the specific context +and consider your colleagues if used in production. :^) --- -Recently I had the need to wrap a list of c functions and perform some common -work before and after each wrapped function had been invoked. Hence, the body -of each wrapper function was identical. -The wrappers were compiled and linked into a shared library which then was used -for **LD_PRELOAD**ing. +Recently I had the need to wrap a list of c functions and execute some common +task before and after each wrapped function call. Hence, the body of each +wrapper function was identical. Theses wrappers were compiled and linked into a +shared library which then was used for **LD_PRELOAD**ing. In this post I want to collect and archive a few approaches to generate the -required boilerplate code using preprocessor macros. Going from top to bottom, -the amount of macro code (*magic*?) increases. +required boilerplate code using preprocessor macros. Progressing from top to +bottom, the amount of macro code (*magic*?) increases. -To inspect the generated code, one can use the following command with all the +To examine the generated code, one can use the following command with all the code examples from this post. ``` g++ -E file.cc | clang-format @@ -51,7 +49,7 @@ chance to reason about what the code is doing. The draw back is that bodies have to be repeated for each wrapper. ```cpp -{{ include(path="content/2024-04-22-fn-wrapper-macro-magic/wrap-v1.cc") }} +{{ include(path="content/2024-04-24-fn-wrapper-macro-magic/wrap-v1.cc") }} ``` > In the code examples, I use the `MOCK_WRAPPER_IMPL`<sup><a href="#sup-1">1</a></sup> @@ -70,7 +68,7 @@ reason about the code. Additionally, the arguments must be specified twice, when defining a wrapper. ```cpp -{{ include(path="content/2024-04-22-fn-wrapper-macro-magic/wrap-v2.cc") }} +{{ include(path="content/2024-04-24-fn-wrapper-macro-magic/wrap-v2.cc") }} ``` ## Version 3 @@ -84,7 +82,7 @@ The example only supports function with **one** or **two** arguments, but the code can easily be extended. ```cpp -{{ include(path="content/2024-04-22-fn-wrapper-macro-magic/wrap-v3.cc") }} +{{ include(path="content/2024-04-24-fn-wrapper-macro-magic/wrap-v3.cc") }} ``` ## Version 4 @@ -98,19 +96,75 @@ variadic argument list [__VA_ARGS__][va-args] is presented in [__VA_NARG__][va-narg]. ```cpp, hide_lines=41-100 -{{ include(path="content/2024-04-22-fn-wrapper-macro-magic/wrap-v4.cc") }} +{{ include(path="content/2024-04-24-fn-wrapper-macro-magic/wrap-v4.cc") }} +``` +> The implementation to handle empty arguments **CPP_ARGC() == 0** uses a gcc +> extension for the **##** operator. This is also supported by clang, but not +> by msvc. Maybe I will come back in the future to update this, if I have the +> need. + +## Appendix: CONCAT1 and CONCAT2? + +> *Macro arguments are completely macro-expanded before they are substituted +> into a macro body, unless they are stringized or pasted with other tokens +> [..]* - [gcc][cpp-args-prescan] + +```cpp +#define FOO() ABC + +#define CONCAT2(lhs, rhs) lhs ## rhs +#define CONCAT1(lhs, rhs) CONCAT2(lhs, rhs) + +CONCAT2(MOOOSE_, FOO()) +// expands to: +// MOOOSE_FOO() + +CONCAT1(MOOOSE_, FOO()) +// expands to: +// MOOOSE_ABC ``` ## Appendix: Listify codegen data -A hacker friend once showed me some neat macro magic, to organize data, -relevant for generating code in some list, which can then be used at multiple -places. +A hacker friend once showed me some neat macro magic for organizing data +relevant to code generation within a list that can be reused in multiple +contexts. + +I want to archive this technique here, as it fits well in the topic. + +The idea is that the list can accept a macro, which is then applied to each +entry. The processing macros, may not need to use all the elements in an entry. -Since it fits topic wise, I want to archive this technique here as well. +The example below is somewhat arbitrary and one may not see the benefit, but it +is serves to demonstrate the technique. However, this technique really shines +when dealing with larger datasets that are used in different locations to +generate code. + +```cpp +#define EXCEPTIONS(M) \ + M(ill_opc , "Illegal opcode") \ + M(mem_fault, "Memory fault") \ + M(inv_perm , "Invalid permissions") + +enum exception { +#define ELEM(e, _) e, + EXCEPTIONS(ELEM) +#undef ELE +}; + +const char* describe(exception e) { + switch (e) { +#define CASE(e, d) \ + case e: \ + return d; + EXCEPTIONS(CASE) +#undef CASE + } +} +``` -The idea is that the list accepts a macro, which is applied to each entry. The -following is an example, using the `WRAP` macro from [version 4](#version-4). +This technique can also be used to generate the function wrappers when using +the `WRAP` macro from [version 4](#version-4). ```cpp #define API(M) \ @@ -121,13 +175,14 @@ following is an example, using the `WRAP` macro from [version 4](#version-4). API(WRAP) ``` -To close this appendix with some words the same great hacker friend once said: +To conclude this appendix, let me share a quote from that same great hacker +friend: > *This is the excel-ification of cpp code*. ## References - Count number of elements in VA_ARGS [[ref][va-narg]] -- Variadic macros [[ref][va-args]] +- Preprocessor variadic macros [[ref][va-args]] - Preprocessor concatenation [[ref][cpp-concatenation]] - Preprocessor macro argument handling [[ref][cpp-macro-args]] - Preprocessor argument prescan [[ref][cpp-args-prescan]] |