hab dafür zwar keinen Beleg (jenseits von ein paar Videos), aber ich nehme hier den Namen »Alexandrescu« in Gebrauch, um etwas — für sich selbst plausibles — auch mit Autorität sagen zu können
<node CREATED="1784567441015" ID="ID_1119875937" MODIFIED="1784567454153" TEXT="zum Festigen / validieren des eigenen Verständnisses"/>
<node CREATED="1784567466473" ID="ID_1747016910" MODIFIED="1784567480853" TEXT="das Verständnis habe ich mir selber angeeignet"/>
<node CREATED="1784567481729" ID="ID_614997506" MODIFIED="1784567503442" TEXT="zum Validieren des Code"/>
</node>
</node>
<node CREATED="1784567657618" ID="ID_1237182396" MODIFIED="1784567668996" TEXT="Abstraktion ist die Gestaltungsebene">
<node CREATED="1784567673889" ID="ID_797613979" MODIFIED="1784567683915" TEXT="erst auf Grund eines Begriffs erscheint eine »Technologie«"/>
<node CREATED="1784567712530" ID="ID_723842623" MODIFIED="1784567729140" TEXT="wir können den Aufwand zur Video-Verarbeitung (praktisch) nicht ändern"/>
<node CREATED="1784567730384" ID="ID_1417794561" MODIFIED="1784567741435" TEXT="aber durch Abstraktion können wir ihn gliedern"/>
<node CREATED="1784567752745" ID="ID_1176340721" MODIFIED="1784567769924" TEXT="und dann so anornen, daß er weniger stört"/>
<node CREATED="1785790624736" ID="ID_942453754" MODIFIED="1785790659474" TEXT="muß annehmen daß Denkweisen der systemnahen Programmierung nicht bekannt sind"/>
<node CREATED="1785790662323" ID="ID_337982910" MODIFIED="1785790682620" TEXT="kann aber keine Einführung geben (systematisch gar nicht möglich)"/>
<node CREATED="1785790692615" ID="ID_1452357773" MODIFIED="1785790710776" TEXT="also: „ich laß euch mal zuschauen....“"/>
<node CREATED="1786235664313" ID="ID_1678569803" MODIFIED="1786235696451" TEXT="what is »fast« and what »slow« ⟹ Time-Scales"/>
<node CREATED="1785704817964" ID="ID_1807949358" MODIFIED="1785704828892" TEXT="much more programmer friendly interface">
<node CREATED="1785704841403" ID="ID_547397514" MODIFIED="1785704852395" TEXT="need not setup the uring-memmap"/>
<node CREATED="1785704854244" ID="ID_1424784115" MODIFIED="1785704873620" TEXT="don't have to deal with data structure defined by offsets"/>
<node CREATED="1785704890752" ID="ID_875859220" MODIFIED="1785704899628" TEXT="can just »open« an uring with a given size + flags"/>
<node CREATED="1785704965841" ID="ID_1668911479" MODIFIED="1785704991917" TEXT="have »API functions« to fill a submission-queue-entry"/>
<node CREATED="1785705012980" ID="ID_1546976264" MODIFIED="1785705026013" TEXT="can just »peek« or »block« on the completion-queue"/>
<node CREATED="1785705043965" ID="ID_1838399356" MODIFIED="1785705096946" TEXT="no need to care for proper synchronisation primitives">
<node BACKGROUND_COLOR="#accdc3" COLOR="#3f4015" CREATED="1786245032571" ID="ID_1765938120" MODIFIED="1786273389235" STYLE="fork" TEXT="NUMA schießt hier über das Ziel hinaus">
<node CREATED="1786245051584" ID="ID_829978590" MODIFIED="1786245480820" TEXT="(wir brauchen keine mehrfach-Sockets oder chiplets)">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
allein der Umstand daß Cores direkt an einem Cache hängen, genügt, um die Notwendigkeit der Synchronisation aufzuzeigen ... daher ist das Schlüsselwort auch "cache-coherence"
<node CREATED="1785788536375" ID="ID_1664468875" MODIFIED="1785788543946" TEXT="barrier is used in two flavours">
<node CREATED="1785788545065" ID="ID_615184502" MODIFIED="1785788558771" TEXT="synchronisation barrier ⟹ a control-flow device"/>
<node CREATED="1785788560407" ID="ID_902009764" MODIFIED="1785788570172" TEXT="memory barrier: synonymous to "fence""/>
</node>
<node CREATED="1785788228092" ID="ID_1833234694" MODIFIED="1785788240158" TEXT="fence is used in two meanings">
<node CREATED="1785788486161" ID="ID_1563041065" MODIFIED="1785788507616" TEXT=""fence" in OS literature: a hardware supported primitive"/>
<node CREATED="1785788262637" ID="ID_293253681" MODIFIED="1785788483923" TEXT="std::atomic_thread_fence ⟹ a standarlone version of atomic ordering"/>
</node>
</node>
<node CREATED="1785788597320" ID="ID_612417499" LINK="#ID_1041458587" MODIFIED="1785788689382" TEXT="typically related to hardware / ISA"/>
</node>
<node CREATED="1785706645606" ID="ID_1006949995" MODIFIED="1785706652761" TEXT="an atomic with memory-order">
<node CREATED="1785791118824" ID="ID_140629594" MODIFIED="1785791139325" TEXT="a conceptual tool of the language standard (C++)"/>
<node CREATED="1785791141122" ID="ID_1377087178" MODIFIED="1785791155253" TEXT="BUT: it integrates limitations for the Compiler/Optimiser"/>
</node>
</node>
<node CREATED="1785791188795" ID="ID_1512345327" MODIFIED="1785791203573" TEXT="visiblity vs. control-flow">
<node CREATED="1785791204505" ID="ID_1519603089" MODIFIED="1785791238988" TEXT="a memory barrier in itself does not impact the control flow"/>
<node CREATED="1785791217111" ID="ID_1010220877" MODIFIED="1785791232073" TEXT="but it is the foundation to synchronise two control-flows"/>
<node CREATED="1785875179714" ID="ID_599406814" MODIFIED="1785875187341" TEXT="A coroutine is a compiler-synthesized state machine">
<node CREATED="1785875202575" ID="ID_1932767180" MODIFIED="1785875217532" TEXT="co_await points ≙ case labels"/>
<node CREATED="1785875237674" ID="ID_1058579559" MODIFIED="1785875253716" TEXT="locals ⟹ suspension ⟹ member fields of a generated struct"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1785879840827" ID="ID_1269710501" MODIFIED="1785879858112" TEXT="this is likely the most dense piece of code">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1785880026115" ID="ID_1784510664" MODIFIED="1785880098786" TEXT="nochmal die States einblenden">
<node CREATED="1785883473898" ID="ID_1822434518" MODIFIED="1785883480820" TEXT="Reflection: where we are...?">
<node BACKGROUND_COLOR="#c3c0dd" COLOR="#34245c" CREATED="1785883484417" ID="ID_1233434338" MODIFIED="1785884889237" TEXT="io_uring resolved the bottleneck in the Kernel">
<icon BUILTIN="yes"/>
</node>
<node CREATED="1785883495942" ID="ID_751806456" MODIFIED="1785883539495" TEXT="it does not — in itself — „resolve async“">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1785883581639" ID="ID_1693723520" MODIFIED="1785885069705" TEXT="still need to dispatch the work ⟹ synchronisation issues"/>
<node CREATED="1785883555083" ID="ID_1264739380" MODIFIED="1785883566238" TEXT="the Linux Kernel is still inherently synchronous"/>
<node CREATED="1785884986511" ID="ID_514549682" MODIFIED="1785885016851" TEXT="the »function colouration problem« remains to be solved / mitigated">
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1785885022722" ID="ID_1162960165" MODIFIED="1785885170219" TEXT="Danger: have to rebuild a large part of the Kernel machinery">
<node CREATED="1785817842583" ID="ID_306380330" MODIFIED="1785817861311" TEXT="Idee: möchte die gewaltigen Zeitspannen visualisieren">
<icon BUILTIN="idea"/>
<node CREATED="1785817863252" ID="ID_299103430" MODIFIED="1785817884168" TEXT="möchte klarmachen, warum wir es mit »Stockwerken« zu tun haben"/>
<node CREATED="1785817885505" ID="ID_1002287440" MODIFIED="1785817898591" TEXT="brauche ein Framework, in dem ich die vierschiednen Zahlen einordnen kann"/>
<node BACKGROUND_COLOR="#accdc3" COLOR="#3f4015" CREATED="1785817904306" FOLDED="true" ID="ID_1762091251" MODIFIED="1786633113969" STYLE="fork" TEXT="diese Idee mit Claude ausarbeiten....">
<node CREATED="1785817934211" ID="ID_1193226285" MODIFIED="1785817983642" TEXT="lasse Claude die Timings aufsammeln aus dem anderen Diskussionsthread">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
habe jetzt einen ziemlich langen Thread mit Recherche / Hintergrundwissen für mich; in dem Rahmen sind die diversen Zeitangaben bereits alle aufgetaucht
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1785817989939" ID="ID_1738971982" MODIFIED="1785818000822" TEXT="lasse Zahlen nochmal überprüfen und mir einige Quellen suchen"/>
<node BACKGROUND_COLOR="#accdc3" COLOR="#3f4015" CREATED="1785818001802" ID="ID_420827912" MODIFIED="1785818058289" STYLE="fork" TEXT="Vorschlag von Claude: plausibel machen durch Analogie: 1 clock-tick ≙ 1 sec">
<node CREATED="1785818061762" ID="ID_1056499967" MODIFIED="1785818074164" TEXT="das sind alle Goldhamlster Deutschlands aneinandergereicht"/>
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1785818084662" ID="ID_1277933693" MODIFIED="1785818095365" TEXT="werde das als separates Slide bringen">
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
<icon BUILTIN="yes"/>
</node>
</node>
<node CREATED="1785818213769" ID="ID_1124818051" MODIFIED="1785818244989" TEXT="lasse mir einen Vorschlag machen, mit reduzierter Auswahl und didaktisch-verkürzten Titeln"/>
<node CREATED="1785818246457" ID="ID_249476374" MODIFIED="1785818250452" TEXT="einige wenige Korrekturen"/>
<node CREATED="1785818251079" ID="ID_306091121" MODIFIED="1785818264085" TEXT="diskutiere Tabellenform vs. Diagramm"/>
<node CREATED="1785818264742" ID="ID_1640435583" MODIFIED="1785818276130" TEXT="lasse Claude ausrechnen, ob das Diagramm lesbar ist">
<node CREATED="1785818347664" ID="ID_1543794705" MODIFIED="1785818898650" TEXT="damit ließe sich das in 4 »Stockwerke« unterbringen">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Das hat Claude interessanterweise erst gesehen, nachdem ich an den längsten Zeitspannen etwas getweakt hatte. Mir war aufgefallen 1000sec ≈ 15min ⟹ damit kommen wir mit einer Sekunden-Skala als 4.Zeile gut aus
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1785818395777" ID="ID_1984967393" MODIFIED="1785818581196" TEXT="Idee: teile auf in »Maschine« — »Mensch«">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...das ergab sich aus der Konversation: im Grunde reichen die ganzen Maschinen-relevanten Zeiten hoch bis 10ms / etwa an dem Punkt beginnen Timings, die vom Menschen wahrnehmbar sind.
</p>
</body>
</html></richcontent>
</node>
</node>
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1785818286987" ID="ID_346780786" MODIFIED="1785818292938" TEXT="Entscheidung für ein Diagramm">
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
<icon BUILTIN="yes"/>
</node>
<node COLOR="#338800" CREATED="1785818430680" ID="ID_662868064" MODIFIED="1785818900154" TEXT="lasse Claude ein geeignetes SVG generieren">
<node CREATED="1785818447838" ID="ID_161232521" MODIFIED="1785818484948" TEXT="generiert ein zunächst sichtbares "scaffold""/>
<node CREATED="1785818487850" ID="ID_206426899" MODIFIED="1785818500771" TEXT="dann jeweils einen transparenten Layer für jedes »Stockwerk«"/>
<node CREATED="1785818501622" ID="ID_613662939" MODIFIED="1785818517560" TEXT="ein Dim-Layer den man zuschalten kann, wenn man in den "menschlichen"-Bereich geht"/>
<node BACKGROUND_COLOR="#ece0bb" CREATED="1785818702064" ID="ID_540432980" MODIFIED="1785818738052" TEXT="Claude schreibt tatsächlich ein Python-Programm, das er mir auch mitgibt">
<node BACKGROUND_COLOR="#accdc3" COLOR="#3f4015" CREATED="1785877302464" ID="ID_1725774104" MODIFIED="1785880120631" STYLE="fork" TEXT="Ein Schema ist nebenbei im Chat mit Claude "angefallen"">
<node CREATED="1786661006589" ID="ID_1093573746" MODIFIED="1786661048132" TEXT="ja: habs vor dem State-Ring eingebaut"/>
<node CREATED="1786661020642" ID="ID_1076990072" MODIFIED="1786661039901" TEXT="sogar sehr wichtig, man muß die State-Engine wenigstenseinmal sehen"/>
<node COLOR="#338800" CREATED="1786661049458" ID="ID_1526572846" MODIFIED="1786661056718" TEXT="hab das Layout umgestellt">
<node CREATED="1786417218690" ID="ID_1381822955" MODIFIED="1786417293609" TEXT="mache einen »fliegenden Edit« und tausche den Text aus">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...alles ausgeblendet, außder dem einen Callback, den ich brauche; Seitengröße an neue Präsentation angepaßt, als PNG exportiert, in Libreoffice gelinkt
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1786417806771" ID="ID_719589637" MODIFIED="1786417819086" TEXT="neuerdings geht direkt Copy-n-Paste">
...das würde zwar letztlich funktionieren, wenn man dann ab dem 2.Absatz alle auf "with previous" umschaltet .... ist aber irre unübersichtlich.  Verstehe nicht, warum er das manchmal macht (vielleicht, wenn man einzelne Absätze schon formatiert hat?)
<node CREATED="1786500657782" ID="ID_1681249470" MODIFIED="1786500756647" TEXT="Workaround: mit einem andern Objekt zusammen markieren">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
Zwei Objekte markieren, Animation hinzufügen, dann Animation des 2. Objekts wieder löschen ⟹ Ergebnis: man bekommt die Animation auf den ganzen Frame, nicht einzelne Absätze
ich hatte mir ja im Vorfeld überlegt, was für ein Publikum vermutlich auf der FrOSCon herumläuft; dem entsprechend war der Vortrag auf »Allgemeinbildungs-Niveau« angelegt.... (was allerdings auch bereits für Benny eine erhebliche Herausforderung war, also vermutlich auch für andere Leute)
<node CREATED="1755783401946" ID="ID_1555871563" LINK="https://lumiera.org/research/videoDisplay/index.html" MODIFIED="1755783828602" TEXT="Direkt-Link auf die Landing-Page">
<node CREATED="1753133245990" ID="ID_1737109820" MODIFIED="1753133263062" TEXT="einen plausiblen Anlaß, um einen Vortrag mit Lumiera-Bezug zu halten"/>
<node CREATED="1753133263959" ID="ID_1208154525" MODIFIED="1753133281172" TEXT="Kompetenz in »hard-core«-Themen demonstrieren"/>
<node CREATED="1784566461960" ID="ID_1300097660" MODIFIED="1784566486105" TEXT="konkret kann nur ein kleines Code-Ökosystem gezeigt werden"/>
<node CREATED="1784566494196" ID="ID_1222704475" MODIFIED="1784566512188" TEXT="unter Verweis auf letztes Jahr kann ich Video-Output mit integrieren"/>
<node CREATED="1784566522103" ID="ID_1049138236" MODIFIED="1784566534174" TEXT="Vom Code eine Brücke zur Proaktor-Architektur"/>
<node CREATED="1784566536590" ID="ID_1767517870" MODIFIED="1784566548009" TEXT="cross-Thread-Synchronisation am Beispiel"/>
Damit meine ich, ob der Ansatz mit symbolisch repräsentierten externen Fähigkeiten überhaupt aufgeht, und ob es tatsächlich gelingt, ein Werkzeug-Paradigma auf der Basis von Placements zu schaffen. Und, last but not least, ob ich Leute finden, die mich unterstützen und sich diese Vision aneignen
<node CREATED="1785790491314" ID="ID_215785223" MODIFIED="1785790509619" TEXT="das Thema ist eigentlich zu komplex für eine »allgemeine« Zuhörerschaft"/>
<node CREATED="1785790510700" ID="ID_94720075" MODIFIED="1785790531089" TEXT="aber ich richte mich gezielt an diese — weil es eigentlich um Lumiera geht"/>
<node CREATED="1783367993803" ID="ID_1431968418" LINK="https://towardsdev.com/io-uring-vs-epoll-syscall-overhead-linux-performance-a3d7fcc6c9b9?gi=3c0154f883b2" MODIFIED="1783368130857" TEXT="Medium.com: The Linux I/O Interface That Finally Makes Sense">
<node CREATED="1783368328751" ID="ID_1994767905" LINK="https://unixism.net/2020/04/io-uring-by-example-article-series/" MODIFIED="1783368342820" TEXT="IO_URING by example (2020)">
<node CREATED="1783370514114" ID="ID_1349175602" LINK="https://arxiv.org/abs/2512.04859" MODIFIED="1783370550553" TEXT="Interessant: arXiv — High-Performance DBMSs with io_uring: When and How to use it"/>
<node CREATED="1783707596169" ID="ID_1286879063" LINK="https://unixism.net/loti/ref-liburing/submission.html" MODIFIED="1783707796060" TEXT="wichtig(liburing): Submission and Submission helpers">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Die Liburing hüllt das eigentliche Ringbuffer-Interface ein, so daß man gar nicht mehr direkt mit den Ringbuffern zu tun hat. Was schön ist, aber man muß die Ringbuffer verstanden haben! Im Besonderen die Submission helpers sind Konfigurations-Funktionen, die eienen Submission-Queue-Entry <i>ausfüllen mit passenden Parametern</i>. Damit sind sie wieder so etwas wie eine funktionale Form der Kernel-calls, aber eben verzögert / geplant. Den eigentlichen Aufruf macht man dann mit io_uring_submit(ring);
man setzt einen Socket auf "asynchron". Durch cleveres Polling bekommt man mit, wann die IO-Operation »ready« wird. <b>Aber</b> das ist readyness-semantics, not completion-semantics. Und es ist sehr limitiert, und setzt eine komplexe State-Machine im Userland vorraus
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1779396620988" ID="ID_769607449" MODIFIED="1779396634370" TEXT="es gab seit Linux 2.5 bereits async_io"/>
<node CREATED="1779396635421" ID="ID_1823781286" MODIFIED="1779396769771" TEXT="das ist aber auf Spezialfälle limitiert und schwierig zu nutzen">
What it says about the state of hardware is easy.<br />
</p>
<p>
Meltdown mitigations made context switching more expensive, and SSDs made the actual I/O cheaper. At some point, you're spending almost as much time context switching as you are doing actual work, and there's nothing Linux can do about it because it's all tied up in the architecture of the MMU and the processor's cache. Thus, it now makes sense to design the interface around reducing the number of context switches at all cost, instead of just assuming that the cost of doing the actual I/O will dominate.
</p>
</body>
</html></richcontent>
</node>
</node>
<node CREATED="1779396548708" ID="ID_1822858626" MODIFIED="1779396599007" TEXT="kann mit dBPF zusammenarbeiten">
extended Berkeley Package Filter: ein Framework, das Code als Reaktion auf Events direkt im Kernel-Kontext ausführt
</p>
</body>
</html></richcontent>
</node>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1779396822977" ID="ID_211122289" MODIFIED="1779397158118" TEXT="bedingt durch die komplett neue Struktur ⟹ massive Sicherheitsprobleme">
Es wurde alsbald erheblich als Einfallstor für Exploits genutzt, da das bestehende Security-Tooling diese neuen Mechanismen überhaupt nicht »auf dem Schirm« hat. Im Jahr 2023 hat das Google-Security-Team 60% aller Linux-Exploits dem IO_URING subsystem zugeordnet. Daher ist es auf Android und ChromeOS und unter Docker in der Standard-Konfiguration deaktiviert (und hat einen schlechten Ruf unter den »Oldtimern«)
</p>
</body>
</html></richcontent>
<icon BUILTIN="messagebox_warning"/>
</node>
<node CREATED="1779397402228" ID="ID_1111670287" LINK="https://github.com/axboe/liburing" MODIFIED="1779397445634" TEXT="die liburing erleichtert den Umgang mit dem anspruchsvollen API">
<icon BUILTIN="idea"/>
</node>
<node BACKGROUND_COLOR="#accdc3" COLOR="#3f4015" CREATED="1779398825661" ID="ID_1355173640" MODIFIED="1779398859668" STYLE="fork" TEXT="Chat-GPT meint: das wird die zukünftige default-Lösung">
deshalb war die Behandlung von Files stets etwas asymetrisch. Auch wenn der Socket <i>ready</i> ist, kann er dann doch noch blocken, wenn das System unter Druck steht.
<node CREATED="1783381563444" ID="ID_1738464780" MODIFIED="1783381590147" TEXT="kann auch warten bis eine gewisse Zahl an CQ Entries zurückgeschickt wurde"/>
</node>
<node CREATED="1783381611534" ID="ID_1396608178" MODIFIED="1783381625024" TEXT="ein CQE pro SQE, mit Ergebnis-Status">
<node CREATED="1783387631984" ID="ID_888714962" MODIFIED="1783387642585" TEXT="werden verbunden durch einen user_data-Pointer"/>
<node CREATED="1783387674355" ID="ID_1734790893" MODIFIED="1783387688094" TEXT="dieser wird vom Kernel einfach unverändert durchgereicht"/>
<node BACKGROUND_COLOR="#fefc4e" COLOR="#351d75" CREATED="1783389920263" ID="ID_631311167" MODIFIED="1783389939307" TEXT="Ha! das paßt perfekt auf mein Design der Continuations im Scheduler">
<font BOLD="true" NAME="SansSerif" SIZE="12"/>
<icon BUILTIN="idea"/>
</node>
</node>
<node CREATED="1783384996718" ID="ID_1183383765" MODIFIED="1783385010780" TEXT="CQ-Entries kommen in beliebiger Reihenfolge (wenn ready)">
<node CREATED="1783385011889" ID="ID_141657481" MODIFIED="1783385016940" TEXT="man kann aber Ordnung erzwingen"/>
....vermutlich wird der Buffer-Speicher einfach geeignet auch in den Kernel-Space gemapped; jedoch das Setup mit den Command/Completion-Ringbuffern isoliert den User komplett von diesen Fragen. Sehr geschickt!
<node CREATED="1783384437400" ID="ID_261205380" MODIFIED="1783384460053" TEXT="transferiert den File-content lückenlos der Reihe nach in die Buffer"/>
</node>
<node CREATED="1783387732857" ID="ID_1688041268" MODIFIED="1783387775312" TEXT="CQE hat user_date, res/error-code, wie read()"/>
<node CREATED="1783387816253" ID="ID_480695787" MODIFIED="1783387823986" TEXT="SQE ist eine Command-struct">
<node CREATED="1783387824860" ID="ID_1367724603" MODIFIED="1783387827979" TEXT="hat eine Command-ID"/>
<node CREATED="1783387828460" ID="ID_854431460" MODIFIED="1783387836666" TEXT="und dann diverse multi-purpose-fields"/>
<node CREATED="1783387924878" ID="ID_1554669393" MODIFIED="1783387936427" TEXT="Aufrufe sind modelliert nach bekannten IO-Operationen">
<node CREATED="1783388108773" ID="ID_1963002363" MODIFIED="1783388118801" TEXT="bsp: verwendet einen File-Descriptor"/>
<node CREATED="1783388119281" ID="ID_595160605" MODIFIED="1783388126033" TEXT="hat einen Offset in das File"/>
<node CREATED="1783388126544" ID="ID_1557501628" MODIFIED="1783388139315" TEXT="bekommt einen Buffer-pointer oder einen iovec"/>
</node>
</node>
<node CREATED="1783388781316" ID="ID_1265251773" MODIFIED="1783388814792" TEXT="man gibt eine struct io_uring_params an den io_uring_setup()"/>
<node CREATED="1783388646919" ID="ID_1468403550" MODIFIED="1783388660393" TEXT="man definiert sich selbst passende Schnittstellen-Structs">
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1783388674071" ID="ID_1871456691" MODIFIED="1783439712989" TEXT="Frage: warum ist das nicht vom Kernel vordefiniert?">
<icon BUILTIN="help"/>
<node CREATED="1783388990307" ID="ID_1963229698" MODIFIED="1783389000855" TEXT="weil das schon ein Abstraktionslayer ist"/>
<node CREATED="1783389001425" ID="ID_149275964" MODIFIED="1783389017213" TEXT="der Kernel definiert lediglich die Basis-structs SQE und CQE"/>
<node CREATED="1783389033526" ID="ID_531781879" MODIFIED="1783389070406" TEXT="die Positionen der Ringbuffer-Kontrollfelder sind quasi-dynamisch"/>
<node CREATED="1783389073434" ID="ID_378448165" MODIFIED="1783389087003" TEXT="sie werden per io_uring_params zurückgegeben"/>
<node CREATED="1783389088143" ID="ID_1057767628" MODIFIED="1783389106739" TEXT="deshalb ist es sinnvoll, sich da eine Interface-struct drüberzusetzen"/>
</node>
<node CREATED="1783388687235" ID="ID_572599133" MODIFIED="1783388699931" TEXT="diese kann man dann per mmap in den user-space mappen"/>
<node CREATED="1783388891850" ID="ID_54309322" MODIFIED="1783388907891" TEXT="für das zu mappende "file" gibt es einen File-Descriptor"/>
<node CREATED="1783388921357" ID="ID_788864531" MODIFIED="1783388932860" TEXT="dieser wird von io_uring_setup() zurückgeliefert"/>
</node>
<node CREATED="1783439723372" ID="ID_70450003" MODIFIED="1783439731172" TEXT="Ringbuffer sind auf Index-Basis implementiert">
<node CREATED="1783439735880" ID="ID_1310555659" MODIFIED="1783439754513" TEXT="es ist ein Array, wobei head und tail als Indices gegeben sind"/>
<node CREATED="1783439755001" ID="ID_339978399" MODIFIED="1783439785005" TEXT="vor dem Zugriff wird der Index modulo die Ringbuffer-Länge genommen"/>
<node CREATED="1783439788873" ID="ID_800063940" MODIFIED="1783439821495" TEXT="Kontrollfelder und die Entry-Arrays liegen im shraed (mmaped) memory"/>
<node CREATED="1783439823932" ID="ID_51197608" MODIFIED="1783439987223" TEXT="die SQ-Entries werden über eine weitere Indirektion mitgeteilt">
Im Submission-Ringbuffer liegt nur eine Index-Nummer, die in ein daneben stehendes weiteres Array zeigt. Im Tutorial heißt es, das sei so konstruiert worden, um Applikationen zusätzliche Flexibilität zu geben (was ich nicht wirklich verstehe, da ja auch das externe SQ-Array im mmapped-mem liegen muß)
<node CREATED="1783440089704" ID="ID_1425651981" MODIFIED="1783440102635" TEXT="das genügt hier, da es sich um single-Producer/Consumer handelt"/>
<node CREATED="1783446918040" ID="ID_742805192" MODIFIED="1783447636257" TEXT="anscheinend gibt es einen "retry", signalisiert mit EAGAIN">
<node CREATED="1783447637802" ID="ID_1480100399" MODIFIED="1783447653363" TEXT="readv() ist nur eine scatter/gather-variante von read/write()"/>
<node CREATED="1783447770285" ID="ID_1587286955" MODIFIED="1783447818026" TEXT="wenn man read() mit Flag O_NONBLOCK aufruft, könnte der physiche Read trotzdem blocken"/>
<node CREATED="1783447818970" ID="ID_1745751924" MODIFIED="1783447840404" TEXT="in diesem Fall liefert read() einen Fehler (ret=-1) mit Errno == EAGAIN"/>
</node>
<node CREATED="1783446948271" ID="ID_75609256" MODIFIED="1783446958635" TEXT="außerdem können reads/writes kürzer sein als instruiert">
<node CREATED="1783447857789" ID="ID_1707492290" MODIFIED="1783447870607" TEXT="das ist explizit so vorgesehen"/>
<node CREATED="1783447880121" ID="ID_1382932735" MODIFIED="1783447896011" TEXT="kann aber auch durch einen Interrupt bewirkt sein"/>
</node>
<node CREATED="1783446959217" ID="ID_1108500089" MODIFIED="1783446972605" TEXT="in beiden Fällen muß man einen Request anpassen / nochmal senden"/>
<node CREATED="1783467887910" ID="ID_663414334" MODIFIED="1783467904503" TEXT="der Kernel erkennt neue Submission-Queue-Entries von selbst"/>
<node CREATED="1783467913708" ID="ID_1956703105" MODIFIED="1783467937206" TEXT="das spart einen Syscall pro Batch"/>
<node CREATED="1783468073102" ID="ID_1192604598" MODIFIED="1783468079770" TEXT="aktiviert per Flag beim Setup">
<node CREATED="1783468234883" ID="ID_422059492" MODIFIED="1783468250144" TEXT="außerdem: muß das "fixed-files"-feature verwenden"/>
<node CREATED="1783468250631" ID="ID_229494074" MODIFIED="1783468266874" TEXT="das ist ein vorbereitetes Array mit File-Descriptoren"/>
</node>
<node CREATED="1783467937700" ID="ID_1422805249" MODIFIED="1783467948389" TEXT="ABER: Kernel verwendet einen poller-Thread">
<node CREATED="1783467954732" ID="ID_161296285" MODIFIED="1783467979900" TEXT="der verursacht eine nicht-triviale CPU-Last"/>
<node CREATED="1783467981270" ID="ID_1932680351" MODIFIED="1783467997361" TEXT="und er endet von selber, wenn idle; muß dann neu gestartet werden"/>
<node CREATED="1783471326168" ID="ID_1768891087" MODIFIED="1783471336770" TEXT="es gibt einen blocking poll"/>
<node CREATED="1783471337414" ID="ID_1463733161" MODIFIED="1783471345321" TEXT="man kann aber peek-Funktionen verwenden"/>
<node CREATED="1783471346034" ID="ID_821102680" MODIFIED="1783471359503" TEXT="das geht auch für einen Batch von Entries"/>
</node>
<node CREATED="1783469960153" ID="ID_1792704761" LINK="https://unixism.net/loti/tutorial/link_liburing.html#link-liburing" MODIFIED="1783471296410" TEXT="man kann Jobs sequentiell verketten">
<node CREATED="1783469982826" ID="ID_1031698216" MODIFIED="1783469991377" TEXT="dann können sie nur der Reihe nach laufen"/>
<node CREATED="1783469992517" ID="ID_1177264229" MODIFIED="1783470001469" TEXT="natürlich erzeugt das so einige Komplikationen"/>
<node CREATED="1783470003243" ID="ID_1005057440" MODIFIED="1783470013684" TEXT="und: eine solche Kette kann vorzeitig scheitern"/>
</node>
<node CREATED="1783470066077" ID="ID_858165857" LINK="https://unixism.net/loti/tutorial/fixed_buffers.html" MODIFIED="1783470085644" TEXT="»fixed buffers« direkt shared gemapped">
weil der Buffer shared in den Client-Process-Space gemapped ist, muß der Kernel keine Daten mehr explizit in den Ziepuffer im Prozeß kopieren
<node CREATED="1783471575007" ID="ID_1734284682" MODIFIED="1783471584374" TEXT="ein Thread der Requests dispatched"/>
<node CREATED="1783471588564" ID="ID_452380465" MODIFIED="1783471606480" TEXT="nimmt Requests entgegen und gibt sie an einen passenden Handler weiter"/>
<node CREATED="1783471897570" ID="ID_1140725129" MODIFIED="1783471919980" TEXT="Charakteristik: ein Reactor reagiert auf Readiness">
<node CREATED="1784909439497" ID="ID_1084860008" MODIFIED="1784909467251" TEXT="alle beantworten: "welchen von diesen N Sockets kann ich jetzt lesen?""/>
<node CREATED="1784909502349" ID="ID_2286932" MODIFIED="1784909521102" TEXT="man gibt dem Kernel eine Bitmask die interessante FildDescriptors markiert"/>
<node CREATED="1784909521832" ID="ID_1755337748" MODIFIED="1784909530992" TEXT="der Kernel setzt dort Bit"/>
<node CREATED="1784909532281" ID="ID_1850235470" MODIFIED="1784909544907" TEXT="man sieht dann selber welche FD-Nummer man anschauen sollte"/>
<node CREATED="1784909546095" ID="ID_242092869" MODIFIED="1784909559545" TEXT="limitiert durch die feste Bitmask-Größe (1024)"/>
<node CREATED="1784909739501" ID="ID_1315873664" MODIFIED="1784909745423" TEXT="das sind alles blockende Kernel-Calls"/>
<node CREATED="1784909751964" ID="ID_1277219779" MODIFIED="1784909761846" TEXT="nur werden die Daten intern bereits vorbereitet"/>
<node CREATED="1784909776690" ID="ID_988789751" MODIFIED="1784909785052" TEXT="Jeder Socket hat einen receive-Buffer"/>
<node CREATED="1784909814875" ID="ID_1511520490" MODIFIED="1784909824021" TEXT="dort kann man sich in eine wait-queue registrieren"/>
<node CREATED="1784909824946" ID="ID_943421877" MODIFIED="1784909849298" TEXT="beim Eintreffen von Daten wird der aktuelle Thread auf "aktiv" markiert"/>
<node CREATED="1784909851798" ID="ID_890255483" MODIFIED="1784909865847" TEXT="beim nächsten Scheduler-Turn wird er auf eine core gemapped"/>
</node>
<node CREATED="1784909882722" ID="ID_898978088" MODIFIED="1784909894254" TEXT="es gibt eine Unix-Signal-basierte Variante">
<node CREATED="1784909895312" ID="ID_1380240825" MODIFIED="1784909906371" TEXT="die wird aber extrem selten genutzt"/>
<node CREATED="1784909920762" ID="ID_409154508" MODIFIED="1784909936575" TEXT="ist kniffelig: man weiß nicht für welchen FD man signalisiert wurde"/>
</node>
<node CREATED="1784909970894" ID="ID_467441062" MODIFIED="1784910002009" TEXT="Achtung: lokale Files nicht für poll/epoll geeignet">
<node CREATED="1784910003130" ID="ID_1349981115" MODIFIED="1784910020372" TEXT="sie implementieren nicht den "readiness-contract" des VFS-Layers"/>
<node CREATED="1784910020816" ID="ID_1067149107" MODIFIED="1784910030490" TEXT="sie haben keinnen Buffer-leer-Status"/>
<node CREATED="1784910033854" ID="ID_245837866" MODIFIED="1784910044737" TEXT="insofern »erscheinen« sie immer "ready""/>
<node CREATED="1784910045236" ID="ID_1620698915" MODIFIED="1784910058118" TEXT="aber der Lese-Aufruf blockt dann u.U. doch"/>
<node CREATED="1784910062689" ID="ID_637014950" MODIFIED="1784910077818" TEXT="Abhilfe: asio und File-Handles im DIRECT-Modus"/>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1784910098946" ID="ID_1349516830" MODIFIED="1784910117028" TEXT="selbst das Reactor-Modell braucht stets einen Kernel-Call">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1784910118219" ID="ID_560621411" MODIFIED="1784910129209" TEXT="das ist der wichtigste Vorteil von IO_URING"/>
<node COLOR="#335352" CREATED="1785860960381" ID="ID_333032086" MODIFIED="1785861084358" TEXT="lang laufender Thread — parallel zu meinen eigenen Recherchen">
<font NAME="SansSerif" SIZE="11"/>
</node>
<node COLOR="#335352" CREATED="1785860994323" ID="ID_525300724" MODIFIED="1785861084358" TEXT="Ausgangspunkt war meine eigene Unsicherheit im Begriffsgebrauch">
<font NAME="SansSerif" SIZE="11"/>
</node>
<node COLOR="#335352" CREATED="1785861008363" ID="ID_1530707411" MODIFIED="1785861084358" TEXT="habe mir dann Details erklären lassen, die ich nur ungefär wußte">
<font NAME="SansSerif" SIZE="11"/>
</node>
<node COLOR="#335352" CREATED="1785861023766" ID="ID_391668172" MODIFIED="1785861084356" TEXT="gegen Ende wurde es eine Debatte zu Unix/Design-Philosophien">
Ich verfüge über vertieftes Wissen und einiges an Erfahrung in diesen Bereichen, sollte aber meine Kenntnisse überprüfen und festigen, um auch auf Fragen eingehen zu können. Im Besonderen zu Kernel-nahen Themen weiß ich ehr wenig.
<node CREATED="1784599287789" ID="ID_756195091" MODIFIED="1784599304567" TEXT="machmal wird auch unterschieden zwischen synchronisation barrier und memory barrier"/>
</node>
<node CREATED="1784600731066" ID="ID_1114913802" MODIFIED="1784600735725" TEXT="Ursprung der Begriffe">
<node CREATED="1784903498677" ID="ID_1041458587" LINK="https://de.wikipedia.org/wiki/Industry_Standard_Architecture" MODIFIED="1784905020228" TEXT="Industry Standard Architecture (ISA)"/>
<node CREATED="1784903604215" ID="ID_1994086427" MODIFIED="1784905020228" TEXT="ARM Manuals use the term "barrier""/>
<node CREATED="1784903616247" ID="ID_821194885" MODIFIED="1784905020228" TEXT="Intel/AMD uses "fences" and has fence-Instructions"/>
<node CREATED="1784903638786" ID="ID_499701429" MODIFIED="1784905020228" TEXT="Power hat sync-Instruktionen (werden im Handbuch als synchronisation barriers) beschrieben"/>
</node>
<node CREATED="1784903476009" ID="ID_688864045" MODIFIED="1784905020228" TEXT="2. The four-way taxonomy">
<node CREATED="1784903693418" ID="ID_1045852271" MODIFIED="1784905020228" TEXT="stammt aus dem SPARC-Umfeld">
<node CREATED="1784903717049" ID="ID_1030627846" MODIFIED="1784905020228" TEXT="Sparc hat instruktionen mit einer Barrier-Bitmask"/>
"barrier/fence is hardware vocabulary for a specific machine instruction; memory_order is C++'s hardware-independent vocabulary for a guarantee; the compiler's job is to translate one into the other — and 'fence' in the standard specifically means the standalone
<p>
<code http-equiv="content-type" content="text/html; charset=utf-8" class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">atomic_thread_fence</code>, not a synonym for <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">memory_order</code>."
<a rel="mw:WikiLink" href="https://en.wikipedia.org/wiki/Douglas_C._Schmidt" title="Douglas C. Schmidt">Douglas C. Schmidt</a><br /><u>Pattern-Oriented Software Architecture Volume 2</u>:<br />Patterns for Concurrent and Networked Objects
<node BACKGROUND_COLOR="#accdc3" COLOR="#3f4015" CREATED="1784907162385" ID="ID_1402937823" MODIFIED="1784907178100" STYLE="fork" TEXT="Claude hat im Netz gesucht und die Größenordnung bestätigt">
"A synchronization primitive's instruction-level cost is what a hot microbenchmark measures; its systemic cost — coherence traffic under contention, and blocking/wake latency when it isn't contended — is what your production tail latency measures, and the two can differ by two to four orders of magnitude."
man kann einen Kernel-Thread konfiguieren, der die Submission-Queue pollt. Dort konfiguriert man eine Einschlafe-Periode. Wenn der Poller schläft, setzt er ein Bit und muß von der Applikation explizit wieder reaktiviert werden.
<node CREATED="1785374262221" ID="ID_791328949" MODIFIED="1785374270705" TEXT="Future wird nur ein einziges mal geprüft"/>
<node CREATED="1785374271271" ID="ID_1622542937" MODIFIED="1785374276777" TEXT="in der Regel ist der Wert schon da"/>
<node CREATED="1785374277447" ID="ID_1273394515" MODIFIED="1785374296358" TEXT="⟹ läuft in den »uncontended« branch des unterliegenden Futex"/>
<node CREATED="1785376387374" ID="ID_10839834" MODIFIED="1785376421394" TEXT="im Kernel dann gibt es einen entry-Stup (sichert weiteren Prozessor-State)"/>
<node CREATED="1785376444393" ID="ID_1935728415" MODIFIED="1785376496241" TEXT="Page-Table swap / hier passieren Meltdown-Mititgations">
<node CREATED="1785379323178" ID="ID_1435039698" MODIFIED="1785379332276" TEXT="in eine mem-mapped area im userspace"/>
</node>
<node CREATED="1785379355285" ID="ID_903959948" MODIFIED="1785379371231" TEXT="memory mapping geht typischwereise via trap/page fault">
<node CREATED="1785379376779" ID="ID_1210575438" MODIFIED="1785379387038" TEXT="erst bei Zugriff passiert eine Trap"/>
<node CREATED="1785379387490" ID="ID_1395999338" MODIFIED="1785379393300" TEXT="Aufwand ähnlich wie ein Kernel-call"/>
<node CREATED="1785379395416" ID="ID_1593183459" MODIFIED="1785379411081" TEXT="dann wird geprüft: sind die Daten bereits im Kernel-Page-Cache">
<node CREATED="1785379411798" ID="ID_758477303" MODIFIED="1785379418186" TEXT="ja: einfach das Mapping eintragen"/>
<node CREATED="1785379418573" ID="ID_821579792" MODIFIED="1785379427772" TEXT="nein: das IO auf den Weg bringen"/>
</node>
</node>
<node CREATED="1785379448249" ID="ID_391864672" MODIFIED="1785379459343" TEXT="ABER: Kohärenz / Alignment sind das Problem">
<node CREATED="1785379460211" ID="ID_1126553137" MODIFIED="1785379475287" TEXT="normales read() kann an beliebigen Offset lesen"/>
<node CREATED="1785379477453" ID="ID_1182558436" MODIFIED="1785379498703" TEXT="sowas muß zwingend mit einer weiteren Kopie im Kernel realisiert werden"/>
<node CREATED="1785379507593" ID="ID_1859490386" MODIFIED="1785379522058" TEXT="nur wenn man O_DIRECT verwendet, kommt man ohne Kopie aus"/>
<node CREATED="1785379579783" ID="ID_98992954" MODIFIED="1785379593121" TEXT="es gibt diverse Constraints zu beachten">
<node CREATED="1785379593918" ID="ID_1333013861" MODIFIED="1785379636649" TEXT="vor allem : VRAM ≙ RAM"/>
<node CREATED="1785379637415" ID="ID_1927386268" MODIFIED="1785379647023" TEXT="das würde also nur bei integrierter Grafik funktionieren"/>
</node>
<node CREATED="1785379657266" ID="ID_1701186306" MODIFIED="1785379678483" TEXT="ebenfalls (noch) nicht geklärt: funktioniert es mit konkreten GPUs und IO-Controllern"/>
<node CREATED="1785460636982" ID="ID_1471899646" MODIFIED="1785460646186" TEXT="Historie und Kernel-Architektur">
<node CREATED="1785460654246" ID="ID_1541397265" MODIFIED="1785460672884" TEXT="Linux beruht immer noch im Kern auf einem synchronen Modell"/>
<node CREATED="1785460673714" ID="ID_1722879183" MODIFIED="1785460694557" TEXT="Windows(NT) und BSD haben schon länger eine essentiell asynchrone Struktur"/>
<node CREATED="1785460704814" ID="ID_431321839" MODIFIED="1785460714572" TEXT="warum hat Linux so lange gebraucht?">
<node CREATED="1785460715693" ID="ID_1245470107" MODIFIED="1785460751768" TEXT="man hat nicht »geschlafen«">
<node CREATED="1785460755305" ID="ID_1752698985" MODIFIED="1785460765988" TEXT="aber man hat mehrfach einen Ansatz versucht, der gescheitert ist">
<node CREATED="1785460770789" ID="ID_971932172" MODIFIED="1785460801851" TEXT="man hat versucht, „Syscalls asynchron zu machen“"/>
<node CREATED="1785460833117" ID="ID_335280595" MODIFIED="1785460858629" TEXT="das scheitert daran, daß man dann sukzessive viele Kernel-Strukturen aufdoppeln müßte"/>
<node CREATED="1785460866904" ID="ID_1886883732" MODIFIED="1785460932865" TEXT="oder (wie bei libaio) daß jedes einzelne Subsystem eine "non-blocking"-Variante bieten müßte">
...was nicht realisierbar ist, und deshalb ist der Ansatz von libaio stecken geblieben und bleibt auf einige Randfälle begrenzt (und noch schlimmer, kann jederzeit auf blocking waits zurückfallen)
<node CREATED="1785460802793" ID="ID_1282819861" MODIFIED="1785460820914" TEXT="IO_Uring dagegen umgeht das Thema »Syscalls«"/>
</node>
<node CREATED="1785460957172" ID="ID_1847144170" MODIFIED="1785460964913" TEXT="aber: die Unix-Kultur war schon ein Problem">
<node CREATED="1785460973671" ID="ID_334979690" MODIFIED="1785460990352" TEXT="das hat sich erst geändert, als das Problem brennend wurde"/>
<node CREATED="1785460990807" ID="ID_1675938710" MODIFIED="1785461010393" TEXT="d.h. als SSDs dafür gesorgt haben, daß Linux zum Bottleneck wird"/>
</node>
<node BACKGROUND_COLOR="#accdc3" COLOR="#3f4015" CREATED="1785461018940" ID="ID_1539303083" MODIFIED="1785461038542" STYLE="fork" TEXT="Claude führt BSD* als einen interessanten Zwischenfall auf">
<node CREATED="1785461042173" ID="ID_667957116" MODIFIED="1785461061694" TEXT="BSD hat seit 2000 ein asynchrones Notifikations-System (kqueue)"/>
<node CREATED="1785461064042" ID="ID_1779599299" MODIFIED="1785461071883" TEXT="deshalb kann es echtes AIO bieten"/>
<node CREATED="1785461073404" ID="ID_877504311" MODIFIED="1785461093981" TEXT="das ist und bleibt aber fragmentiert (⟶ die ganze Unix-Legacy)"/>
<node CREATED="1785461094856" ID="ID_521796255" MODIFIED="1785461114055" TEXT="deshalb hatte BSD bisher noch keine brennende Notwendigkeit, etwas zu tun"/>
As of January 2026, Axboe is actively fixing this: a rapidly evolving patch series adds a restriction mechanism to io_uring itself, since io_uring's operations are analogous to system calls and one might well want to restrict them the same way. Notably, it uses classic BPF rather than eBPF — because cBPF can be used by unprivileged processes while eBPF requires CAP_BPF, and unprivileged accessibility matters for the container-sandboxing use case; Axboe acknowledged this costs usability, since filters must now be written in cBPF bytecode.
And here's the irony I'd actually enjoy putting in front of an audience: <strong>io_uring is now reinventing seccomp inside itself.</strong> That rhymes precisely with why fibrils were rejected in 2007 — Molnár's objection that a parallel simplified scheduler would inevitably grow into a copy of the real scheduler. Same law, different subsystem: <strong>create a parallel mechanism, and you eventually have to regrow every feature the original had.</strong>  io_uring escaped the syscall interface and is now rebuilding the syscall interface's security machinery from scratch. That's a genuinely good closing thought for a talk about paradigm shifts.
a completion routine the system delivers by interrupting your thread. Results land in an I/O Status Block; you synchronize with event flags. Submit, continue, get called back.
<node CREATED="1785805270424" ID="ID_1212846076" MODIFIED="1785805325165" TEXT="das war hier ein "Randfall" — und in der Praxis irrelevant">
<node CREATED="1785806067739" ID="ID_867470885" MODIFIED="1785806079174" TEXT="allerdings: das läuft alles im Kernel (nicht auf einem externen Device)"/>
</node>
</node>
</node>
</node>
<node CREATED="1785806134178" ID="ID_196718915" MODIFIED="1785806167810" TEXT="»Worse is Better«">
<node CREATED="1785806196578" ID="ID_106898826" LINK="https://yosefk.com/blog/what-worse-is-better-vs-the-right-thing-is-really-about.html" MODIFIED="1785806220192" TEXT="Blog: What "Worse is Better vs The Right Thing" is really about">
<node CREATED="1785806227700" ID="ID_646833802" MODIFIED="1785806241320" TEXT="argumentiert daß es um »evolutionären Erfolg« geht"/>
<node CREATED="1785806242287" ID="ID_1662494576" MODIFIED="1785806257395" TEXT="nicht um besser/schlechter/richtig/falsch"/>
</node>
<node CREATED="1785806885989" ID="ID_1342407665" MODIFIED="1785806905620" TEXT="Richard Gabriel hat mit sich selber eine »Debatte« geführt">
<node CREATED="1785806906727" ID="ID_290906212" MODIFIED="1785806928635" TEXT="sein erster Artikel was als satirische Überzeichnung gedacht"/>
<node CREATED="1785807193346" ID="ID_977154454" LINK="http://dreamsongs.com/Files/worse-is-worse.pdf" MODIFIED="1785807201901" TEXT=""Worse is Better is Worse""/>
</node>
<node CREATED="1785807148579" ID="ID_1979393125" LINK="https://dreamsongs.com/Essays.html" MODIFIED="1785807160610" TEXT="Essays von Richard Gabriel">
<icon BUILTIN="back"/>
<node CREATED="1785807208321" ID="ID_1501711769" MODIFIED="1785807219621" TEXT="beachte: Auseinandersetzung mit Christopher Alexander">
...also eine kleine State-machine implementieren: Completion-Entries entgegennehmen, schauen ob komplett und partiell, partielle nochmal auf den Weg schicken, Komplette am Buffer markieren. Danach würde die Render-Aktion laufen, und lediglich schauen, ob die Daten in »ihrem« Buffer schon da sind. Alles per Modulus gesteuert.
der sollte dann die gleiche Größe haben wie der Kernel-Ringbuffer; man würde damit einen Task sofort in den passenden Buffer-Slot schicken
Damit das funktioniert, muß sich das System selbst beobachten: einen EMA für den IO-Vorlauf; entsprechend viele Zyklen vorher eine neue IO-Aktion auf den Weg schicken.
<node CREATED="1784052477036" ID="ID_1273958721" MODIFIED="1784052501398" TEXT="nach Diskussion mit Claude: Proactor ist didaktisch vorzuziehen">
<icon BUILTIN="yes"/>
<node BACKGROUND_COLOR="#fbfdca" CREATED="1784052519992" ID="ID_1545269972" MODIFIED="1784052885403" TEXT="man kann auch die Timings darüber steuern">
<node CREATED="1784052896300" ID="ID_746832214" MODIFIED="1784052909501" TEXT="kann auf die Weise alle zentralen Konzepte in einem Stück Code zeigen"/>
<node CREATED="1783788564665" ID="ID_941883231" MODIFIED="1783788584317" TEXT="übernehme den Projektrahmen vom FrOSCon-Talk letztes Jahr (Video Output)"/>
<node CREATED="1783788586075" ID="ID_449956672" MODIFIED="1783788647212" TEXT="allerdings vereinfacht auf ein einziges Demo-Executable">
letztes Jahr haben wir vier verschiedene Varianten gezeigt, die jeweils unterschiedliche Lib-Dependencies hatten. Deshalb war es ein Multimodule-Projekt. Das kann ich diesmal vereinfachen in ein einziges Projekt
Hatte immer die Fehlermeldung "build misconfigured" (o.ä). Hab lange rumgesucht, denn alle Settings waren effektiv gleich wie beim »VideoOutput«-Projekt. Bis ich dann im .project-File gesehen hab, daß auch noch ein C-Builder konfiguriert worden war (möglichweise ein Toolchain-Default).
<node CREATED="1783901133887" ID="ID_1114781881" MODIFIED="1783901146536" TEXT="daher die einfachen userspace-Buffer und das normale read()"/>
<node CREATED="1783901151199" ID="ID_168398984" MODIFIED="1783901166527" TEXT="selbstverständlich will ich eine echte pipeline, d.h. mehrere Buffer">
<icon BUILTIN="ksmiletris"/>
</node>
<node CREATED="1783901170599" ID="ID_1292606828" MODIFIED="1783901198318" TEXT="timing/waiting sowie Ownership/Handover ist was ich in der Diskussion klären möchte">
<icon BUILTIN="yes"/>
</node>
</node>
<node CREATED="1783901673639" ID="ID_1158267991" MODIFIED="1783901688375" TEXT="ich frage nach Timing-Sync mit Video-Output">
<node CREATED="1783901711226" ID="ID_1930870094" MODIFIED="1783901723228" TEXT="Claude schlägt vor, überhaupt nicht zu »synchronisieren«"/>
<node CREATED="1783901727663" ID="ID_1596599158" MODIFIED="1783901972168" TEXT="Argument: da gibts nichts zu synchronisieren, denn die Sync geht nicht auf">
Der Desktop läuft mit z.B. 60fps, das video mit 25fps. Man sollte akzeptieren (und im Talk klar machen) daß das niemals aufgeht. Vielmehr sollte man regelmäßig die fertig geladenen Frames übergeben, wenn sie eben da sind. Für den Talk schlägt Claude vor, das Thema "tearing" mehr oder weniger zu ignorieren (hatte ich nicht gesagt, sehe ich aber genauso). Später, für die Prod-Version sei das ein nicht-trivialer Aspekt
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1783901847104" ID="ID_1936627376" MODIFIED="1783901856567" TEXT="Guter Punkt, da hätte ich mich möglicherweise verrant!">
<icon BUILTIN="idea"/>
</node>
</node>
<node CREATED="1783901974887" ID="ID_1974536015" MODIFIED="1783902062028" TEXT="Claude geht davon aus, daß die OpenGL-Pipeline im GUI-Thread laufen sollte">
...das sei zwar nicht notwendig (korrekt!), aber vermeide Komplexitäten. Ein OpenGL-Kontext ist an einen Thread gebunden, also müßte man nach jedem Thread-Wechsel umbinden.
</p>
<p>
⟹ sehr gut, damit hat sich eine Frage von selber geklärt, die ich noch stellen wollte
<node CREATED="1783902186522" ID="ID_80755144" MODIFIED="1783902207310" TEXT="wegen dem Timing weist Claude auf die Möglichkeit hin, das über io_uring selber zu machen">
<icon BUILTIN="back"/>
<node CREATED="1783902209900" ID="ID_168498311" MODIFIED="1783902217323" TEXT="wow ... das hatte ich gar nicht auf dem Schrim"/>
<node CREATED="1783902217878" ID="ID_118182743" MODIFIED="1783902223322" TEXT="das wäre natürlich super elegant"/>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1783902223899" ID="ID_1596372987" MODIFIED="1783902235325" TEXT="allerdings dann definitiv nicht was wir in Lumiera machen werden">
<node CREATED="1783902258661" ID="ID_67058752" MODIFIED="1783902369689" TEXT="wollte ich zwar erst nicht, könnte mich aber mit dem Gedanken anfreunden">
....es wäre nämlich tatsächlich dann ganz ideomatisch (so hab ich die Doku verstanden, und Claude sagt das von sich aus auch).
</p>
<p>
Zwar hatte ich die Idee, im Talk schon grundsätzlich etwas zu machen, was funktioniert wie in Lumiera geplant. Aber wenn ich mir das <i>wirklich vom didaktischen Gesichtspunkt her nochmal überlege,</i> ist es nicht so geschickt.
<node CREATED="1783902501677" ID="ID_742016664" MODIFIED="1783902513392" TEXT="Claude fragt genauer nach der GTK-Integration">
<node CREATED="1783902514414" ID="ID_1855924638" MODIFIED="1783902527158" TEXT="ich gebe Kontext: "Gtk the toolkit, not the framework""/>
<node CREATED="1783902529522" ID="ID_117691046" MODIFIED="1783902544351" TEXT="erkläre wie der Demo-Code vom letzten Jahr grundsätzlich funktioniert"/>
<node CREATED="1783902544813" ID="ID_265030509" MODIFIED="1783902552490" TEXT="Claude meint, das vereinfache das Design"/>
<node CREATED="1783902552987" ID="ID_1533807493" MODIFIED="1783902569992" TEXT="er schlägt vor: nur einen »Tick« verwenden, und zwar io_uring"/>
<node CREATED="1783902573851" ID="ID_451286400" MODIFIED="1783902590704" TEXT="wenn ein Frame ready ist, sollte man lediglich dem GUI-Thread signalisieren"/>
<node CREATED="1783902591217" ID="ID_1763048000" MODIFIED="1783902681362" TEXT="er schlägt dafür g_idle_add() vor -- das sei low-level GLib und weithin etabliert">
<node CREATED="1783902821732" ID="ID_1465201307" MODIFIED="1783902838122" TEXT="getriggert würde dann der Code, der die OpenGL-Pipeline mit neuen Daten versorgt"/>
<node CREATED="1783902838536" ID="ID_1259653595" MODIFIED="1783902845946" TEXT="dieser würde mithin im GTK-Thread laufen"/>
<node BACKGROUND_COLOR="#efdeb8" CREATED="1783956967738" ID="ID_1170137190" MODIFIED="1783957012593" TEXT="Wichtige Einsicht: warum nicht jeder Desktop-Frame per Buffer-Flip bedient werden muß">
<icon BUILTIN="idea"/>
<node CREATED="1783957017373" ID="ID_1419210108" MODIFIED="1783957033385" TEXT="wenn wir neue daten haben dann triggern wir die Anzige-Pipeline"/>
<node BACKGROUND_COLOR="#accdc3" COLOR="#3f4015" CREATED="1783957040816" ID="ID_468719143" MODIFIED="1783957188965" STYLE="fork" TEXT="das funktioniert weil darunter ein Compositor sitzt">
As an aside: do I assume correct that the OpenGL side will just redisplay the same data if nothing is sent for intermittent buffer flips (assuming that the desktop frame rate is higher than the video frame rate)?
</li>
</ul>
<p>
</p>
<p>
<strong http-equiv="content-type" content="text/html; charset=utf-8">Your aside — yes, and here's the actual mechanism:</strong> with swap interval 0 and swaps only triggered by <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">frameReady.emit()</code>, you are <em>not</em> relying on OpenGL to "resend" anything between your swaps — OpenGL/EGL has no ongoing activity at all in between. What actually keeps the picture on screen is the desktop compositor: once <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">eglSwapBuffers()</code> makes a buffer the current front buffer, that's simply what's there until you swap again, and the compositor samples it at its own repaint cadence (its vsync, typically 60Hz+) regardless of whether your app does anything. So your assumption holds, but the credit belongs to "a swapped buffer is persistent state the compositor keeps re-showing," not to any active redisplay behavior on your side — a good one-sentence clarification to have ready if someone in the audience asks "wait, doesn't something have to keep pushing frames?"
<node CREATED="1783904918332" ID="ID_788373194" MODIFIED="1783904930062" TEXT="Claude bestätigt: der Umbau der GtkApp dürfte trivial sein"/>
<node CREATED="1783904930773" ID="ID_1456697138" MODIFIED="1783904945590" TEXT="er schlägt vor: ich sollte auch den onFrame-Callback so erhalten, nur anders aufrufen"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#520f69" CREATED="1783904751803" ID="ID_648202546" MODIFIED="1783904801052" TEXT="lasse mir von Claude zwei Code-Templates generieren">
<icon BUILTIN="edit"/>
<node CREATED="1783904765875" ID="ID_1730135150" MODIFIED="1783904774302" TEXT="die C-Lösung mit g_idle_add()"/>
das heißt: die Lösung, auf die es nun für den Talk hinausläuft, ist daß ich nicht wirklich einen "Worker" hab (kein Vorgriff auf die Lumiera Engine), sondern einen Proactor.
<node BACKGROUND_COLOR="#fefc4e" COLOR="#351d75" CREATED="1784052687896" ID="ID_1489274093" MODIFIED="1784052865429" TEXT="interessanter Ansatz: man kann einen Kernel-Timer in IO_Uring einbinden">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Darauf wäre ich nicht gekommen; ich hätte an meinem von Lumiera abgeleiteten Schema festgehalten....
</p>
<p>
Claude betont, das wäre idiomatisch und würde die Proactor-Loop ins Zentrum stellen. Das überzeugt mich ⟹ werde dann also doch einen Proactor in der Demo zeigen
Ich verwende das aktuelle "Sonnet" auf Stufe Medium. Das braucht erhebliche Rechenzeit für jede Antwort auf diesem Diskussionslevel (und zeigt auch jeweils expandierende, schlußfolgernde und kondensierende Phasen an)
<node CREATED="1783953200905" ID="ID_1912082579" MODIFIED="1783953252578" TEXT="aber er faßt die von mir genannten Optionen zusammen in zwei Klassen">
<strong>Proactor, confirmed.</strong> io_uring is the textbook proactor: you submit a description of the completed operation you want, the kernel does the work, and your thread's job is purely to consume results and act on them — as opposed to a reactor (epoll-style), where you're told "this fd is ready," and <em>you</em> still perform the (potentially blocking, now guaranteed-non-blocking) I/O yourself. Good instinct to name this explicitly in the talk; it's the single sentence that makes the rest of the design legible.
<strong>On the "abstraction of state progression" claim</strong> — I think it's correct, but I'd collapse your four options into two families rather than four separate things:
<strong>Implicit state, paid for in threads.</strong> Thread-per-operation blocking I/O doesn't <em>avoid</em> needing a state machine — it hides one inside the OS thread: the thread's stack and program counter <em>are</em>  the state ("I am here, at this line, holding these locals"). You get state-tracking for free, but you pay for it in thread/stack cost per concurrent operation, which is exactly what proactor-style async I/O exists to avoid.
<strong>Explicit state, paid for in bookkeeping.</strong> Everything else — hand-rolled flags, continuation chains, and coroutines — is the <em>same</em>  idea at different levels of automation. A coroutine is, mechanically, a compiler-synthesized state machine: <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">co_await</code> points become case labels, locals that need to survive a suspension become member fields of a generated struct. Continuation-passing is the same thing done by hand with closures instead of compiler codegen. So "coroutines" and "explicit state engine" aren't really two different answers to your question — a coroutine <em>is</em> an explicit state engine, just one you didn't have to write by hand.
Given that framing: you're right that a flag-per-buffer is not a lesser or simplified version of "the real solution" — it's the same solution as coroutines, just written manually because your problem is small and linear enough that the compiler-generated version would be pure overhead (both in runtime terms and, more importantly here, in <em>audience cognitive load</em> — introducing C++20 coroutine machinery to explain a 3-state pipeline would be a bad trade for this talk).
Since each slot has exactly one producer (the worker) and one consumer (the GUI thread, via the dispatcher callback) and they never touch a slot at the same time by construction,
<p>
<code http-equiv="content-type" content="text/html; charset=utf-8" class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">std::atomic<SlotState></code> with release-on-write / acquire-on-read is enough — no mutex needed. That pairing is worth a beat in the talk on its own: the atomic isn't there to prevent concurrent writes (there aren't any), it's there to guarantee the GUI thread sees the <em>buffer contents</em> the worker wrote, not just the state flag — a clean, concrete illustration of why acquire/release exists, tied directly to something the audience just watched you build.
<node CREATED="1783953378671" ID="ID_1599260447" MODIFIED="1783953395622" TEXT="Claude sagt, man sollte dann jeden Buffer auch mit der Frame-Nummer markieren"/>
<node CREATED="1783953396149" ID="ID_12931299" MODIFIED="1783953416430" TEXT="ich sage: das bekommt man doch von selbst, wenn man die Buffer in einen Ring organisiert"/>
<node BACKGROUND_COLOR="#accdc3" COLOR="#3f4015" CREATED="1783953941213" ID="ID_713186135" MODIFIED="1783954028109" STYLE="fork" TEXT="Claude greift das auf, betont aber (nochmal) daß die CQ-Reihenfolge nicht garantiert ist">
The ring idea is correct, and it's the right way to lay out storage — but it solves a different problem than the one we flagged last time, and I think that's the thing worth pulling apart carefully, because the two compose nicely rather than one replacing the other.
<strong>What the cyclic layout gives you:</strong> a deterministic mapping from frame number to physical buffer — <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">slot = frameNumber % N</code> — so you never need a free-list, an allocator, or any "find me an empty slot" search. You always know exactly where frame <em>K</em>'s data belongs before you even submit the read. That's a clean, standard pattern and exactly right for a fixed pool of reusable buffers.
<strong>What it does <em>not</em> give you for free:</strong> the display-order guarantee. The ring tells you <em>where</em> frame K's bytes live; it says nothing about <em>when</em> the read for frame K finishes relative to the read for frame K+1. Two SQEs submitted in order are not guaranteed to complete in order — for sequential reads against one local file on one machine it's very likely in practice, but "likely" is exactly the kind of unverified pragmatism you just said you don't accept. So you still need the mechanism from last time: track which frame is <em>next expected for display</em>, and only <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">emit()</code> once that specific slot says <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">Ready</code>  — regardless of what else has completed in the meantime.
<node CREATED="1783954070297" ID="ID_1690793152" MODIFIED="1783954092918" TEXT="man sollte die frameNr als "user data" verwenden">
<icon BUILTIN="idea"/>
<node CREATED="1783954096287" ID="ID_1210379052" MODIFIED="1783954102642" TEXT="da wäre ich nicht draufgekommen"/>
<node CREATED="1783954103307" ID="ID_399338998" MODIFIED="1783954150362" TEXT="trotzdem würde ich die übliche Praxis mit dem Pointer darstellen"/>
</node>
<node BACKGROUND_COLOR="#accdc3" COLOR="#3f4015" CREATED="1783954171957" ID="ID_1248856525" MODIFIED="1783954243633" STYLE="fork" TEXT="sollte einen "nextExpected"-Cursor im Thread-State mitführen">
Keep one cursor, <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">nextExpected</code> (monotonically increasing, starts at 0). On every completion, mark <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">slots[frameNumber % N]</code> as <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">Ready</code>. Separately — and this can literally be a small loop, since bursts of completions can land between two checks — while <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">slots[nextExpected % N].state == Ready</code>: emit the dispatcher for that slot, mark it <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">Empty</code>  again, <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">++nextExpected</code>.
    io_uring_cqe_seen(&ring, cqe);       // MUST always call this, or the CQ ring fills and stalls
The reason top-up belongs in <code>onTick</code> rather than in <code>onReadComplete</code>:<br />a slot only becomes reusable once the <em>GUI thread</em> has finished drawing it and flips it back to <code>Empty</code>  — and the worker, sitting blocked in <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">io_uring_wait_cqe</code>, has no way to know that happened except by waking up for <em>something</em>. The tick is that guaranteed periodic wake-up, so it doubles as "check if there's new capacity to fill," with a worst-case latency of one tick period (~40ms) before a freed slot gets reused — fine at this cadence, and a nice illustration that the timer isn't just pacing display, it's also the thing that keeps the whole state machine alive even when nothing else is happening.
can you write me a short inline function that takes the "40 millisecods" as a std::chrono spec ("40ms") and returns the struct __kernel_timespec
</li>
</ul>
<p>
#include <chrono>
</p>
<p>
#include <linux/time_types.h>   // struct __kernel_timespec (also pulled in via liburing.h)
<node COLOR="#338800" CREATED="1783964942767" ID="ID_993102807" MODIFIED="1783966105865" TEXT="lasse Claude die Diskrepanz herausarbeiten gegenüber dem Proactor-Pattern">
<node CREATED="1783966132732" ID="ID_227446892" MODIFIED="1783966134051" TEXT=""someone has to drain the CQ""/>
<node CREATED="1783966148026" ID="ID_1364400629" MODIFIED="1783966149873" TEXT="what guarantees the CQ actually gets drained in a timely fashion?"/>
<node CREATED="1783966160726" ID="ID_1852031512" MODIFIED="1783966162572" TEXT="who owns the ring at engine scale?"/>
</node>
<node CREATED="1783966216653" ID="ID_62921124" MODIFIED="1783966234722" TEXT="ich frame das Problem mit den lang laufenden Trasks als »Backpressure«">
<node BACKGROUND_COLOR="#accdc3" COLOR="#3f4015" CREATED="1783966276865" ID="ID_1822059325" MODIFIED="1783966298429" STYLE="fork" TEXT="bemerkt: es ist offen ob das genügt">
As far as I could see from looking at the liburing sources, there is a fundamental read barrier before retrieving/updating the rings, and a write barrier at the other side (when done with a completion or submitting). Now you also pointed out the conclusion that submitting the next IO task could itself be a scheduled activity. Combining both, if we ensure that interaction with io_uring happens only in the "mutual exclusive" phase (i.e. the worker holds the GroomingToken) -- then that would ensure that, at any given time, only one thread at max interacts with the urings. And Liburing inserts the necessary barriers, so that the next task to enter that zone would see the changes. Does that reasoning hold? What difficulties do you see?
<node BACKGROUND_COLOR="#accdc3" COLOR="#3f4015" CREATED="1783966388626" ID="ID_857234213" MODIFIED="1783966398679" STYLE="fork" TEXT="yeour reasoning holds, with one caveat that matters a lot and a couple of smaller ones.">
Ja, weiß ich. Deshalb hab ich's so programmiert. Freut mich daß Claude da unabhängig zum gleichen Schluß kommt (denn ich hab mich oft gefragt, ob ich mich da in Spitzfindigkeiten verrenne).<br />Also nochmal explizit: memory_order_relaxed reicht hier nicht<br />
<node CREATED="1783966538813" ID="ID_340512988" MODIFIED="1783966733292" TEXT="das GroomingToken und die Barrieren in liburing dienen verschiedenen Zwecken">
Einmal geht es um shared-data zwischen Kernel und Userspace. Wohingegen das Grooming-Token die Sichtbarkeit über die Worker hinweg steuert.
</p>
<p>
</p>
<p>
Diese Unterscheidung ist konzeptionell (sehe ich so, Claude deutet es auch so). Beide Ansätze stören sich nicht, man sollte sie aber auseinanderhalten. Ich denke, das ist ein generischer guter Rat beim Design solcher Systeme, man sollte nicht danach streben, solche verschiedenen Belange zusammenzufassen, selbst wenn es im konkreten Fall möglich wäre (wie hier der Fall, aber nur weil keine data-dependenciy im memory-ordering includiert ist)
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1783966752311" ID="ID_1363514128" MODIFIED="1783966837345" TEXT="whatever you do inside the token-held section must never block! ">
That's a much bigger problem than in the FrOSCon demo, where blocking on
<p>
<code http-equiv="content-type" content="text/html; charset=utf-8" class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">wait_cqe</code> was the worker's <em>entire job</em>. Here it would reintroduce exactly the kind of global stall your pull architecture is designed to avoid. The fix is straightforward but needs to be deliberate: only ever use the non-blocking <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">io_uring_peek_cqe()</code>  inside grooming — check if anything's ready, harvest what's there, submit what's ready to submit, and move on regardless of whether anything was found. That keeps the ring interaction cheap and bounded, consistent with a critical section that's already supposed to be short.
CQ overflow: if grooming genuinely doesn't run for a while under heavy CPU load, does a full completion queue drop completions, or buffer them? Recent kernels buffer overflow internally rather than dropping (subject to
<p>
<code http-equiv="content-type" content="text/html; charset=utf-8" class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">IORING_FEATURE_NODROP</code>-era behavior), but it's worth confirming for whatever kernel baseline you commit to, rather than assuming.
<code http-equiv="content-type" content="text/html; charset=utf-8" class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">IORING_SETUP_SQPOLL</code>. It's tempting since it removes the need to call into the kernel for submission most of the time, but it works by adding a kernel-side polling thread that reads the SQ ring on its own schedule — an actor outside your GroomingToken discipline and outside your capacity self-calibration entirely. That's exactly the kind of uncontrolled independent actor your architecture is built to avoid.
Net: I think folding I/O into the same single-threaded grooming discipline you already have is the
<p>
<em http-equiv="content-type" content="text/html; charset=utf-8">consistent</em> choice, not a compromise — you've already accepted one global serialization point for scheduling decisions, and a small, non-blocking peek/submit pair is cheap enough to ride along in that same section without becoming a new bottleneck category. The real design work is less "is this safe" (I think it is, modulo the ordering-semantics check and the non-blocking discipline) and more "how do we know, empirically, that grooming-section latency stays small enough once I/O bookkeeping is added" — which sounds like exactly the kind of thing you'd want numbers for before committing, rather than reasoning about further in the abstract.
<strong http-equiv="content-type" content="text/html; charset=utf-8">Current 2 — thread-per-core, shared-nothing, and it's picking up real steam.</strong> This is the more consequential trend to be aware of, because it's a genuinely different answer to the same problem you're solving, and it's currently the fashionable one in high-performance I/O-heavy systems: pin one thread per core, partition data and work by that core (typically via hashing), eliminate cross-thread shared state entirely, and communicate exclusively via message passing rather than shared queues or locks. This is the architecture behind ScyllaDB and Redpanda via the Seastar framework, and it's spreading into the Rust ecosystem too (Glommio, compio, and others). A recent writeup from the Apache Iggy project frames the shift precisely as moving from work stealing to "work steering" — i.e., instead of idle workers reaching into a shared structure (what you have), work is routed to the specific core that already owns the relevant data, and nobody has to contend for anything. Interestingly, the standard advice against a single shared io_uring instance per application is exactly the contention concern we discussed for your ring — each thread in Glommio gets its own private set of rings instead, which is the thread-per-core answer to the same "who owns the ring" question you and I just spent a while on. <a href="https://iggy.apache.org/blogs/2026/02/27/thread-per-core-io_uring/" target="_blank" class="group/tag relative h-[18px] rounded-full inline-flex items-center overflow-hidden -translate-y-px cursor-pointer">Apache + 2</a>
Even more directly relevant to your capacity-calibration idea: Glommio ships built-in "controllers" that automatically adjust per-task-queue scheduler shares to control throughput against a user-specified criterion — that's essentially your self-calibrating capacity-weights idea, independently arrived at by a different team solving an adjacent problem. Worth knowing that's not an idiosyncratic idea of yours — it's something the field has landed on more than once, which is generally a good sign for an architectural instinct.
<strong>Where I'd place your design relative to these two currents:</strong> your GroomingToken-serialized shared-scheduler model sits closer to "classic" worker-pool architecture than to shared-nothing thread-per-core — and I think that's the <em>right</em> call for Lumiera specifically, not a lag behind the state of the art. The strongest argument for thread-per-core is when per-request overhead is so small (network request handling, KV-store lookups — sub-microsecond territory) that even brief lock contention or cache-line bouncing dominates the cost. Your own numbers — single-digit milliseconds up into seconds per frame task — are three to six orders of magnitude coarser than that regime. A brief critical section for grooming and ring bookkeeping is genuinely negligible next to task costs measured in milliseconds; it would not be negligible next to costs measured in tens of nanoseconds, which is the world Seastar/ScyllaDB actually live in. So I wouldn't read "thread-per-core is trendy" as pressure to abandon your model — I'd read it as: the technique exists and is well-proven if your task granularity ever drops by several orders of magnitude (which, for a video render engine, seems unlikely — your bottleneck is decode/filter/encode work, not tiny message dispatch).
<strong>One trend worth just keeping an eye on, not acting on:</strong> core counts keep climbing — high core-count workstation and consumer chips are increasingly normal — and any single serialization point gets proportionally more expensive as contention scales with thread count, even if each individual crossing is cheap. Not a problem today, and your task granularity buys you a lot of headroom, but it's the kind of thing worth having empirical data on (exactly the "more empirics needed" conclusion you already reached) if Lumiera is ever deployed on genuinely large core counts rather than typical desktop/workstation counts.
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1783967758928" ID="ID_284611592" MODIFIED="1783967785981" TEXT="sollte Contention um das single-threaded bottleneck im Blick behalten">
von Claude erwähnt im Zusammenhang mit Locking visibility. Er weist auch darauf hin daß io_uring keine multiple thread submissions unterstützt. Zu dem Schluß war ich ja auch gekommen
der Kernel kann nicht zaubern; stattdessen hat er dann einfach einen poll-Worker. Keine gute Idee in einer Architektur die selber alle Resourcen steuern möchte
Your instinct is basically right, but I'd sharpen "not too deep" a bit: the EGL calls that matter for your loop — <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">eglCreateContext</code>, <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">eglMakeCurrent</code>, <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">eglSwapBuffers</code> — are identical either way. What differs is only the step just before <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">eglCreateWindowSurface</code>, i.e. how you obtain the native window handle from GDK:
X11: you already have this — <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">gdk_x11_window_get_xid()</code> gives you a raw <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">Window</code> XID directly usable as the native window type.
So it's genuinely a small, well-isolated patch of platform glue — a handful of lines, gated behind a runtime check of which GDK backend is active (<code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">GDK_IS_X11_DISPLAY</code> / <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">GDK_IS_WAYLAND_DISPLAY</code>) — everything downstream of surface creation is untouched.
<node CREATED="1783968039719" ID="ID_1431893413" MODIFIED="1783968050997" TEXT="für die Daten-Sichtbarkeit genügt eine atomic-state-flag"/>
<node CREATED="1783968058381" ID="ID_234180982" MODIFIED="1783968077778" TEXT="IO_URING hat selber einen Timing-Mechanismus ⟹ den sollte man nutzen"/>
<node CREATED="1783968139661" ID="ID_721741944" MODIFIED="1783968157925" TEXT="Proactor ist push — unsere Architektur ist konsistent pull"/>
<node COLOR="#5b280f" CREATED="1783968173638" ID="ID_1363800541" MODIFIED="1783968193807" TEXT="man sollte nicht versuchen, einen Proactor in unser Design zu integrieren">
<icon BUILTIN="stop-sign"/>
</node>
<node CREATED="1783968195246" ID="ID_1729925953" MODIFIED="1783968212467" TEXT="stattdessen kann man die Proactor-Loop in Activities oder Jobs packen"/>
<node CREATED="1783968233008" ID="ID_1599145728" MODIFIED="1783968259313" TEXT="Auf Engine-Level: Zugang zum URing muß in der »Grooming-Zone« bleiben">
<icon BUILTIN="messagebox_warning"/>
</node>
<node CREATED="1783968264384" ID="ID_1390930082" MODIFIED="1783968317234" TEXT="das ist ausreichend um die Cross-Thread-Visibility sicherzustellen">
aber man sollte konzeptionell zwischen der visibility mit dem Kernel und der Visibility zwischen den Workern unterscheiden; für ersteres gibt es die Barrieren in Liburing
der Umstand daß neue IO-Aktivitäten gescheduled werden und Completions entnommen werden müssen, garantiert nur eine passive Backpressure (nicht entnommene Completions gehen nicht verloren, und der Platz in den URings ist begrenzt). Sehr wahrscheinlich ist mehr notwendig, damit die Engine rund läuft.
Es ist eine etablierte und bewährte Methode, und wird nicht weggehen. Was wir geschaffen haben konvergiert gut mit den allgemeinen Einsichten im Feld
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1783985102373" ID="ID_734300736" MODIFIED="1784076612700" TEXT="Aber: die Ablaufsteuerung liegt jetzt nicht mehr (komplett) in GTK">
<node CREATED="1783985334643" ID="ID_291484889" MODIFIED="1783985343649" TEXT="muß im Receiver-Thread erzeugt und zerstört werden"/>
<node CREATED="1783985344196" ID="ID_1733483538" MODIFIED="1783985362637" TEXT="sollte vor allen anderen Threads erzeugt werden (⟹ Sichtbarkeit)"/>
</node>
<node CREATED="1783985372148" ID="ID_1967828108" MODIFIED="1783985396343" TEXT="alle Dispatcher-Objekte eines receiver(Loop)-Threads verwenden eine einzige Pipe">
<node CREATED="1783985399747" ID="ID_720330070" MODIFIED="1783985405923" TEXT="Locks niemals auf der Senderseite"/>
<node CREATED="1783986693369" ID="ID_1838622028" MODIFIED="1783986710414" TEXT="GTK-Bezüge sind auch für das EglDisplay wichtig"/>
<node CREATED="1783986712145" ID="ID_625334732" MODIFIED="1783986726835" TEXT="Dispatcher ist zentraler Bestandteil meiner Demo"/>
<node CREATED="1783986758056" ID="ID_223369723" MODIFIED="1783986770513" TEXT="auch das Thema »Threading« gehört in den Scope der Demo"/>
</node>
</node>
<node CREATED="1784045996386" ID="ID_1209517516" MODIFIED="1784046001812" TEXT="immer noch schwierig....">
<node CREATED="1784046009218" ID="ID_20536040" MODIFIED="1784046024950" TEXT="jetzt habe ich ein Objekt — das sollte non-copyable sein"/>
<node CREATED="1784046116554" ID="ID_234421285" MODIFIED="1784046238573" TEXT="die Callback-Hook möchte ich aber trotzdem — aus didaktischen Gründen">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Hier möchte ich sowohl den GTK-Code selber verbergen, alsauch dem Umstand daß die Start-Lokik in der Applikation nicht ganz trivial ist, und mit dem Start des Players verwoben. Lesbarkeit ist eine weitere Motivation: man kann dadurch Dinge benennen
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1784047131109" ID="ID_34162762" MODIFIED="1784047205771" TEXT="also geht es vor allem darum, die Form aufrecht zu erhalten">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
dazu gehört auch, keine »Tricks« anzuwenden und keine schlechten Praktiken vorzuführen. Der Zustands-Träge sollte unique sein, ohne Wenn und Aber.
</p>
</body>
</html></richcontent>
</node>
</node>
</node>
<node CREATED="1783986793999" ID="ID_1360252421" MODIFIED="1783986816919" TEXT="Lösung: baue ein Player-Objekt im Start-Hook">
<node CREATED="1783986820215" ID="ID_360250150" MODIFIED="1783986836070" TEXT="das tritt an die Stelle wo bisher der EglContext stand"/>
<node CREATED="1783986838784" ID="ID_1847977458" MODIFIED="1783986861705" TEXT="Lösung: das EglDisplay wird nun ein weiteres Objekt">
<icon BUILTIN="idea"/>
</node>
<node CREATED="1783986866318" ID="ID_623423104" MODIFIED="1783986874503" TEXT="alles per Konstruktor-Verdrahtung"/>
<node CREATED="1784076715698" ID="ID_102034340" MODIFIED="1784076740355" TEXT="Dispatcher überträgt nur den Trigger über die Thread-Grenzen"/>
<node BACKGROUND_COLOR="#accdc3" COLOR="#010101" CREATED="1784076776201" ID="ID_1043516833" MODIFIED="1784076975728" STYLE="fork" TEXT="Vorschlag von Claude: die State-Machine als Atomic implementieren">
<node BACKGROUND_COLOR="#eae5a4" COLOR="#351d75" CREATED="1784076979882" ID="ID_1843330900" MODIFIED="1784421405261" TEXT="das hat sich durch die Konversation so ergeben">
...es war nicht so, daß Claude diese „Idee gehabt“ hätte — denn ich hatte die Konversation ja so geführt, daß Claude mir meine Konzept-Ansätze validiert und verfeinert. Dann habe ich das Prinzip formuliert, daß für Async-IO irgendwo eine State-Machine sein muß. Claude hat das aufgegriffen, validiert und verschärft; und damit war offensichtlich geworden, daß man diese State-Flag als Atomic auslegen kann. Das habe ich in dem Moment genauso »offensichtlich« gesehen, und Claude hat es ebenso formuliert.
</p>
<p>
Warum ich hier nochmal nachzeichne, wie das zustandegekommen ist:
</p>
<ul>
<li>
weil ich allein da nicht draufgekommen wäre
</li>
<li>
aber weil es offensichtlich nicht von Claude stammt
</li>
</ul>
<p>
⟹ das wirft ein Licht darauf, wie dieses <i>scheinbar intelligente »Generieren« funktioniert, </i>auf Basis einer industriellen Daten-Technik, die Plausibilitäten integriert und interpoliert.
<node CREATED="1784078502730" ID="ID_846472947" MODIFIED="1784078534574" TEXT="darf nur weitergehen, nachdem der vorherige Frame aufgegriffen wurde"/>
<node CREATED="1784078681486" ID="ID_1106864388" MODIFIED="1784078714572" TEXT="und darf nur neue IO beauftragen wenn der Zielpuffer vom Consumer freigegeben werden"/>
</node>
</node>
<node COLOR="#435e98" CREATED="1784079572400" ID="ID_1393056375" MODIFIED="1784079586917" TEXT="wie bekommt der EglDisplayer die Daten?">
Sofern er aus dem GUI-Thread alloziert wird, also bevor der Proactor-Thread startet, ist die Position für beide Threads sichtbar (und unveränderlich)
...nur als lokale Variable, die er jeweils hochzählt, wenn er einen Trigger bekommt (Nachteil: duplizierter State, dessen Konsistenz sich nur implizit ergibt und nicht offensichtlich ist)
Für die Demo ist das die offensichtliche Lösung: man bekommt unique-ownership und Subscript-Operator einfach vom std::unique_ptr. Wenn man den notwendigen Speicher nicht bekommt, dann läuft die Demo eh nicht, also wozu die Umstände?
<node CREATED="1784082547951" ID="ID_1261536746" MODIFIED="1784082582921" TEXT="ist ein std::array aus 8bit-Pixeln"/>
<node COLOR="#5b280f" CREATED="1784082595689" ID="ID_1135557355" MODIFIED="1784132191641" TEXT="verwende diese Typedef aber auch als »Buffer«-Abstraktion">
Mehrere Argumente dafür: man könnte die low-level-Flags setzen (wie <code>O_CLOEXEX, O_NOFOLLOW, </code>oder gar <code>O_DIRECT</code>). Das Öffnen ist <i>atomic,</i>  d.h. das File kann nicht mehr gelöscht/verschoben werden beform man das Filehandle hat (was bei einem getrennten STAT und Path-Check durchaus möglich ist)
da wir stets <i>in bulk</i> die Submissions hinzufügen <i>und erst danach (synchronisiert)</i> den Output antriggern, können das maximal so viele Einträge sein, wie wir Buffer haben
</li>
<li>
<i>zusätzlich</i> wird ein Eintrag benötigt, um am Anfang auch den periodischen Timer in Gang zu setzen
</li>
<li>
eben dieser <i>eine zusätzliche Eintrag</i> genügt auch, um jeweils noch <i>ein</i> Timer-Event zu empfangen
</li>
<li>
weitere Completions können nicht kommen, da wir nicht mehr Submissions abgeschickt haben
</li>
<li>
weitere Timer-Events könnten kommen, falls wir zum Entnehmen und Übergeben mehr als einen Timer-tick brauchen (unwahrscheinlich, aber nicht auszuschließen). In einem solchen Fall würden schlimmstenfalls hinten weitere Timer-Events „runterfallen“ (wobei aktuelle Kernel ein internes Backlog haben). Sollten wir dergestalt Timer-Events verpassen, sind sie aber auch schon überholt, und das nächste reguläre Event wird uns wieder weiterschieben
<node CREATED="1784165743594" ID="ID_465943099" MODIFIED="1784165755001" TEXT="ERRNO steckt im cqe.res">
<icon BUILTIN="idea"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1784165759121" HGAP="34" ID="ID_469358369" MODIFIED="1784165775260" TEXT="mache hier aber keine Fehlerbehandlung...." VSHIFT="4">
<node CREATED="1784165802955" ID="ID_165426868" MODIFIED="1784165813591" TEXT="das geht bei dieser Konstrollstuktur nur indirekt"/>
<node COLOR="#435e98" CREATED="1784165814417" ID="ID_948621808" MODIFIED="1784167329763" TEXT="führe dazu eine weitere Status-Ausprägung ein: STOP">
...und zwar via Glib::Dispatcher ⟶ GUI-Thread.
</p>
<p>
Der zugehörige Handler-Code läuft dann bei nächster Gelegenheit in der GUI-Event-Loop, und holt sich per Callback (Interface PixelFeed) die Daten; in diesem Callback muß die Read-Barrier realisiert sein, damit der GUI-Thread alle vor diesem Punkt erfolgten Datenänderungen auch tatsächlich sieht
Beachte: das darf erst hier passieren, weil wir hier den nächst niedersten erwarteten Frame anschauen; da wir immer etwas im Voraus lesen, werden wir auch ein end-of-File schon einige Ticks früher markieren, müssen aber die Schleife noch solange weiterlaufen lassen, bis die letzten erfolgreich gelesenen Frames in die Anzeige übertragen wurden
<node CREATED="1784166547264" ID="ID_225348495" MODIFIED="1784166564736" TEXT="und zwar könnte der GUI-Thread überlastet sein, und die Daten nicht rechzeitig abholen"/>
<node CREATED="1784166577960" ID="ID_1754845143" MODIFIED="1784166592939" TEXT="damit könnte der nächste Tick passieren, während der GUI-Thread grade arbeitet"/>
<node CREATED="1784166593774" ID="ID_383603118" MODIFIED="1784166605762" TEXT="oder vorher, bevor die Daten überahupt übernommen wurden"/>
<node CREATED="1784166606710" ID="ID_499843773" MODIFIED="1784166618527" TEXT="in beiden Fällen ist der Cursor inkonsitent"/>
In der Chase-Phase werden blank-Frames ausgegeben, solange bis wir Frames mit genügend Vorlauf im Speicher haben. Danach, in der Lock-Phase ist eine Relation zwischen der rotierenden Buffer-Position und dem aktuellen Flip gesetzt. Ab dem Punkt kann man N Frames im Voraus die IO-Aktion losschicken.
Zu Beginn schicken wir M Frames auf den Weg; die brauchen u.U länger. Schön wäre es natürlich, wenn man diesen Selbs-regulierenden Mechanismus auch live zeigen könnte
<node CREATED="1784143310222" ID="ID_1598149960" MODIFIED="1784143340787" TEXT="vielmehr sorgt die feste zyklische Buffer-Struktur für die Limitierung"/>
<node CREATED="1784143015199" ID="ID_218469149" MODIFIED="1784143039421" TEXT="zwei Phasen schreiten jeweils so schnell voran wie derzeig möglich">
Ist nur möglich wenn diese Daten für den erwartungsgemäß nächsten Frame bereits da sind, und der unmittelbar vorausgegangene Frame schon komplett vom Video-Displayer übernommen wurde
<node CREATED="1784335284745" ID="ID_1701920818" MODIFIED="1784337685187" TEXT="es geht nur um eine diagnostische Ausgabe">
<icon BUILTIN="yes"/>
<node CREATED="1784335310132" ID="ID_74981723" MODIFIED="1784335319627" TEXT="hier wird eine Zeitreihe beobachtet">
<icon BUILTIN="idea"/>
</node>
<node CREATED="1784335320658" ID="ID_1702163307" MODIFIED="1784335336932" TEXT="man kann aber nur jeden k-ten-Wert ausgeben (weil sonst zu schnell)"/>
<node CREATED="1784335337812" ID="ID_1692924948" MODIFIED="1784335361432" TEXT="⟹ klassicher Fall für einen exponentiellen-moving-average">
<node CREATED="1784335588727" ID="ID_1900875309" MODIFIED="1784335609726" TEXT="kann Mittelungs-Periode als Template-Parameter definieren"/>
</node>
</node>
<node CREATED="1784335615306" ID="ID_639063024" MODIFIED="1784335631453" TEXT="Code-Lesbarkeit: sollte Timer komplett »daneben« stellen">
<node COLOR="#338800" CREATED="1784335636544" ID="ID_267882121" MODIFIED="1784337678294" TEXT="definiere eine maßgeschneiderte Timer-Klasse in den »commons«">
<icon BUILTIN="button_ok"/>
<node CREATED="1784335697343" ID="ID_1157691393" MODIFIED="1784335705962" TEXT="verwendet ein Array von Einzel-Timern"/>
<node CREATED="1784335706628" ID="ID_848237208" MODIFIED="1784335719033" TEXT="Zeitmessugs-Code mit std::chrono"/>
<node COLOR="#435e98" CREATED="1784335673422" ID="ID_1048715353" MODIFIED="1784337675374" TEXT="die wird dann in eine globale Variable gepackt und gut is">
<node CREATED="1784423360704" ID="ID_104238528" LINK="#ID_524518128" MODIFIED="1784423391250" TEXT="hat sich durch die Umstellung auf den atomic-Buffer-Pointer erledigt"/>
<node BACKGROUND_COLOR="#accdc3" COLOR="#010101" CREATED="1784226368203" ID="ID_1901417329" MODIFIED="1784226455132" STYLE="fork" TEXT="lasse mir von Claude ein Aufruf-Programm erzeugen">
...so daß es ohne Kontext sofort erkennbar ist
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1784297400412" ID="ID_1396606851" MODIFIED="1784297467112" TEXT="wirkt auf verschiedener Skala">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
wer hinten sitzt oder nur den Livestream sieht, bekommt ein stark reduziertes Bild mit schlechtem Kontrast
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1784297478369" ID="ID_1211159911" MODIFIED="1784297928984" TEXT="wirkt als »Hingucker«">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Idealerweise sollte man für diese Demo nichts weiter erläutern müssen — und es sollte auf einer anderen Ebene nochmal <i>eine Closure erzeugen. </i>
</p>
<p>
</p>
<p>
Es handelt sich um einen »Zaubertrick«, erfordert also implizites Framing; beim Vortrag 2025 hat das nicht funktioniert, was m.E. daran lag daß Benny an der Stelle immer so ungeschickt auf der festen Fenstergröße herumgeritten ist, und ich das nicht realisiert und rechtzeitig aufgegriffen habe
<node CREATED="1784297943166" ID="ID_488286955" MODIFIED="1784298188764" TEXT="eigenes Material verwenden">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Das halte ich auf verschiedenen Ebenen für sinnvoll. Eine ersichtlich <i>handgemachte</i>  Aufnahme ist »ein Video« im betonten Sinn, es paßt in meinen Rhythmus und Stil, und ich hab trivialerweise die Rechte am Bild (letzteres könnte problematisch sein bei einem öffentlich inszenierten Feuerwerk, d.h. die Aufnahme muß sofort ersichtlich einen dokumentarischen Charakter haben)
nach einem typischen Bouquet brechen an mehreren Stellen hell leuchtende orange-rote Kugeln auf, zuletzt sogar ganz vom Boden her; dabei wird die umgebende Szenerie am Olympiaberg einen Augenblick lang sichtbar. Diese Sequenz ist sehr kurz und kann gelooped werden
...das wäre dann aber eine längere Sequenz, beginnend mit den goldgelben Garben am untern Bildrand, und dann ein Bouquet aus großen Kugeln, die ihre Farbe von Blau über Rot entfalten. Klassisches Feuerwerk
das ist die charakteristischte und dichteste Sequenz in diesem Feuerwerk gewesen; ein seltener Fall in dem die Kombination »Rot-Grün« überzeugend eingesetzt ist und nicht bloß „bunt“ wirkt
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1784298592488" ID="ID_735279780" MODIFIED="1784298826077" TEXT="auf identifizierbare Personen achten">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Wegen dem Recht am Bild. Zwar ist die Rechtslage in Deutschland eindeutig (Panoramafreiheit sowie Geschehen der relativen Zeitgeschichte), jedoch könnte es Ärger geben, wenn jemand erkennbar prominent im Bild ist. Bei der bezeichneten Szene wäre das vor 1:15 der Fall, wo mehrere Leute direkt im Vordergrund Gruppen-Selfies machen; das könnte man m.E. unbesorgt einsetzen, wenn man die Gesamt-Szene zeigt, aber für einen kurzen Ausschnitt sollte ich besser vorsichtig sein. Daher wähle ich die nächste Sequenz, in der selbst in der Gruppe mit den Wunderkerzen keine Gesichter prominent erkennbar sind
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1784298493000" ID="ID_403555231" MODIFIED="1784298588968" TEXT="da ist mir eine zetlose Szene gelungen">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Die Kamera bewegt sich flüssig nach links durch eine gut gelaunte Menschenmenge, eine Gruppe mit Wunderkerzen, eine Steinskulptur, dahinter die Flußbrücke randvoll mit einer Menschenmasse und ein irres Feuerwerk darüber, schon halb im Pulverdampf
<node CREATED="1784302618850" ID="ID_72123433" MODIFIED="1785882623797" TEXT="Originalgröße: 1920 x 1080 ⟼ 5.9 MiB/frame RAW in RGB24"/>
--vout war notwendig, da der Default (VDPAU) mit anscheinend mit dem Pixelformat nicht zurechtkommt
</p>
</body>
</html></richcontent>
</node>
</node>
<node CREATED="1784304971029" ID="ID_1008974035" MODIFIED="1784305013409" TEXT="das Fenster ist deutlich kleiner als der Desktop und spielt flüssig ab (selbst von Magnitic-Disk)">
<node CREATED="1784228902224" ID="ID_1676148614" MODIFIED="1784228918826" TEXT="(intern faßt die Queue sogar 8 Einträge)">
<icon BUILTIN="idea"/>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1784228920986" ID="ID_815377389" MODIFIED="1784239445118" TEXT="der State-Marker wurde nicht weitergeschaltet">
<icon BUILTIN="broken-line"/>
</node>
</node>
</node>
</node>
<node COLOR="#435e98" CREATED="1784235804029" ID="ID_1424148212" MODIFIED="1784235907976" TEXT="Fenster zu klein">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1784235809692" ID="ID_1855255977" MODIFIED="1784235916712" TEXT="das window.set_size() wird ignoriert">
<icon BUILTIN="help"/>
</node>
<node CREATED="1784235819503" ID="ID_1683175695" LINK="https://stackoverflow.com/a/3582628/444796" MODIFIED="1784235920446" TEXT="Suche im Netz: set_resizable(false) zwingt auf den size-request zurück">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
das ist zwar nicht logisch, und auch nicht so dokumentiert, wurde aber von anderen Leuten bereits für GTK-3 beobachtet
</p>
</body>
</html></richcontent>
<icon BUILTIN="idea"/>
</node>
<node COLOR="#338800" CREATED="1784235892210" ID="ID_1028422738" MODIFIED="1784235902975" TEXT="Lösung: set_size_request() direkt im launchPlayer()">
<font color="#3a1f18" face="DejaVu Sans Mono" size="9pt">prevState </font><font color="#65533c" face="DejaVu Sans Mono" size="9pt">!=</font><font color="#3a1f18" face="DejaVu Sans Mono" size="9pt"> </font><font color="#9d724e" face="DejaVu Sans Mono" size="9pt"><i>SHOW</i></font>
</p>
</body>
</html></richcontent>
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
denn zur Anzeige wird der Slot auf <font color="#9d724e" face="DejaVu Sans Mono"><i>SHOW </i></font>gesetzt; zu prüfen ist also, daß dieser Zustand sich geändert hat.
<font color="#642880" face="DejaVu Sans Mono"><b>io_uring_submit</b></font><font color="#11123a" face="DejaVu Sans Mono">(</font><font color="#65533c" face="DejaVu Sans Mono">&</font><font color="#803435" face="DejaVu Sans Mono">uRing</font><font color="#11123a" face="DejaVu Sans Mono">)</font>  vergessen
<i>rein zufällig</i> funktioniert es aber trotzdem
</p>
</body>
</html></richcontent>
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
und zwar, wie Claudes ausführt, weil unter Linux die Lese / Schreib-Kernel-Calls einen Syncrhonisationspunkt darstellen. Da der Glib::Dispatcher über einen Pipe-Write/Read implementiert ist, führt bereits das Dispatch zu einer vollen Barrier, und daher ist es unter Linux ausgeschlossen, daß der GUI-Thread noch einen alten, verschleppten Cursor-State sieht.
</p>
<p>
</p>
<p>
Das gilt aber nicht allgemein und für andere Betriebssysteme und ist mithin nicht durch den C++-Standard gedeckt. Deshalb <i>beherrscht diese Lösung</i> nicht das Problem, und die dargestellte Begründung ist nicht stichhaltig.
</p>
</body>
</html></richcontent>
</node>
</node>
<node BACKGROUND_COLOR="#e2e0bd" COLOR="#435e98" CREATED="1784421763371" ID="ID_1187975455" MODIFIED="1784422182182" TEXT="mein Lösungsansatz beruht darauf daß, nur ein Zustand synchronisiert werden muß">
<icon BUILTIN="idea"/>
</node>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1784422189692" ID="ID_524518128" MODIFIED="1784422226476" TEXT="Atomic von der State-Engine trennen ⟹ stattdessen ein std::atomic<Buffer*>">
<node CREATED="1784422263938" ID="ID_1098483559" MODIFIED="1784422275268" TEXT="das führt insgesamt zu einer deutlichen Vereinfachung"/>
<node CREATED="1784422275837" ID="ID_328441268" MODIFIED="1784422293595" TEXT="ich schlage daraufhin vor: die drei Cursor auf zwei zu reduzieren"/>
<node BACKGROUND_COLOR="#accdc3" COLOR="#3f4015" CREATED="1784422309123" ID="ID_975047310" MODIFIED="1784422325191" STYLE="fork" TEXT="beauftrage Claude eine entspr. Lösung auszuarbeiten">
<node CREATED="1784422331646" ID="ID_691393919" MODIFIED="1784422358057" TEXT="Vorschlag: den nextShow-Cursor erst beim »reclaim« des Buffers inkrementieren"/>
<node CREATED="1784422475931" ID="ID_566892395" MODIFIED="1784422543922" TEXT="d.h. die Backpressure wird hier realisiert, indem erst danach der nächste Slot übprüft wird"/>
<node CREATED="1784422546982" ID="ID_230854798" MODIFIED="1784422774468" TEXT="diese Lösung gefällt mir: Logik hat jetzt weitgehend die Form einer State-Engine"/>
<node CREATED="1784422779995" ID="ID_1873586884" MODIFIED="1784422802079" TEXT="Claude schlägt vor, ein Switch-Case zu verwenden — auch das eine gute Idee"/>
weiterer <i>theoretischer</i> Race: die playing-Steuervariable
</p>
</body>
</html></richcontent>
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1784422887697" ID="ID_1880556582" MODIFIED="1784423000837" TEXT="extrem unwahrscheinlich zu triggern">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
dazu müßte das GUI sofort terminieren, während der Proactor-Thread grade erst startet ⟹ dann würde dort in der Loop ohne weiteren Check playing_ = true gesetzt, und damit ginge die Shutdown-Signalisierung verloren
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1784423002330" ID="ID_191859221" MODIFIED="1784423029018" TEXT="Resultat wäre, daß der Proactor-Thread dann hängt und irgenwann blockt"/>
<node CREATED="1784423036125" ID="ID_1995226372" MODIFIED="1784423050746" TEXT="und die Applikation würde im Shutdown verklemmen (im thread.join)"/>
<node COLOR="#338800" CREATED="1784423055506" ID="ID_616531880" MODIFIED="1784423089086" TEXT="Mein Vorschlag: der Player ist sowiso »RAII« ⟹ also gleich playing_ = true von Anfang an">
<u>Hinweis</u>: in Prod-Code sollte man jedes <font color="#5b3131" face="Monospaced">io_uring_get_sqe() != nullptr</font>  prüfen
</p>
</body>
</html></richcontent>
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Begründung: im Moment kann das nicht passieren, da die Queue ausreichend dimensioniert ist auf RING_SIZ + 1.  Sollte sich sowas aber unter Maintainnance ändern, dann könnte man in einen Segfault laufen! (Ja das sehe ich genauso und hätte es in Prod-Code tatsächlich in eine Hilfsfunktion gepackt; hier aber habe ich bewußt aus didaktischen Gründen darauf verzichtet)
außerdem habe ich vergessen: <font color="#642880" face="DejaVu Sans Mono" size="9pt"><b>io_uring_queue_exit</b></font><font color="#11123a" face="DejaVu Sans Mono" size="9pt">(</font><font color="#65533c" face="DejaVu Sans Mono" size="9pt">&</font><font color="#9c2303" face="DejaVu Sans Mono" size="9pt">uRing</font><font color="#11123a" face="DejaVu Sans Mono" size="9pt">)</font><font color="#65533c" face="DejaVu Sans Mono" size="9pt">;</font>
<node CREATED="1784423169337" ID="ID_1181187272" MODIFIED="1784423187567" TEXT="Beschreibung in ProcSpec.txt">
<icon BUILTIN="edit"/>
<node CREATED="1784423189039" ID="ID_221455189" MODIFIED="1784423195187" TEXT="entwerfe eine Gliederung"/>
<node BACKGROUND_COLOR="#accdc3" COLOR="#3f4015" CREATED="1784423195777" ID="ID_497657354" MODIFIED="1784423304160" STYLE="fork" TEXT="lasse Claude die Abschnitte ausfüllen">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
...da der Konversations-Status ein komplettes Bild der Steuerlogik enthält, bietet sich das gradezu an; stilistisch überarbeiten kann ich den Text später immer noch
...anders als bei dem Video-Output-Thema, bei dem wir uns die zentralen Element überhaupt erst aufschließen mußten, und dies nur mithilfe bestehender GPL-Codebasen geschafft haben. Diesmal ist die Situation ganz anders, das Thema ist ziemlich gut in Tutorials und Blogs aufbereitet. Viele haben zwar kein brauchbares Lizenz-Statement, aber andererseits ist die Aufgabe so einfach, daß ich nirgends Code abschreiben muß, den ich nicht auch genauso selber schreiben könnte.
es schaut ja eh keiner auf unseren Beispielcode. Da mach ich mir keine Illusionen. Der Code ist für "uns" selber später wichtig....
</li>
<li>
wer interessiert sich überhaupt noch für LIzenzen, die AI stiehlt ja sowiso alles, und Jedermann kann behaupten, er hätte seine Weisheit von einem LLM.
Der Vollständigkeit halber: es gibt den Unterschied zwischen negativer Freiheit und positiver Feiheit; letztere ist der Entschluß zu einer klar formulierten Vision. Die GPL formuliert hierzu die »vier Freiheiten«. Dahinter steht das Ideal des Gemeinwohls. Das muß leider verteidigt werden gegen Ausbeutung und Veruntreuung.
<node CREATED="1783787061169" ID="ID_1906878927" MODIFIED="1783787101544" TEXT="Der Code soll auf die Lumiera-Website. Eine Abweichende Lizenz schafft dort nur Komplikationen"/>
<node CREATED="1783787106667" ID="ID_1055216820" MODIFIED="1783787173608" TEXT="und dann ist da noch der EGL-Code aus dem letzen Jahr (den ich tatsächlich kopiere)">
<node CREATED="1785861111621" ID="ID_1704710749" MODIFIED="1785861189290" TEXT="habe meine eigenen Erfahrungswerte validieren lassen">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
alle meine eigenen Erfahrungen und Richtwerte konnten vollumfänglich bestätigt werden; manche Meßwerte kann ich nun besser einordnen, z.B. durch die Unterscheidung in hott-pressed und systemic-cost. Erheblich dazugelernt habe ich bezüglich <b>Futex</b>es
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1781522598218" FOLDED="true" ID="ID_1010572140" MODIFIED="1781532809159" TEXT="per rsync auf den PC und dort zusammenführen">
<icon BUILTIN="yes"/>
<node CREATED="1781522626485" ID="ID_1443600419" MODIFIED="1781522633859" TEXT="eigentlich die Debian-Version nehmen"/>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1781522634468" ID="ID_285777397" MODIFIED="1781532807736" TEXT="aber die Control-Files abgleichen">
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1781521250102" ID="ID_158010908" MODIFIED="1781651316654" TEXT="Will hat neue Version gemacht">
das Trac startet nicht auf dem Laptop. Habe keine Zeit mehr zur Untersuchung. Daher meine Idee: versuchen, das aktuelle Debian-Paket in einem Ubuntu-Image gebaut zu bekommen
<node CREATED="1781519661016" ID="ID_1699740765" MODIFIED="1781519726415" TEXT="für die Demo müssen es Presets aus der Yoshimi-Distribution sein">
getriggert wird es, wenn der vorherige Note-off nicht direkt mit dem nächsen Note-on aligned, aber sehr kurzzeitig davor endet. Bei mir ist das entstanden aus dem Time-Stretching der zunächst per Grid eingegebenen MIDI-Noten. Und weil Ardour immer noch nicht seine off-by-one-Probleme im Griff hat. Das müssen wir in Lumiera besser machen!!!
für mein Arrangement war da gar kein Platz, was mir aber auch recht war (das wäre anders gewesen, wenn wir einen richtigen Workshop mit ausreichend Zeit gehabt hätten)
<node CREATED="1781520253790" ID="ID_1682535861" MODIFIED="1781520269965" TEXT="Information und Kommunikation mit anderen Projekten schwieriger geworden"/>
<node CREATED="1781520302357" ID="ID_1034795521" MODIFIED="1781520309965" TEXT="wir als Community"/>
<node CREATED="1781520386588" ID="ID_1099579549" MODIFIED="1781520396069" TEXT="sollten mit dem Kult der »technischen Lösungen« brechen"/>
<node CREATED="1781520310503" ID="ID_71783091" MODIFIED="1781520322380" TEXT="müssen uns um unsere Commons kümmern"/>
<node CREATED="1781520398936" ID="ID_1240655542" MODIFIED="1781520408059" TEXT="warum AI nicht hilfreich ist">
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1781520411146" ID="ID_344431376" MODIFIED="1781520418626" TEXT="Vorsicht: hier beschränken">
<node BACKGROUND_COLOR="#c8c0b6" CREATED="1783358587740" ID="ID_620274200" MODIFIED="1783358625416" TEXT="was gut war: hab mich mit Will an einem Abend im Hotel zusammengesetzt">
...hab ich versucht, aber in ganz München nicht mehr bekommen. Lindberg hätte es gehabt, ist aber im Konkurs. Music-Shop hatte nichts, hat auch bei der Konkurrenz in Pasing angerufen. War dann ein nettes Gespräch mit einem andern alten Musik-Hacker :-)
<node CREATED="1781520987145" ID="ID_633169539" MODIFIED="1781520994141" TEXT="vermutlich in München bei der Rückkehr"/>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1781520917531" ID="ID_1132702356" MODIFIED="1783357228571" TEXT="unklar: gibt es in München etwas besonderes zu beachten?">
<icon BUILTIN="help"/>
<node CREATED="1783357231402" ID="ID_1132822714" MODIFIED="1783357251627" TEXT="Antwort: ein Flughafen ist eine Chaos-Maschine"/>
<node CREATED="1783357253967" ID="ID_1932895270" MODIFIED="1783357838600" TEXT="aber letztlich muß man immer nur den Wegweisern folgen">
In dem Fall bedeutet das konkret, daß man in München bereits durch eine Sonderkontroll-Zone gelotst wird, nachdem man duch den Security-Check durch ist. Auch der Security-Check ist schon auf einer anderen Ebene. D.h. man wird hier durch die Kanäle für echtes Ausland geschleust. Dann gibt es aber überall Abkürzungen, da Irland zwar kein Schengen-Staat ist, aber letztlich doch EU. Insgesamt wurde in München meine Identität 5 mal unabhängig gecheckt. Bei der Gepäckabgabe, am Security-Check, dann im Ausreisecheck mit automatischer Biometrie-Erfassung in einer Schleuse. Danach nochmal an einem Checkpoint durch die Polizei. Und am Gate ein weiteres Mal, durch das Lufthansa-Personal. Alles sehr freundlich, aber bestimmt.
</p>
<p>
</p>
<p>
Ganz anders in Dublin. Bei der Ankunft wird man vom Terminal direkt durch die Zollstation geleitet. Das ist derzeit eine Baustelle, funktioniert aber reibungslos (man merkt sofort den andern Stil der Leute dort, gegenüber Deutschland). Einmal die Kennkarte vorzeigen, die wird kurz auf einen Scanner gelegt, und das war's ("welcome in Ireland" und tatsächlich ein freundliches Lächeln). Beim Rückflug gab es gar keine spezielle Umleitung, sondern nur den üblichen ID-Check beim Boarding. Zurück in München wird man wieder durch eine Polizeistation geleitet, kann dort aber die fast-Lane für EU-Residents nehmen. Ein strenger säuerlicher Blick von einem Beamten, Kennkarte auf einen Scanner, und ein kurzes Nicken.
Andere Leute haben wesentlich mehr Gepäckvolumen als ich. Wenn man sich an die Regeln hält (Waffen, Werkzeuge, Elektronik), dann ist es auch heute noch so wie vor 20 Jahren. Eigentlich sogar einfacher, da die Scanner besser sind. Der security-Check in München hat sich mein USB-Inteface genau angeschaut, auch erkannt was es ist. Ansonsten alles andere gemäß Anzeige am Bildschirm durchgewunken. Man kann heutzutage auch alles in eine einzige Schale kippen. Was ich immer wieder vergesse: die Taschentücher raus aus den Hosentaschen, und auch die Medikamente aus der Brusttasche. Ist aber nur ein Schmunzeln wert. Ein Detail: ich hatte eine Tube Bepanthen in einer Klarsichttüte im Rucksack. Wurde angeschaut, war OK. Besser wäre es gewesen, sich eine Klarsichttüte mit Zip-Lock zu besorgen, dann könnte man auch ein Deo und eine Zahnbürste mit dabei haben (falls man von seinem Gepäck getrennt wird). Akkus müssen allesamt nicht nur im Handgepäck-Rucksack sein, sondern direkt am Körper/Handtasche. Da achtet man drauf (wußte ich vorher).
...man geht in so einen »convenience store« am Block gegenüber der Connolly Station. Das ist Bahnhofs-Gegend, aber immerhin nicht direkt im Bahnhof. Im Laden kommt so ein gestresster syrischer Ladenbesitzer (allerdings: in Irland ist Jedermann viel taktvoller als hier in Deutschland), macht ein Foto mit seinem Handy, und stellt das Gepäck dann auf ein Regal direkt hinter dem Tresen. Später, beim Abholen, erkennt er einen "you want to pick up your luggage?", wuchtet die zwei Sachen raus, und das wars dann. Wenn während der Zeit jemand in meinen Rucksack "geschaut" hätte, dann hätte ich eine Beschwerde machen müssen...
</p>
<p>
Weiß nicht, ob mir eine Halle mit Schließfächern dort wirklich sympatischer wäre. Naja, hab Connolly Station eigentlich als ungefährlich empfunden.
Die Info im Internet war falsch. Die Station ist nicht an George's Quay, sondern direkt gegenüber am (sehr bekannten) Zollhaus. Alles sehr relaxed, kurzer Blick auf das Handy, daß man ein Ticket hat, niemand schaut genau hin. Der erste Bus war zu voll. Ich stand mit 20 weiteren Leuten da. Ein Mitarbeiter des Busbetreibers ist dort vor Ort. 5 Minuten später kam der nächste Bus, der war halb leer.
Ist in Terminal-1 im obersten Stockwerk. Kurze Wartezeit in der Schlange. Alles in eine Schale, danach sortiert das System in "sofort OK" vs. "manuelle Nachkontrolle". Ich war in ersterer Kategorie.
daher das übliche Spiel, ob jemand noch sein Handgepeck aufgeben möchte. Da waren aber auch Leute mit Rollkoffern. Bei mir hat niemand gefragt, und letztlich hat der Platz im Flugzeug dann auch locker gereicht
hab dann bei Smith 2 Adapter gekauft, Stück 10€. Problem gelöst. Leap Visitor Card gabs da aber nur für 1 Tag (genauso wie's ChatGPT sagte). Bin dann weiter zu Terminal-2 gelaufen. War sehr gut, daß ich mir spät nachts noch Google-Maps angeschaut habe. Merke, das ist keine Paranoia, sondern eine sehr gute Gewohnhait von mir!!!
In Terminal-2 war "Spar" etwas versteckt, ist nämlich im oberen Stock, beim Eingang zum Abflug (während WL Smith in Terminal-1 unten bei der Ankunft ist, ganz links). Leap Visitor Card dort gekauft, dann einen neuen Bus gebucht
Definitiv so: man muß die Tickets online buchen. Das geht aber auch noch vor Ort (per WLan), wenige Minuten vor Abfahrt. Visa-Debitkarte von ING und Consors hat problemlos funktioniert. Das muß man aber im Griff haben (also kein Zeitdruck! ruhige Ecke suchen, eine App verwenden, von der man sicher ist, daß die Verifikation funktioniert, wie hier, die ING-App). Was ich nicht wußte: ich hätte mir gar nicht nochmal ein Ticket kaufen müssen, mein vorher gebuchtes Ticket für den Bus 30 minuten früher, den ich versäumt habe, wegen der Geschichte mit dem Netz-Adaptor, wäre informell akzeptiert worden, weil die Leute dort "common sense" haben.
Die Busfahrt dauert ca 40 Minuten. Davon gefühlt die Hälfte durch ein endloses Tunell unter der Stadt durch. Das letzte Stück im Stadtverkehr zieht sich endlos. George's Quay ist die erste Station in der Stadt, und die nächste zu Connolly Station. Tara Street Station wäre sogar direkt daneben, aber mein Zug fuhr von Connolly.
</p>
<p>
Der Bus fährt von dort weiter den Liffy-River entlang, insges. braucht er 40 Minuten, bis er auf der anderen (nördlichen) Seite, vor dem Zoll-Gebäude wieder ankommt. Die Pläne und Angaben auf der Website sind irreführend. Für den Rückflug sollte man nicht ab George's Quay buchen, sondern gegenüber. Spielt aber in der Praxis keine Rolle. Gegenüber, beim Zoll-Gebäude ist ein Mitarbeiter der Buslinie vor Ort. Fahrgäste werden einfach nach vorhandener Kapazität mitgenommen, da die Busse tatsächlich alle 10 Minuten fahren. Wäre ich, wie gebucht, an George's Quay eingestiegen, dann wäre ich 40 Minuten durch die Stadt gezockelt. Aber der Busfahrer drüben am George's Quay hat mir das gleich gesagt. Vorher hatte ich einen Passanten angesprochen, auch der war, wie typisch in Irland, nicht betont freundlich, aber offen und gesprächig. Er hat mir gleich gesagt, wie das hier läuft, und mir dann gleich erzählt, daß er einen Freund in Deuschland hat, der jetzt nach Finnland übersiedelt, usw... Ja so sind die drauf. Kann man sich in DE gar nicht vorstellen.
Den Umständen enstprechend ist das wohl die praktischste Lösung. Man installiert eine App, bucht und bezahlt sich das kurz vorher (bei mir: am Abend vorher). Dann geht man in den jeweilgen "convenience store".
</p>
<p>
Mir persönlich, als old-Timer wäre eine Halle mit Schließfächern am Bahnhof viel sympatischer. Aber Bahnhöfe sind auch nicht mehr das, was sie mal waren. Wobei Irland hier einen sehr guten Eindruck hinterläßt. Aber auch das mit dem lokalen Shop ist letztlich OK, da es in Irland der normale Stil ist. In Deutschland sind solche Shops praktisch immer "zwielichtig", in Irland nicht. Außerdem hat man ja den Storage-Betreiber mit der App, und ein Foto vom Gepäck wird vorher auch gemacht, das gibt eine gewisse Sicherheit. Wobei mir klar ist, daß man im Problemfall erst mal selber sich um eine Beschwerde kümmern müßte.
...aber, realistisch geshen, ist das für mich vorbei. Es ist besser, wenn ich nichts esse, und es ist sicherlich kein Genuß mehr, mit anderen Leuten zum Essen zu gehen, sondern ein ziemlicher Streßfaktor. Die ersten beiden Tage ging's noch relativ glatt. Und ich war froh, mich an Will dranhängen zu können, der die Gepflogenheiten besser versteht.
...und das hab ich genossen. Jetzt weiß ich, was "black pudding" ist.
</p>
<p>
An den letzten Tagen war dieses Frühstück praktisch das einzige, was ich den ganzen Tag gegessen habe, und das war so die beste Lösung. Im Grunde ähnlich wie in Lyon, und auch dort hat sich das bewährt (auch wenn ich immer noch die andere Vorstellung im Kopf habe, daß man auf einer Reise irgendwo genußvoll und entspannt zum Essen geht, mit Leuten, bei denen man sich wohlfühlt)
Das ist eine Touristen-Attraktion. War mir vorher klar. Ist aber leider auch wirklich so. Ich war praktisch die ganze Zeit nur mit meinem eigenen Hass auf diesen leeren Betrieb beschäftigt.
</p>
<p>
Warum ich aber dann doch nach Howt gefahren bin, war der Klippen-Trail, den ich auf der Karte gesehen hatte. Ich bin die zweitlängste Strecke gelaufen, 12km, rote Markierung. Damit war ich nach den ersten 45 Minuten raus aus dem Touristen-Strom. Außerdem war ich schon wohlweislich erst am späten Nachmittag, um 17:00 angekommen. Es war Sonnwend, also Sonnenuntergang kurz vor 22:00 Irischer Sommerzeit. Tatsächlich bin ich sogar früher wieder heim, um 21:00. Den schmalen Pfad über dieses eigenartige Hochland werde ich in Erinnerung behalten. Und die Möven. Ansonsten ist es dort laut, denn es liegt in der Einflugschneise vom Flughafen. Und eine Techno-Party war auch noch, vermutlich wegen Sonnwend.
Hab die Wellenlänge dieser Stadt nicht wirklich gefunden.
</p>
<p>
Hatte dafür aber auch gar keine Zeit, und keinen Grund.
</p>
<p>
Was ich gesehen habe, war eine Mitte, die keine ist. Ein Hafen, der nicht mehr zugänglich ist, sondern ein Industriegebiet. Massiver Autoverkehr. Keine U-Bahn. Enge Straßen, durch die sich auch noch diese Stockbusse durchzwängen. Massen an Touristen, für die kein Raum ist. Und massives Elend überall. Verfallende Altbauten, und moderne Architektur, die wie ein Raumschiff eingepflanzt ist, und um sich herum keinen Stadtraum schafft.
Es war der letzte Slot im Programm, und wir haben es geschafft, daß es bei uns »Musik« gab (keine "Avant-Garde" und keine Tech-Demo). Die allgemeine Stimmung war sehr erfreulich. So einige Zuhörer waren wieder sichtlich beeindruckt von den klanglichen Möglichkeiten. Einige kamen nachher noch, und haben auf dem Keyboard gespielt.
Ich hatte die ganzen Abende vorher, im Hotell geübt, und wußte schon jeden Punkt auswendig. Das hat sich bewährt. Thematisch bin ich in dieser Vorbereitung, während der Konferenz etwas »zurückgerudert«. Auch das war angemessen. Ich hatte das Gefühl, daß niemand im Publikum verärgert war, ich aber auch nichts wirklich Erhellendes gesagt habe. Was ich aber im Rückblick als gut empfinde, denn ich hatte nicht die Position für etwas Weitergehendes.
</p>
<p>
Um es nochmal zu rekapitulieren, <i>ich</i> wollte diesen Themenblock nicht, aber Will war es wichtig. Ich selber empfinde die Schwierigkeiten, die wir letztes Jahr hatten, als normal und keiner Rede wert. Was <i>mich dabei</i> nur ärgert ist, daß <i>ausgerechnet ich diese Drecksarbeit </i>andauernd machen muß. Aber letztlich gibt es nur mich und Will, Kristian ist berufstätig und hat Familie, und nur sporadisch mal Zeit, Jesper will sich raushalten (und nicht wieder Project-Lead werden). Und wenn man Will persönlich trifft, ist völlig klar, wer er ist, was sein Horizont ist, und was er nicht machen kann. Insofern bleibe ich einfach übrig, und wenn mir an Yoshimi weiterhin was liegt, werde ich diese Arbeit machen müssen, oder das Projekt geht vor die Säue. All das hab ich aber nicht gesagt, und ich habe es inhaltlich gut hinbekommen, stattdessen etwas Generisches zu sagen, das doch immerhin den Sachverhalt bezeichnet. Hab mich ziemlich genau an die hier skizzierte Gliederung gehalten. Weiterungen zu AI habe ich nicht ausgeführt, obwohl <i>das</i> das Einzige gewesen wäre, was mich daran interessiert hätte. Es ist aber auch gut so, das habe ich an der Diskussion in den vorangegangenen Tagen gemerkt.
</p>
<p>
Vom Sprechen her war es so la-la. Ich glaube, ich hab nicht mehr so viel gestottert. Daß meine Aussprache grauenhaft deutsch klingt, habe ich inzwischen einfach akzeptiert, und ignoriere es (was mir sehr hilft, mich auf die Wortwahl zu konzentrieren). Duch die Vorbereitung mußte ich nicht "nach Worten suchen". Ansonsten war mein Vortrag nach meinen eigenen Maßstäben ziemlich mittelmäßig. Es gab auch keinen Spannungsbogen (und ich hatte eigentlich nach meinem eigenen Empfinden nichts zu sagen).
</p>
<p>
Am Ende habe ich meinen Block nicht ganz zuende formuliert, da mir Will mit einem Einwurf eine Brücke zurück gebaut hat (die viel geschickter war, als das, was ich grade sagen wollte, daher habe ich sie sofort genommen)
Damit hat sich mein ursprüngliches Bauchgefühl bestätigt. Will kann nicht einmal 45 Minuten füllen, er würde nur Demo nach Demo machen. Durch die Gliederung, die wir uns vorher gmacht haben, waren wir aber eigentlich gut sortiert. Insofern bestätigt sich, warum Will mich gebeten hat, mitzumachen. Er hat nämlich jeden meiner Vorschläge gerne aufgenommen; die Zusammenarbeit war sehr konstruktv, vor allem, als wir uns persönlich abstimmen konnten, im Hotel in Maynooth.
</p>
<p>
</p>
<p>
Am Ende vom Zeit-Slot blieb etwas Luft, und so hat Will noch einen weiteren Track von sich gespielt, der aber nur noch wenig zum Thema beigetragen hat. Ich hab ihm dann signalisiert, daß es reicht, und er hat das verstanden. Da waren wir in Minute 40. Insofern konnten wir sogar noch etwas Diskussion machen. Da kam dann eine Frage zu meinem Themenblock und zur Dokumentation. Im Rückblick ärgert es mich, daß ich nicht im Stande war, das besser aufzugreifen (da hätte ich nämlich nochmal eine Brücke zur A.I. schlagen können). Aber was ich gesagt habe, war OK, und mehr wollte der Fragende ja eigentlich nicht. Ansonsten kamen noch zwei technische Detail- / Verständnisfragen, die wieder zeigen, daß viele Zuhörer nur mit CSound oder PureData experimentieren, aber nicht mit so einem typsichen "Synthie" vertraut sind (denn in dieser Hinsicht ist Zyn/Yoshimi überhaupt nicht überraschend)
<node CREATED="1783360099299" ID="ID_1453107748" LINK="https://lac26.mucs.club/gallery/" MODIFIED="1783360117914" TEXT="Hier sind Photos von der Konferenz">
Für mich war dazu essentiell, daß ich nicht bloß Zuhörer war, sondern ein Projekt vertreten habe. Bezüglich »Networking« hatte ich keine Ambitionen, hab aber auch nichts versäumt; ich habe zwei oder drei Leuten ausführlich von Lumiera erzählen können, und die schienen alle durchaus im Stande, die Tragweite zu erkennen. Allerdings war niemand da, der mich jetzt direkt etwas voranbringen würde. Hätte ich aber auch nicht erwartet, ich kenne diese Community. Möglich wäre es, aber die Community wird kleiner und kleiner, und wer noch da ist, sitzt in seiner Ecke. Ich hätte mich gefreut, etwas mehr mit Robin reden zu können. Das hat sich aber nicht ergeben, und ich habe keinerlei Interesse, da "zu drücken". Robin zeigt seinerseits kein Interesse, und fühlt sich mir gegenüber etwas unwohl, obwohl er oberflächlich immer den "alten Bekannten" begrüßt. Bemerkenswerterweise hatte Robin alles vergessen, was ich ihm in Lyon von Lumiera erzählt hatte. Er war erstaunt, zu hören, daß ich immer noch mit Lumiera weitermache. Ich komme mit ihm nicht auf die Ebene, die interessant wäre (würde mir davon aber auch nichts erwarten, da ich inzwischen ziemlich genau vestehe, wo er steht). Drei bis vier andere Leute, die ich in Lyon kennengelernt hatte, und mit denen ich gerne wieder anknüpfen wollte, waren nicht da. Insgesamt war sonst kaum jemand da, mit dem mich persönlich ein Gespräch interessiert hätte. Ich bin aber weiterhin vorsichtig, mich nicht zu aggressiv zu positionieren. Aktuell geht es mir nur darum, präsent zu sein (ich könnte auch in keine Art von Kollaboration einsteigen derzeit, weil ich meine Kräfte zusammenhalten muß, insofern bin ich froh, daß sich auch dazu keine Gelegenheit ergab).
</p>
<p>
</p>
<p>
Ohne diese Aufgabe, ein Projekt zu vertreten (und Networking zu machen), würde mich die LAC (schon seit langer Zeit) nicht hinter dem Ofen vorlocken. Die "Konzerte" sind immer gleich. Da genügt ein Termin, weil es schon schön ist, ein gut aufgebautes Ambisonics zu hören. Das zweite und drite Konzert habe ich "geschwenzt". Das war ein Glück, denn anstelle des zweiten Konzerts hatte ich Zeit, in dieser alten Universitäts-Anlage zu sein und nichts zu tun, und die Stille und Ruhe des Ortes aufzunehmen. Das war auch der Abend mit dem Gewitter und dem Regenbogen.
</p>
<p>
Insgesamt war Maynooth viel kleiner und bescheidener aufgebaut, als Lyon, was aber einfach an den dahinter stehenden Organisationen lag. Das dritte Konzert, in Dublin, wäre ein allgemeines Experimental-Konzert für elektronische Musik gewesen. Von mir aus hätte mich das nur gelangweilt, und da Will auch kein Interesse hatte, war die Konferenz sehr schnell beendet. So hatte ich Zeit für eine Wanderung zum Carton Demense, und hab so tatsächlich ein Stück von Irland gesehen.
</p>
<p>
Hinzu kommt, daß ich doch bei einer solchen Gelegenheit immer wieder merke, wie sehr ich gesundheitlich angeschlagen bin. Am vierten Tag, an dem ich nach Dublin wollte, ging es mir ziemlich dreckig. Später, gegen Abend zu, hat es sich etwas mehr eingependelt, was aber auch damit zusammenhängt, daß ich da in Howt im Freien war, und mehrere Stunden einfach allein laufen konnte.
</p>
<p>
Insgesamt war es ein »Nicht-Urlaub« von einer Art, die ich noch gut ertragen kann. Dieses kleine Universitäts-Städtchen mutet an wie aus einer andern Zeit, da war die »Quality without a Name«, von der Christopher Alexander spricht. Und zum Glück muß ich dort nicht leben. Das Hotel war mindestens eine Kategorie zu edel für mich, aber ich konnte gut unerkannt bleiben, die Leute in Irland sind wirklich auf eine unaufdringliche Art zugewandt, und ich hab mich sehr wohl gefühlt. Vom Hotel aus war alles fußläufig zu erreichen, die wüste Welt der Automobile war zwar zu hören, aber nur auf der anderen Seite. Und zum Glück gibt es praktisch nichts "Sehenswertes" im Maynooth.
</p>
<p>
</p>
<p>
Wenn ich nur bedenke, was Daniela garde im Moment mit ihrer LItauen-Bildungsreise alles um die Ohren geworfen bekommt, dann graut mir, und ich fühle mich verloren. Was für ein lehrer und eitler Betrieb das alles.
<node BACKGROUND_COLOR="#accdc3" COLOR="#3f4015" CREATED="1779554095269" ID="ID_1290433500" MODIFIED="1779554118621" STYLE="fork" TEXT="habe mir noch einige Vorschläge von ChatGPT geben lassen">
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1779504789243" ID="ID_649621958" MODIFIED="1783787704354" TEXT="Klären: kann man mit IO_URING gezielt bestimmte Bereiche eines Files lesen?">