Prototype: code improvements

- rename the states to better reflect their purpose
 - introduce getters for in BufferDispatcher
This commit is contained in:
Fischlurch 2026-07-16 19:31:34 +02:00
parent 0cb388d4a7
commit c9f9fec117
3 changed files with 176 additions and 152 deletions

View file

@ -369,16 +369,13 @@
</node> </node>
<node CREATED="1784162963010" ID="ID_1477358179" MODIFIED="1784163021269" TEXT="oder direkt die negierte ERRNO"> <node CREATED="1784162963010" ID="ID_1477358179" MODIFIED="1784163021269" TEXT="oder direkt die negierte ERRNO">
<richcontent TYPE="NOTE"><html> <richcontent TYPE="NOTE"><html>
<head> <head/>
</head>
<body> <body>
<p> <p>
IO_URING kann errno nicht sinnvoll direkt verwenden (errno ist eine globale variable) IO_URING kann errno nicht sinnvoll direkt verwenden (errno ist eine globale variable)
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
</node> </node>
</node> </node>
</node> </node>
@ -843,11 +840,12 @@
</node> </node>
<node CREATED="1779504863066" ID="ID_986008832" MODIFIED="1779504921775" TEXT="jeden Frame in den Output-Code aus dem Video-output-Vortrag schicken"/> <node CREATED="1779504863066" ID="ID_986008832" MODIFIED="1779504921775" TEXT="jeden Frame in den Output-Code aus dem Video-output-Vortrag schicken"/>
<node CREATED="1783642371760" ID="ID_622863035" MODIFIED="1783642377238" TEXT="Konstruktions-Schema"> <node CREATED="1783642371760" ID="ID_622863035" MODIFIED="1783642377238" TEXT="Konstruktions-Schema">
<node CREATED="1783642378650" ID="ID_460419" MODIFIED="1783642391427" TEXT="naheliegend: einen Proactor zeigen"> <node CREATED="1783642378650" ID="ID_460419" MODIFIED="1784222786307" TEXT="naheliegend: einen Proactor zeigen">
<node CREATED="1783642938966" ID="ID_1117409154" MODIFIED="1783642955536" TEXT="m&#xe4;&#xdf;ig sinnvoll"/> <node CREATED="1783642938966" ID="ID_1117409154" MODIFIED="1783642955536" TEXT="m&#xe4;&#xdf;ig sinnvoll"/>
<node CREATED="1783642956739" ID="ID_141690825" MODIFIED="1783642968326" TEXT="hier nur ein Consumer"/> <node CREATED="1783642956739" ID="ID_141690825" MODIFIED="1783642968326" TEXT="hier nur ein Consumer"/>
<node CREATED="1784222792149" ID="ID_1259331721" MODIFIED="1784222808639" TEXT="ist aber die Standard-L&#xf6;sung (push)"/>
</node> </node>
<node COLOR="#5b280f" CREATED="1783642985618" ID="ID_169416260" MODIFIED="1784052474215" TEXT="oder einen pull-Worker"> <node COLOR="#5b280f" CREATED="1783642985618" FOLDED="true" ID="ID_169416260" MODIFIED="1784052474215" TEXT="oder einen pull-Worker">
<icon BUILTIN="button_cancel"/> <icon BUILTIN="button_cancel"/>
<node CREATED="1783642995707" ID="ID_216666777" MODIFIED="1783642999794" TEXT="das w&#xe4;re n&#xe4;her an Lumiera"/> <node CREATED="1783642995707" ID="ID_216666777" MODIFIED="1783642999794" TEXT="das w&#xe4;re n&#xe4;her an Lumiera"/>
<node CREATED="1783643000727" ID="ID_737342556" MODIFIED="1783643655114" TEXT="der w&#xfc;rde jeweils nur die Queue ausr&#xe4;umen"/> <node CREATED="1783643000727" ID="ID_737342556" MODIFIED="1783643655114" TEXT="der w&#xfc;rde jeweils nur die Queue ausr&#xe4;umen"/>
@ -894,8 +892,8 @@
</node> </node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1783644313430" ID="ID_170028474" MODIFIED="1783788829437" TEXT="Prototyp entwickeln"> <node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1783644313430" ID="ID_170028474" MODIFIED="1783788829437" TEXT="Prototyp entwickeln">
<icon BUILTIN="pencil"/> <icon BUILTIN="pencil"/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1783644336145" ID="ID_413309976" MODIFIED="1783788834125" TEXT="Skelett"> <node COLOR="#338800" CREATED="1783644336145" ID="ID_413309976" MODIFIED="1784222754616" TEXT="Skelett">
<icon BUILTIN="pencil"/> <icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1783788677873" ID="ID_551733396" LINK="#ID_517750346" MODIFIED="1783788805152" TEXT="Lizenz: GPL v2+"/> <node COLOR="#338800" CREATED="1783788677873" ID="ID_551733396" LINK="#ID_517750346" MODIFIED="1783788805152" TEXT="Lizenz: GPL v2+"/>
<node COLOR="#338800" CREATED="1783644339455" ID="ID_932453573" MODIFIED="1783788820590" TEXT="CMake"> <node COLOR="#338800" CREATED="1783644339455" ID="ID_932453573" MODIFIED="1783788820590" TEXT="CMake">
<icon BUILTIN="button_ok"/> <icon BUILTIN="button_ok"/>
@ -944,13 +942,24 @@
<node COLOR="#338800" CREATED="1783644357376" ID="ID_1687423764" MODIFIED="1784142889926" TEXT="ein Proactor-Thread"> <node COLOR="#338800" CREATED="1783644357376" ID="ID_1687423764" MODIFIED="1784142889926" TEXT="ein Proactor-Thread">
<icon BUILTIN="button_ok"/> <icon BUILTIN="button_ok"/>
</node> </node>
<node CREATED="1783644382004" ID="ID_222096554" MODIFIED="1783644392847" TEXT="Handler"> <node COLOR="#338800" CREATED="1783644382004" ID="ID_222096554" MODIFIED="1784222739934" TEXT="Handler">
<node CREATED="1783644394013" ID="ID_599467746" MODIFIED="1783644398783" TEXT="Completion-Handler"/> <icon BUILTIN="button_ok"/>
<node CREATED="1783644399671" ID="ID_1684157516" MODIFIED="1783644406037" TEXT="Submission-Handler"/> <node COLOR="#338800" CREATED="1783644394013" ID="ID_599467746" MODIFIED="1784222741419" TEXT="Completion-Handler">
<node CREATED="1783644407569" ID="ID_69520880" MODIFIED="1783644412668" TEXT="Display-Handler"/> <icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1783644399671" ID="ID_1684157516" MODIFIED="1784222743125" TEXT="Submission-Handler">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1783644407569" ID="ID_69520880" MODIFIED="1784222744755" TEXT="Display-Handler">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1784222746115" ID="ID_1070022489" MODIFIED="1784222750547" TEXT="Shutdown-Handler">
<icon BUILTIN="button_ok"/>
</node> </node>
</node> </node>
<node CREATED="1783900894906" ID="ID_1398236830" MODIFIED="1783900901714" TEXT="Design-Fragen"> </node>
<node COLOR="#234872" CREATED="1783900894906" ID="ID_1398236830" MODIFIED="1784222832373" TEXT="Design-Fragen">
<icon BUILTIN="yes"/>
<node BACKGROUND_COLOR="#accdc3" COLOR="#3f4015" CREATED="1783900916807" ID="ID_1965380217" LINK="https://claude.ai/share/2d09d5e6-1a47-45e9-b05b-500550fb0977" MODIFIED="1783964756096" STYLE="fork" TEXT="Design / Technologie-Dialog mit Claude"> <node BACKGROUND_COLOR="#accdc3" COLOR="#3f4015" CREATED="1783900916807" ID="ID_1965380217" LINK="https://claude.ai/share/2d09d5e6-1a47-45e9-b05b-500550fb0977" MODIFIED="1783964756096" STYLE="fork" TEXT="Design / Technologie-Dialog mit Claude">
<edge COLOR="#808080" STYLE="bezier" WIDTH="thin"/> <edge COLOR="#808080" STYLE="bezier" WIDTH="thin"/>
<icon BUILTIN="wizard"/> <icon BUILTIN="wizard"/>
@ -1411,9 +1420,7 @@
</node> </node>
<node BACKGROUND_COLOR="#accdc3" COLOR="#3f4015" CREATED="1783956594083" ID="ID_1956714359" MODIFIED="1784136509799" STYLE="fork" TEXT="onTick + follow-up"> <node BACKGROUND_COLOR="#accdc3" COLOR="#3f4015" CREATED="1783956594083" ID="ID_1956714359" MODIFIED="1784136509799" STYLE="fork" TEXT="onTick + follow-up">
<richcontent TYPE="NOTE"><html> <richcontent TYPE="NOTE"><html>
<head> <head/>
</head>
<body> <body>
<pre>void onTick() <pre>void onTick()
&#160;&#160;{ &#160;&#160;{
@ -1434,8 +1441,7 @@
</pre> </pre>
</body> </body>
</html> </html></richcontent>
</richcontent>
<edge COLOR="#808080" STYLE="bezier" WIDTH="thin"/> <edge COLOR="#808080" STYLE="bezier" WIDTH="thin"/>
<icon BUILTIN="wizard"/> <icon BUILTIN="wizard"/>
<icon BUILTIN="edit"/> <icon BUILTIN="edit"/>
@ -1863,7 +1869,8 @@
</node> </node>
</node> </node>
</node> </node>
<node CREATED="1783984352027" ID="ID_1602724940" MODIFIED="1783984359484" TEXT="Aufbau der Application-Shell"> <node BACKGROUND_COLOR="#b2e9d4" COLOR="#014e21" CREATED="1783984352027" ID="ID_1602724940" MODIFIED="1784222687829" TEXT="Aufbau der Application-Shell">
<icon BUILTIN="yes"/>
<node CREATED="1783984371031" ID="ID_1219649133" MODIFIED="1783984401222" TEXT="das Grundschema von letztem Jahr war n&#xfc;tzlich"> <node CREATED="1783984371031" ID="ID_1219649133" MODIFIED="1783984401222" TEXT="das Grundschema von letztem Jahr war n&#xfc;tzlich">
<node CREATED="1783984407459" ID="ID_321798557" MODIFIED="1783984427656" TEXT="&#x201e;mu&#xdf; den GTK-Code gar nicht anschauen&#x201c;"/> <node CREATED="1783984407459" ID="ID_321798557" MODIFIED="1783984427656" TEXT="&#x201e;mu&#xdf; den GTK-Code gar nicht anschauen&#x201c;"/>
<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 BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1783985102373" ID="ID_734300736" MODIFIED="1784076612700" TEXT="Aber: die Ablaufsteuerung liegt jetzt nicht mehr (komplett) in GTK">
@ -1951,7 +1958,9 @@
<node CREATED="1783986866318" ID="ID_623423104" MODIFIED="1783986874503" TEXT="alles per Konstruktor-Verdrahtung"/> <node CREATED="1783986866318" ID="ID_623423104" MODIFIED="1783986874503" TEXT="alles per Konstruktor-Verdrahtung"/>
</node> </node>
</node> </node>
<node CREATED="1784076499094" ID="ID_1786219220" MODIFIED="1784076516947" TEXT="Player per Konstruktur-Initialisierung"> <node COLOR="#1f267f" CREATED="1784076499094" ID="ID_1786219220" MODIFIED="1784222712766" TEXT="Player per Konstruktur-Initialisierung">
<font BOLD="true" NAME="SansSerif" SIZE="12"/>
<icon BUILTIN="back"/>
<node CREATED="1784076561463" ID="ID_1248489844" MODIFIED="1784076582686" TEXT="l&#xe4;uft im GUI-Thread"> <node CREATED="1784076561463" ID="ID_1248489844" MODIFIED="1784076582686" TEXT="l&#xe4;uft im GUI-Thread">
<icon BUILTIN="idea"/> <icon BUILTIN="idea"/>
</node> </node>
@ -1962,6 +1971,7 @@
<node CREATED="1784076675289" ID="ID_1648662317" MODIFIED="1784076685507" TEXT="unmittelbar hier den Thread starten"/> <node CREATED="1784076675289" ID="ID_1648662317" MODIFIED="1784076685507" TEXT="unmittelbar hier den Thread starten"/>
</node> </node>
</node> </node>
</node>
<node CREATED="1783644425567" ID="ID_238189215" MODIFIED="1783644429274" TEXT="Flow-Steuerung"> <node CREATED="1783644425567" ID="ID_238189215" MODIFIED="1783644429274" TEXT="Flow-Steuerung">
<node CREATED="1784052955974" ID="ID_1491751742" MODIFIED="1784052978769" TEXT="da nun Proactor &#x27f9; getrieben vom Timer-Tick"> <node CREATED="1784052955974" ID="ID_1491751742" MODIFIED="1784052978769" TEXT="da nun Proactor &#x27f9; getrieben vom Timer-Tick">
<icon BUILTIN="idea"/> <icon BUILTIN="idea"/>
@ -1975,9 +1985,7 @@
<icon BUILTIN="idea"/> <icon BUILTIN="idea"/>
<node BACKGROUND_COLOR="#fefc4e" COLOR="#351d75" CREATED="1784076979882" ID="ID_1843330900" MODIFIED="1784078228911" TEXT="Bemerkenswert: das hat sich durch die Konversation so ergeben"> <node BACKGROUND_COLOR="#fefc4e" COLOR="#351d75" CREATED="1784076979882" ID="ID_1843330900" MODIFIED="1784078228911" TEXT="Bemerkenswert: das hat sich durch die Konversation so ergeben">
<richcontent TYPE="NOTE"><html> <richcontent TYPE="NOTE"><html>
<head> <head/>
</head>
<body> <body>
<p> <p>
...es war nicht so, da&#223; Claude diese &#8222;Idee gehabt&#8220; h&#228;tte &#8212; denn ich hatte die Konversation ja so gef&#252;hrt, da&#223; Claude mir meine Konzept-Ans&#228;tze validiert und verfeinert. Dann habe ich das Prinzip formuliert, da&#223; f&#252;r Async-IO irgendwo eine State-Machine sein mu&#223;. Claude hat das aufgegriffen, validiert und versch&#228;rft; und damit war offensichtlich geworden, da&#223; man diese State-Flag als Atomic auslegen kann. Das habe ich in dem Moment genauso &#187;offensichtlich&#171; gesehen, und Claude hat es ebenso formuliert. ...es war nicht so, da&#223; Claude diese &#8222;Idee gehabt&#8220; h&#228;tte &#8212; denn ich hatte die Konversation ja so gef&#252;hrt, da&#223; Claude mir meine Konzept-Ans&#228;tze validiert und verfeinert. Dann habe ich das Prinzip formuliert, da&#223; f&#252;r Async-IO irgendwo eine State-Machine sein mu&#223;. Claude hat das aufgegriffen, validiert und versch&#228;rft; und damit war offensichtlich geworden, da&#223; man diese State-Flag als Atomic auslegen kann. Das habe ich in dem Moment genauso &#187;offensichtlich&#171; gesehen, und Claude hat es ebenso formuliert.
@ -1997,8 +2005,7 @@
&#10233; das wirft ein Licht darauf, wie dieses <i>scheinbar intelligente &#187;Generieren&#171; funktioniert, </i>auf Basis einer industriellen Daten-Technik, die Plausibilit&#228;ten integriert und interpoliert. &#10233; das wirft ein Licht darauf, wie dieses <i>scheinbar intelligente &#187;Generieren&#171; funktioniert, </i>auf Basis einer industriellen Daten-Technik, die Plausibilit&#228;ten integriert und interpoliert.
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
<font BOLD="true" NAME="SansSerif" SIZE="12"/> <font BOLD="true" NAME="SansSerif" SIZE="12"/>
<icon BUILTIN="back"/> <icon BUILTIN="back"/>
</node> </node>
@ -2006,27 +2013,24 @@
<font BOLD="true" NAME="SansSerif" SIZE="12"/> <font BOLD="true" NAME="SansSerif" SIZE="12"/>
<icon BUILTIN="info"/> <icon BUILTIN="info"/>
<node CREATED="1784078717834" ID="ID_17978925" MODIFIED="1784078954065" TEXT="IO beauftragen: FREE &#x27f6; READ"/> <node CREATED="1784078717834" ID="ID_17978925" MODIFIED="1784078954065" TEXT="IO beauftragen: FREE &#x27f6; READ"/>
<node CREATED="1784078958419" ID="ID_1531715805" MODIFIED="1784078974343" TEXT="&#xdc;bergabe an Display: READ &#x27f6; SHOW"/> <node CREATED="1784078958419" ID="ID_1531715805" MODIFIED="1784221555857" TEXT="&#xdc;bergabe an Display: READ &#x27f6; FEED"/>
<node CREATED="1784165852364" ID="ID_721661485" MODIFIED="1784167391018" TEXT="Warten auf Display: SHOW &#x27f6; WAIT"> <node CREATED="1784165852364" ID="ID_721661485" MODIFIED="1784221545799" TEXT="Warten auf Display: FEED &#x27f6; SHOW">
<linktarget COLOR="#6574c5" DESTINATION="ID_721661485" ENDARROW="Default" ENDINCLINATION="925;77;" ID="Arrow_ID_86014624" SOURCE="ID_312946304" STARTARROW="None" STARTINCLINATION="397;-23;"/> <linktarget COLOR="#6574c5" DESTINATION="ID_721661485" ENDARROW="Default" ENDINCLINATION="925;77;" ID="Arrow_ID_86014624" SOURCE="ID_312946304" STARTARROW="None" STARTINCLINATION="397;-23;"/>
</node> </node>
<node CREATED="1784078981634" ID="ID_1578413583" MODIFIED="1784167275599" TEXT="Frame-Flip: WAOT &#x27f6; FREE"/> <node CREATED="1784078981634" ID="ID_1578413583" MODIFIED="1784221551696" TEXT="Frame-Flip: SHOW &#x27f6; FREE"/>
<node CREATED="1784165852364" ID="ID_849967229" MODIFIED="1784167346009" TEXT="Abbrunch/End-of-File: markiert durch STOP"> <node CREATED="1784165852364" ID="ID_849967229" MODIFIED="1784167346009" TEXT="Abbrunch/End-of-File: markiert durch STOP">
<linktarget COLOR="#6574c5" DESTINATION="ID_849967229" ENDARROW="Default" ENDINCLINATION="755;51;" ID="Arrow_ID_1693130420" SOURCE="ID_948621808" STARTARROW="None" STARTINCLINATION="411;-22;"/> <linktarget COLOR="#6574c5" DESTINATION="ID_849967229" ENDARROW="Default" ENDINCLINATION="755;51;" ID="Arrow_ID_1693130420" SOURCE="ID_948621808" STARTARROW="None" STARTINCLINATION="411;-22;"/>
</node> </node>
</node> </node>
<node CREATED="1784078466234" ID="ID_424139171" MODIFIED="1784078496653"> <node CREATED="1784078466234" ID="ID_424139171" MODIFIED="1784078496653">
<richcontent TYPE="NODE"><html> <richcontent TYPE="NODE"><html>
<head> <head/>
</head>
<body> <body>
<p> <p>
hier mu&#223; auch die <b>Backpressure</b>&#160;beachtet und realisiert werden hier mu&#223; auch die <b>Backpressure</b>&#160;beachtet und realisiert werden
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
<node CREATED="1784078502730" ID="ID_846472947" MODIFIED="1784078534574" TEXT="darf nur weitergehen, nachdem der vorherige Frame aufgegriffen wurde"/> <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 CREATED="1784078681486" ID="ID_1106864388" MODIFIED="1784078714572" TEXT="und darf nur neue IO beauftragen wenn der Zielpuffer vom Consumer freigegeben werden"/>
</node> </node>
@ -2035,102 +2039,82 @@
<node CREATED="1784079589221" ID="ID_1308906754" MODIFIED="1784079609606" TEXT="Optionen"> <node CREATED="1784079589221" ID="ID_1308906754" MODIFIED="1784079609606" TEXT="Optionen">
<node CREATED="1784079611026" ID="ID_870843631" MODIFIED="1784079835110" TEXT="Buffer-Ring k&#xf6;nnte global sichtbar sein"> <node CREATED="1784079611026" ID="ID_870843631" MODIFIED="1784079835110" TEXT="Buffer-Ring k&#xf6;nnte global sichtbar sein">
<richcontent TYPE="NOTE"><html> <richcontent TYPE="NOTE"><html>
<head> <head/>
</head>
<body> <body>
<p> <p>
Sofern er aus dem GUI-Thread alloziert wird, also bevor der Proactor-Thread startet, ist die Position f&#252;r beide Threads sichtbar (und unver&#228;nderlich) Sofern er aus dem GUI-Thread alloziert wird, also bevor der Proactor-Thread startet, ist die Position f&#252;r beide Threads sichtbar (und unver&#228;nderlich)
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
<node CREATED="1784079641676" ID="ID_595831960" MODIFIED="1784079776456" TEXT="eine currentFrameNr ebenso"> <node CREATED="1784079641676" ID="ID_595831960" MODIFIED="1784079776456" TEXT="eine currentFrameNr ebenso">
<richcontent TYPE="NOTE"><html> <richcontent TYPE="NOTE"><html>
<head> <head/>
</head>
<body> <body>
<p> <p>
Diese w&#228;re dann ebenfalls teil der cross-Trade-Synchronisation (ebenfalls bewirkt durch release-Semantik auf dem State-Atomic) Diese w&#228;re dann ebenfalls teil der cross-Trade-Synchronisation (ebenfalls bewirkt durch release-Semantik auf dem State-Atomic)
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
</node> </node>
<node CREATED="1784079653178" ID="ID_1804993764" MODIFIED="1784079727230" TEXT="oder der Displayer hat intern seine eigene FrameNr"> <node CREATED="1784079653178" ID="ID_1804993764" MODIFIED="1784079727230" TEXT="oder der Displayer hat intern seine eigene FrameNr">
<richcontent TYPE="NOTE"><html> <richcontent TYPE="NOTE"><html>
<head> <head/>
</head>
<body> <body>
<p> <p>
...nur als lokale Variable, die er jeweils hochz&#228;hlt, wenn er einen Trigger bekommt (Nachteil: duplizierter State, dessen Konsistenz sich nur implizit ergibt und nicht offensichtlich ist) ...nur als lokale Variable, die er jeweils hochz&#228;hlt, wenn er einen Trigger bekommt (Nachteil: duplizierter State, dessen Konsistenz sich nur implizit ergibt und nicht offensichtlich ist)
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
</node> </node>
</node> </node>
<node CREATED="1784079838160" ID="ID_1763616932" MODIFIED="1784080020991" TEXT="k&#xf6;nnte dem Displayer direkt gegeben werden"> <node CREATED="1784079838160" ID="ID_1763616932" MODIFIED="1784080020991" TEXT="k&#xf6;nnte dem Displayer direkt gegeben werden">
<richcontent TYPE="NOTE"><html> <richcontent TYPE="NOTE"><html>
<head> <head/>
</head>
<body> <body>
<p> <p>
Das w&#228;re dann ein Pointer (const void *); seine Sichtbarkeit ergibt sich auch hier aus dem atomic-State Das w&#228;re dann ein Pointer (const void *); seine Sichtbarkeit ergibt sich auch hier aus dem atomic-State
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
<node CREATED="1784079873496" ID="ID_714454620" MODIFIED="1784079881936" TEXT="kann aber nicht per Dispatcher erfolgen"/> <node CREATED="1784079873496" ID="ID_714454620" MODIFIED="1784079881936" TEXT="kann aber nicht per Dispatcher erfolgen"/>
<node CREATED="1784079882711" ID="ID_102892347" MODIFIED="1784079907595" TEXT="mu&#xdf; dann ein Datenfeld sein (sinnvollerweise im Displayer)"/> <node CREATED="1784079882711" ID="ID_102892347" MODIFIED="1784079907595" TEXT="mu&#xdf; dann ein Datenfeld sein (sinnvollerweise im Displayer)"/>
</node> </node>
</node> </node>
<node CREATED="1784080062495" ID="ID_254917759" MODIFIED="1784080174245" TEXT="die zuletzt genanne M&#xf6;glichkeit erscheint mir am nat&#xfc;rlichsten"> <node CREATED="1784080062495" ID="ID_254917759" MODIFIED="1784080174245" TEXT="die zuletzt genanne M&#xf6;glichkeit erscheint mir am nat&#xfc;rlichsten">
<richcontent TYPE="NOTE"><html> <richcontent TYPE="NOTE"><html>
<head> <head/>
</head>
<body> <body>
<p> <p>
...da ich immer in Zust&#228;ndigkeiten denke, ist es mir unsympatisch, einen Satz gemeinsamer Zustands-Variablen zu verwenden ...da ich immer in Zust&#228;ndigkeiten denke, ist es mir unsympatisch, einen Satz gemeinsamer Zustands-Variablen zu verwenden
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
</node> </node>
</node> </node>
<node CREATED="1784080203172" ID="ID_952531619" MODIFIED="1784080213143" TEXT="daraus ergibt sich die Datenstruktur"> <node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1784080203172" ID="ID_952531619" MODIFIED="1784222609101" TEXT="daraus ergibt sich die Datenstruktur">
<icon BUILTIN="yes"/>
<node CREATED="1784080214847" ID="ID_1165930889" MODIFIED="1784080245515" TEXT="und zwar geh&#xf6;ren damit die Buffer dem Proactor-Thread"/> <node CREATED="1784080214847" ID="ID_1165930889" MODIFIED="1784080245515" TEXT="und zwar geh&#xf6;ren damit die Buffer dem Proactor-Thread"/>
<node CREATED="1784080390813" ID="ID_1044489570" MODIFIED="1784080418199" TEXT="Allocation und Ownership"> <node CREATED="1784080390813" ID="ID_1044489570" MODIFIED="1784080418199" TEXT="Allocation und Ownership">
<node CREATED="1784080461760" ID="ID_1762147278" MODIFIED="1784080535764" TEXT="Buffer sehr gro&#xdf; &#x27f9; einzeln allozieren"> <node CREATED="1784080461760" ID="ID_1762147278" MODIFIED="1784080535764" TEXT="Buffer sehr gro&#xdf; &#x27f9; einzeln allozieren">
<richcontent TYPE="NOTE"><html> <richcontent TYPE="NOTE"><html>
<head> <head/>
</head>
<body> <body>
<p> <p>
...das gilt f&#252;r ein Prod-System, in dem der Speicher framentiert ist, und man vermutlich Buffer-Pools hat ...das gilt f&#252;r ein Prod-System, in dem der Speicher framentiert ist, und man vermutlich Buffer-Pools hat
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
<icon BUILTIN="messagebox_warning"/> <icon BUILTIN="messagebox_warning"/>
</node> </node>
<node CREATED="1784080449077" ID="ID_1803805054" MODIFIED="1784080659901" TEXT="einfach w&#xe4;re ein riesiges Array auf dem Heap"> <node CREATED="1784080449077" ID="ID_1803805054" MODIFIED="1784080659901" TEXT="einfach w&#xe4;re ein riesiges Array auf dem Heap">
<richcontent TYPE="NOTE"><html> <richcontent TYPE="NOTE"><html>
<head> <head/>
</head>
<body> <body>
<p> <p>
F&#252;r die Demo ist das die offensichtliche L&#246;sung: man bekommt unique-ownership und Subscript-Operator einfach vom std::unique_ptr. Wenn man den notwendigen Speicher nicht bekommt, dann l&#228;uft die Demo eh nicht, also wozu die Umst&#228;nde? F&#252;r die Demo ist das die offensichtliche L&#246;sung: man bekommt unique-ownership und Subscript-Operator einfach vom std::unique_ptr. Wenn man den notwendigen Speicher nicht bekommt, dann l&#228;uft die Demo eh nicht, also wozu die Umst&#228;nde?
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
<icon BUILTIN="back"/> <icon BUILTIN="back"/>
</node> </node>
</node> </node>
@ -2165,16 +2149,13 @@
<node CREATED="1784131354971" ID="ID_458757211" MODIFIED="1784131366411" TEXT="diese ist jedoch festgelegt"> <node CREATED="1784131354971" ID="ID_458757211" MODIFIED="1784131366411" TEXT="diese ist jedoch festgelegt">
<node CREATED="1784131367993" ID="ID_55736035" MODIFIED="1784131407585" TEXT="durch die Forderung nach Lesbarkeit (&#xd83e;&#xdc32; Demo-Code)"> <node CREATED="1784131367993" ID="ID_55736035" MODIFIED="1784131407585" TEXT="durch die Forderung nach Lesbarkeit (&#xd83e;&#xdc32; Demo-Code)">
<richcontent TYPE="NOTE"><html> <richcontent TYPE="NOTE"><html>
<head> <head/>
</head>
<body> <body>
<p> <p>
hei&#223;t: hier gibt es keine M&#246;glichkeit, <i>ein Auge zuzudr&#252;cken</i> hei&#223;t: hier gibt es keine M&#246;glichkeit, <i>ein Auge zuzudr&#252;cken</i>
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
</node> </node>
<node CREATED="1784131409804" ID="ID_359711423" MODIFIED="1784131419742" TEXT="durch das einmal gew&#xe4;hlte Domain-Scoping"/> <node CREATED="1784131409804" ID="ID_359711423" MODIFIED="1784131419742" TEXT="durch das einmal gew&#xe4;hlte Domain-Scoping"/>
</node> </node>
@ -2188,16 +2169,13 @@
</node> </node>
<node CREATED="1784136965047" ID="ID_1744030854" MODIFIED="1784137036831" TEXT="zu kurz gedacht: es ist eine Zugriffs-Klammer"> <node CREATED="1784136965047" ID="ID_1744030854" MODIFIED="1784137036831" TEXT="zu kurz gedacht: es ist eine Zugriffs-Klammer">
<richcontent TYPE="NOTE"><html> <richcontent TYPE="NOTE"><html>
<head> <head/>
</head>
<body> <body>
<p> <p>
Eine Operation zum Zugriff und eine Operation um den abgeschlossenen Zugriff zu markieren; zudem gibt es auch noch den Dispatcher. Eine Operation zum Zugriff und eine Operation um den abgeschlossenen Zugriff zu markieren; zudem gibt es auch noch den Dispatcher.
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
<icon BUILTIN="messagebox_warning"/> <icon BUILTIN="messagebox_warning"/>
</node> </node>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1784137038242" ID="ID_1199476075" MODIFIED="1784143571509" TEXT="dann doch ein klassisches OO-Callback-Interface"> <node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1784137038242" ID="ID_1199476075" MODIFIED="1784143571509" TEXT="dann doch ein klassisches OO-Callback-Interface">
@ -2215,16 +2193,13 @@
<node CREATED="1784145655032" ID="ID_815825627" MODIFIED="1784145664817" TEXT="macht man das mit C++?"/> <node CREATED="1784145655032" ID="ID_815825627" MODIFIED="1784145664817" TEXT="macht man das mit C++?"/>
<node CREATED="1784145665437" ID="ID_1276445757" MODIFIED="1784145828191" TEXT="besser direkt mit den POSIX-Funktionen"> <node CREATED="1784145665437" ID="ID_1276445757" MODIFIED="1784145828191" TEXT="besser direkt mit den POSIX-Funktionen">
<richcontent TYPE="NOTE"><html> <richcontent TYPE="NOTE"><html>
<head> <head/>
</head>
<body> <body>
<p> <p>
Mehrere Argumente daf&#252;r: man k&#246;nnte die low-level-Flags setzen (wie <code>O_CLOEXEX, O_NOFOLLOW, </code>oder gar <code>O_DIRECT</code>). Das &#214;ffnen ist <i>atomic,</i>&#160; d.h. das File kann nicht mehr gel&#246;scht/verschoben werden beform man das Filehandle hat (was bei einem getrennten STAT und Path-Check durchaus m&#246;glich ist) Mehrere Argumente daf&#252;r: man k&#246;nnte die low-level-Flags setzen (wie <code>O_CLOEXEX, O_NOFOLLOW, </code>oder gar <code>O_DIRECT</code>). Das &#214;ffnen ist <i>atomic,</i>&#160; d.h. das File kann nicht mehr gel&#246;scht/verschoben werden beform man das Filehandle hat (was bei einem getrennten STAT und Path-Check durchaus m&#246;glich ist)
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
</node> </node>
<node CREATED="1784147238004" ID="ID_973311307" LINK="https://man7.org/linux/man-pages/man2/open.2.html" MODIFIED="1784147251992" TEXT="man: open()"/> <node CREATED="1784147238004" ID="ID_973311307" LINK="https://man7.org/linux/man-pages/man2/open.2.html" MODIFIED="1784147251992" TEXT="man: open()"/>
</node> </node>
@ -2236,9 +2211,7 @@
<node CREATED="1784151717872" ID="ID_1035839641" MODIFIED="1784151726466" TEXT="das ist eine spezielle Submission in den URing"/> <node CREATED="1784151717872" ID="ID_1035839641" MODIFIED="1784151726466" TEXT="das ist eine spezielle Submission in den URing"/>
<node BACKGROUND_COLOR="#e6dfa8" COLOR="#690f14" CREATED="1784151807158" ID="ID_161068537" MODIFIED="1784152246318" TEXT="&#x27f9; mu&#xdf; URing um +1 Slot gr&#xf6;&#xdf;er dimensionieren"> <node BACKGROUND_COLOR="#e6dfa8" COLOR="#690f14" CREATED="1784151807158" ID="ID_161068537" MODIFIED="1784152246318" TEXT="&#x27f9; mu&#xdf; URing um +1 Slot gr&#xf6;&#xdf;er dimensionieren">
<richcontent TYPE="NOTE"><html> <richcontent TYPE="NOTE"><html>
<head> <head/>
</head>
<body> <body>
<p> <p>
Begr&#252;ndung Begr&#252;ndung
@ -2261,8 +2234,7 @@
</li> </li>
</ul> </ul>
</body> </body>
</html> </html></richcontent>
</richcontent>
<icon BUILTIN="messagebox_warning"/> <icon BUILTIN="messagebox_warning"/>
</node> </node>
<node CREATED="1784151734786" ID="ID_546021072" MODIFIED="1784151801321" TEXT="verwende hier meine Hilfsfunktion f&#xfc;r Chrono &#x27fc; Kernel-Timespec"> <node CREATED="1784151734786" ID="ID_546021072" MODIFIED="1784151801321" TEXT="verwende hier meine Hilfsfunktion f&#xfc;r Chrono &#x27fc; Kernel-Timespec">
@ -2270,8 +2242,8 @@
</node> </node>
</node> </node>
</node> </node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1784143738263" ID="ID_1385880788" MODIFIED="1784152297376" TEXT="Handler-Loop"> <node COLOR="#338800" CREATED="1784143738263" ID="ID_1385880788" MODIFIED="1784222595782" TEXT="Handler-Loop">
<icon BUILTIN="pencil"/> <icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1784143781367" ID="ID_1463866164" MODIFIED="1784165740325" TEXT="gelesene Daten entgegennehmen"> <node COLOR="#338800" CREATED="1784143781367" ID="ID_1463866164" MODIFIED="1784165740325" TEXT="gelesene Daten entgegennehmen">
<icon BUILTIN="button_ok"/> <icon BUILTIN="button_ok"/>
<node CREATED="1784165743594" ID="ID_465943099" MODIFIED="1784165755001" TEXT="ERRNO steckt im cqe.res"> <node CREATED="1784165743594" ID="ID_465943099" MODIFIED="1784165755001" TEXT="ERRNO steckt im cqe.res">
@ -2300,23 +2272,18 @@
<icon BUILTIN="button_ok"/> <icon BUILTIN="button_ok"/>
<node CREATED="1784166180437" ID="ID_411616254" MODIFIED="1784166202948"> <node CREATED="1784166180437" ID="ID_411616254" MODIFIED="1784166202948">
<richcontent TYPE="NODE"><html> <richcontent TYPE="NODE"><html>
<head> <head/>
</head>
<body> <body>
<p> <p>
verwende hier den zweiten Cursor: <font face="Monospaced" color="#271bd4">nextShow_</font> verwende hier den zweiten Cursor: <font face="Monospaced" color="#271bd4">nextShow_</font>
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
</node> </node>
<node CREATED="1784166214698" ID="ID_255228689" MODIFIED="1784166237247" TEXT="dar&#xfc;ber auf den State dieses Buffer-Slot zugreifen"/> <node CREATED="1784166214698" ID="ID_255228689" MODIFIED="1784166237247" TEXT="dar&#xfc;ber auf den State dieses Buffer-Slot zugreifen"/>
<node CREATED="1784166238079" ID="ID_503678940" MODIFIED="1784166404098" TEXT="wenn Daten da sind (state == SHOW) &#x27f9; trigger Displayer"> <node CREATED="1784166238079" ID="ID_503678940" MODIFIED="1784166404098" TEXT="wenn Daten da sind (state == SHOW) &#x27f9; trigger Displayer">
<richcontent TYPE="NOTE"><html> <richcontent TYPE="NOTE"><html>
<head> <head/>
</head>
<body> <body>
<p> <p>
...und zwar via Glib::Dispatcher &#10230; GUI-Thread. ...und zwar via Glib::Dispatcher &#10230; GUI-Thread.
@ -2325,21 +2292,17 @@
Der zugeh&#246;rige Handler-Code l&#228;uft dann bei n&#228;chster Gelegenheit in der GUI-Event-Loop, und holt sich per Callback (Interface PixelFeed) die Daten; in diesem Callback mu&#223; die Read-Barrier realisiert sein, damit der GUI-Thread alle vor diesem Punkt erfolgten Daten&#228;nderungen auch tats&#228;chlich sieht Der zugeh&#246;rige Handler-Code l&#228;uft dann bei n&#228;chster Gelegenheit in der GUI-Event-Loop, und holt sich per Callback (Interface PixelFeed) die Daten; in diesem Callback mu&#223; die Read-Barrier realisiert sein, damit der GUI-Thread alle vor diesem Punkt erfolgten Daten&#228;nderungen auch tats&#228;chlich sieht
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
</node> </node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1784166414946" ID="ID_1720545051" MODIFIED="1784166498112" TEXT="wenn hier Short-Read markiert &#x27f9; Player anhalten"> <node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1784166414946" ID="ID_1720545051" MODIFIED="1784166498112" TEXT="wenn hier Short-Read markiert &#x27f9; Player anhalten">
<richcontent TYPE="NOTE"><html> <richcontent TYPE="NOTE"><html>
<head> <head/>
</head>
<body> <body>
<p> <p>
Beachte: das darf erst hier passieren, weil wir hier den n&#228;chst niedersten erwarteten Frame anschauen; da wir immer etwas im Voraus lesen, werden wir auch ein end-of-File schon einige Ticks fr&#252;her markieren, m&#252;ssen aber die Schleife noch solange weiterlaufen lassen, bis die letzten erfolgreich gelesenen Frames in die Anzeige &#252;bertragen wurden Beachte: das darf erst hier passieren, weil wir hier den n&#228;chst niedersten erwarteten Frame anschauen; da wir immer etwas im Voraus lesen, werden wir auch ein end-of-File schon einige Ticks fr&#252;her markieren, m&#252;ssen aber die Schleife noch solange weiterlaufen lassen, bis die letzten erfolgreich gelesenen Frames in die Anzeige &#252;bertragen wurden
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
<icon BUILTIN="messagebox_warning"/> <icon BUILTIN="messagebox_warning"/>
</node> </node>
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1784166503838" ID="ID_645230473" MODIFIED="1784166532804" TEXT="Bei genauerer Betrachtung : t&#xfc;ckisches Korrektheits-Problem hier"> <node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1784166503838" ID="ID_645230473" MODIFIED="1784166532804" TEXT="Bei genauerer Betrachtung : t&#xfc;ckisches Korrektheits-Problem hier">
@ -2350,34 +2313,29 @@
<node CREATED="1784166606710" ID="ID_499843773" MODIFIED="1784166618527" TEXT="in beiden F&#xe4;llen ist der Cursor inkonsitent"/> <node CREATED="1784166606710" ID="ID_499843773" MODIFIED="1784166618527" TEXT="in beiden F&#xe4;llen ist der Cursor inkonsitent"/>
<node CREATED="1784166652416" ID="ID_261339357" MODIFIED="1784166866154"> <node CREATED="1784166652416" ID="ID_261339357" MODIFIED="1784166866154">
<richcontent TYPE="NODE"><html> <richcontent TYPE="NODE"><html>
<head> <head/>
</head>
<body> <body>
<p> <p>
brauche doch einen 3.Cursor: <font face="Monospaced" color="#5f15de">currShow_</font> brauche doch einen 3.Cursor: <font face="Monospaced" color="#5f15de">currShow_</font>
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
</node> </node>
<node BACKGROUND_COLOR="#d9b995" COLOR="#690f14" CREATED="1784165814417" ID="ID_312946304" MODIFIED="1784167391017" TEXT="mu&#xdf; zwingend weitere State-Transition einf&#xfc;rhen: WAIT"> <node BACKGROUND_COLOR="#d9b995" COLOR="#690f14" CREATED="1784165814417" ID="ID_312946304" MODIFIED="1784221578895" TEXT="mu&#xdf; zwingend weitere State-Transition einf&#xfc;rhen: FEED">
<arrowlink COLOR="#6574c5" DESTINATION="ID_721661485" ENDARROW="Default" ENDINCLINATION="925;77;" ID="Arrow_ID_86014624" STARTARROW="None" STARTINCLINATION="397;-23;"/> <arrowlink COLOR="#6574c5" DESTINATION="ID_721661485" ENDARROW="Default" ENDINCLINATION="925;77;" ID="Arrow_ID_86014624" STARTARROW="None" STARTINCLINATION="397;-23;"/>
<arrowlink COLOR="#a03127" DESTINATION="ID_194548529" ENDARROW="Default" ENDINCLINATION="373;0;" ID="Arrow_ID_726120332" STARTARROW="None" STARTINCLINATION="-39;152;"/>
<icon BUILTIN="yes"/> <icon BUILTIN="yes"/>
<node CREATED="1784167398651" ID="ID_977847492" MODIFIED="1784167422438" TEXT="denn der 3.Cursor kann erst hier bewegt werden"/> <node CREATED="1784167398651" ID="ID_977847492" MODIFIED="1784167422438" TEXT="denn der 3.Cursor kann erst hier bewegt werden"/>
<node CREATED="1784167422935" ID="ID_953106086" MODIFIED="1784167433471" TEXT="und es ist nun der 3.Cursor, der vom GUI-Thread verwendet wird"/> <node CREATED="1784167422935" ID="ID_953106086" MODIFIED="1784167433471" TEXT="und es ist nun der 3.Cursor, der vom GUI-Thread verwendet wird"/>
<node CREATED="1784167433959" ID="ID_1914570598" MODIFIED="1784167447134"> <node CREATED="1784167433959" ID="ID_1914570598" MODIFIED="1784167447134">
<richcontent TYPE="NODE"><html> <richcontent TYPE="NODE"><html>
<head> <head/>
</head>
<body> <body>
<p> <p>
also brauche ich die cross-Thread-Barriere <b>erst hier</b> also brauche ich die cross-Thread-Barriere <b>erst hier</b>
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
</node> </node>
</node> </node>
</node> </node>
@ -2409,48 +2367,75 @@
<icon BUILTIN="idea"/> <icon BUILTIN="idea"/>
<node CREATED="1784142980731" ID="ID_1146524396" MODIFIED="1784142995774"> <node CREATED="1784142980731" ID="ID_1146524396" MODIFIED="1784142995774">
<richcontent TYPE="NODE"><html> <richcontent TYPE="NODE"><html>
<head> <head/>
</head>
<body> <body>
<p> <p>
also <i>keine explizite</i>&#160;Steuerung also <i>keine explizite</i>&#160;Steuerung
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
</node> </node>
<node CREATED="1784143310222" ID="ID_1598149960" MODIFIED="1784143340787" TEXT="vielmehr sorgt die feste zyklische Buffer-Struktur f&#xfc;r die Limitierung"/> <node CREATED="1784143310222" ID="ID_1598149960" MODIFIED="1784143340787" TEXT="vielmehr sorgt die feste zyklische Buffer-Struktur f&#xfc;r die Limitierung"/>
<node CREATED="1784143015199" ID="ID_218469149" MODIFIED="1784143039421" TEXT="zwei Phasen schreiten jeweils so schnell voran wie derzeig m&#xf6;glich"> <node CREATED="1784143015199" ID="ID_218469149" MODIFIED="1784143039421" TEXT="zwei Phasen schreiten jeweils so schnell voran wie derzeig m&#xf6;glich">
<node CREATED="1784143040300" ID="ID_227838217" MODIFIED="1784143254426" TEXT="Phase-1 : read-Submissions beauftragen"> <node CREATED="1784143040300" ID="ID_227838217" MODIFIED="1784143254426" TEXT="Phase-1 : read-Submissions beauftragen">
<richcontent TYPE="NOTE"><html> <richcontent TYPE="NOTE"><html>
<head> <head/>
</head>
<body> <body>
<p> <p>
ist jeweils nur m&#246;glich wenn der daf&#252;r vorgesehene Buffer bereits frei geworden ist ist jeweils nur m&#246;glich wenn der daf&#252;r vorgesehene Buffer bereits frei geworden ist
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
</node> </node>
<node CREATED="1784143055979" ID="ID_1727640820" MODIFIED="1784143309405" TEXT="Phase-2 : eingelesene Daten &#xfc;bergeben"> <node CREATED="1784143055979" ID="ID_1727640820" MODIFIED="1784143309405" TEXT="Phase-2 : eingelesene Daten &#xfc;bergeben">
<richcontent TYPE="NOTE"><html> <richcontent TYPE="NOTE"><html>
<head> <head/>
</head>
<body> <body>
<p> <p>
Ist nur m&#246;glich wenn diese Daten f&#252;r den erwartungsgem&#228;&#223; n&#228;chsten Frame bereits da sind, und der unmittelbar vorausgegangene Frame schon komplett vom Video-Displayer &#252;bernommen wurde Ist nur m&#246;glich wenn diese Daten f&#252;r den erwartungsgem&#228;&#223; n&#228;chsten Frame bereits da sind, und der unmittelbar vorausgegangene Frame schon komplett vom Video-Displayer &#252;bernommen wurde
</p> </p>
</body> </body>
</html></richcontent>
</node>
</node>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1784221175896" ID="ID_777175706" MODIFIED="1784222589807" TEXT="Ausreifen und Testen">
<icon BUILTIN="pencil"/>
<node CREATED="1784221197676" ID="ID_888318010" MODIFIED="1784221200745" TEXT="Code-Verbesserungen">
<node CREATED="1784221201656" ID="ID_206094356" MODIFIED="1784221217727" TEXT="Getter im BufferDispatcher einf&#xfc;hren">
<node CREATED="1784221218666" ID="ID_847912873" MODIFIED="1784221225933" TEXT="f&#xfc;r current-state und current-frame"/>
<node CREATED="1784221226449" ID="ID_1575870011" MODIFIED="1784221251514" TEXT="verbirgt den kaskadierenden Zugriff &#xfc;ber den outer-Pointer"/>
<node CREATED="1784221253300" ID="ID_1527096674" MODIFIED="1784221274998" TEXT="macht au&#xdf;erdem die Verwendungsstelle lesbarer (Intention im Namen)"/>
</node>
<node CREATED="1784221286953" ID="ID_468705787" MODIFIED="1784221294691" TEXT="State-Flags umbenennen">
<node CREATED="1784221295711" ID="ID_194548529" MODIFIED="1784221395809" TEXT="die Bedeutung von SHOW hat sich ge&#xe4;ndert">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
im State SHOW pasiert jetzt gar nicht mehr das Display, sondern es bedeutet nun, da&#223; der Frame weitergegeben werden mu&#223;
</p>
</body>
</html> </html>
</richcontent> </richcontent>
<linktarget COLOR="#a03127" DESTINATION="ID_194548529" ENDARROW="Default" ENDINCLINATION="373;0;" ID="Arrow_ID_726120332" SOURCE="ID_312946304" STARTARROW="None" STARTINCLINATION="-39;152;"/>
</node>
<node CREATED="1784221423989" ID="ID_1367029376" MODIFIED="1784221595584" TEXT="nenne diese Phase jetzt FEED">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
suche einen 4-Buchstaben-Namen, da bin ich &#196;sthet. PUSH w&#228;re auch denkbar, nat&#252;rlich w&#228;re PROPAGATE viel korrekter ;-)
</p>
</body>
</html></richcontent>
</node> </node>
</node> </node>
</node> </node>
</node> <node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1784222841942" ID="ID_74519525" MODIFIED="1784222846614" TEXT="zum Laufen bringen">
<icon BUILTIN="flag-pink"/>
</node> </node>
</node> </node>
</node> </node>

View file

@ -40,13 +40,32 @@ auto calcSrcFrame = [](size_t runningNr){ return START_FRAME + runningNr % MAX_L
//-----------------hard-coded-config-- //-----------------hard-coded-config--
/**
* Read video frames from a raw video file and pass them to OpenGL display.
* Using a »Proactor« thread to coordinate reading via IO_URING.
* Allocates a set of frame-sized buffers (using #RING_SIZ buffers)
* and uses them cyclically, first adding new tasks to read a frame-block
* from the file, receiving completed tasks to hand-over the next frame
* driven by a frame-beat timer, that is also based on IO_URING.
* Each buffer »slot« is associated with a #BuffState flag, implemented
* as `std::atomic` to also serve for cross-thread visibility.
* @note UringVideoPlayer must be constructed in the GTK UI thread,
* yet will immediately launch the »Proactor« thread from the ctor.
* @remarks
* - the source video and layout is hard wired
* - playback will either be looped (if the loop fits into the source video)
* - otherwise, when encountering end-of-file, or when the GTK window is closed,
* the »Proactor« thread will terminate.
* - frames will be submitted to display at the regular timer beats,
* whenever they are ready; frames delayed by IO will slip to the next beat.
*/
class UringVideoPlayer class UringVideoPlayer
: NonCopyable : NonCopyable
{ {
using VideoDisplay = EglDisplay<uint8_t, VIDEO_WIDTH,VIDEO_HEIGHT>; using VideoDisplay = EglDisplay<uint8_t, VIDEO_WIDTH,VIDEO_HEIGHT>;
using Buffer = VideoDisplay::Buffer; using Buffer = VideoDisplay::Buffer;
enum BuffState { FREE=0, READ, SHOW, WAIT, STOP }; enum BuffState { FREE, READ, FEED, SHOW, STOP };
using AtomicBuffState = std::atomic<BuffState>; using AtomicBuffState = std::atomic<BuffState>;
using BufferAlloc = unique_ptr<Buffer[]>; using BufferAlloc = unique_ptr<Buffer[]>;
@ -65,10 +84,15 @@ class UringVideoPlayer
void completedFrame() override; void completedFrame() override;
UringVideoPlayer& player_; UringVideoPlayer& player_;
public: public:
BufferDispatcher (UringVideoPlayer& player) BufferDispatcher (UringVideoPlayer& player)
: player_{player} : player_{player}
{ } { }
private:
Buffer& getCurrentFrame();
AtomicBuffState& getCurrentFrameState();
}; };
size_t nextRead_{0}; size_t nextRead_{0};
@ -108,37 +132,37 @@ class UringVideoPlayer
void void
UringVideoPlayer::playVideo() UringVideoPlayer::playVideo()
{ {
/* ===== initial setup ===== */ /* =============== initial-setup =============== */
int inputFD = open (RAW_VIDEO_INPUT_FILE.c_str(), O_RDONLY); int inputFD = open (RAW_VIDEO_INPUT_FILE.c_str(), O_RDONLY);
if (inputFD < 0) if (inputFD < 0)
__FAIL ("open file \""+RAW_VIDEO_INPUT_FILE+"\""); __FAIL ("open file \""+RAW_VIDEO_INPUT_FILE+"\"");
// Allocate several data buffers (used as ring) // Allocate several data buffers (used as ring)
buffer_ = make_unique<Buffer[]> (RING_SIZ); buffer_ = make_unique<Buffer[]> (RING_SIZ);
buffState_ = make_unique<AtomicBuffState[]> (RING_SIZ); buffState_ = make_unique<AtomicBuffState[]> (RING_SIZ);
// initialise uRing Kernel interface // initialise uRing Kernel interface
io_uring uRing; io_uring uRing;
io_uring_queue_init (RING_SIZ+1, &uRing, /*flags*/ 0 ); // Note: one additional »slot« for the timer event(s) io_uring_queue_init (RING_SIZ+1, &uRing, /*flags*/ 0 ); // Note: one additional »slot« for the timer event(s)
// Setup periodic frame beat, firing infinitely // Setup periodic frame beat, firing infinitely
const auto TICK_TAG = UINT64_MAX; // special marker for timer events (different from possible frame numbers) const auto TICK_TAG = UINT64_MAX; // special marker for timer events (differs from possible frame numbers)
auto timespec = asKernelTimespec (40ms); // 25fps ≙ 40ms per frame auto timespec = asKernelTimespec (40ms); // 25fps ≙ 40ms per frame
io_uring_sqe* timerSubmission = io_uring_get_sqe (&uRing); io_uring_sqe* timerSubmission{io_uring_get_sqe (&uRing)};
io_uring_prep_timeout (timerSubmission, &timespec, /*no count limit*/ 0, IORING_TIMEOUT_MULTISHOT); io_uring_prep_timeout (timerSubmission, &timespec, /*no count limit*/ 0, IORING_TIMEOUT_MULTISHOT);
io_uring_sqe_set_data64(timerSubmission, TICK_TAG); io_uring_sqe_set_data64(timerSubmission, TICK_TAG);
addNextReadSubmissions (uRing, inputFD); addNextReadSubmissions (uRing, inputFD);
io_uring_submit (&uRing); io_uring_submit (&uRing);
/* ===== proactor-loop ===== */ /* =============== proactor-loop =============== */
playing_ = true; playing_ = true;
while (playing_.load (std::memory_order_acquire)) while (playing_.load (std::memory_order_acquire))
{ {
io_uring_cqe* completion; io_uring_cqe* completion;
// blocking wait for the next completion entry // blocking wait for the next completion entry
int res = io_uring_wait_cqe (&uRing, &completion); int res = io_uring_wait_cqe (&uRing, &completion);
if (0 > res) if (res < 0)
__FAIL ("retrieval of io_uring completion failed"); __FAIL ("retrieval of io_uring completion failed");
uint64_t tag = completion->user_data; uint64_t tag = completion->user_data;
@ -167,7 +191,7 @@ UringVideoPlayer::addNextReadSubmissions (io_uring& uRing, int inputFD)
assert (0 < inputFD); assert (0 < inputFD);
const size_t BUFFSIZ = sizeof(Buffer); const size_t BUFFSIZ = sizeof(Buffer);
while (buffState_[nextRead_ % RING_SIZ] == FREE) while (FREE == buffState_[nextRead_ % RING_SIZ])
{ {
size_t srcOffset = calcSrcFrame (nextRead_); size_t srcOffset = calcSrcFrame (nextRead_);
io_uring_sqe* readSubmission = io_uring_get_sqe (&uRing); io_uring_sqe* readSubmission = io_uring_get_sqe (&uRing);
@ -191,12 +215,12 @@ UringVideoPlayer::handleCompletedRead (io_uring_cqe& completion)
__FAIL ("async read of frame from video file failed"); __FAIL ("async read of frame from video file failed");
size_t frameNr = completion.user_data; // Note: completion was marked with the frameNr as »user data« size_t frameNr = completion.user_data; // Note: completion was marked with the frameNr as »user data«
auto& state = buffState_[frameNr % RING_SIZ]; // Can thus pick buffer slot based on frame number, modulus ring size auto& state = buffState_[frameNr % RING_SIZ]; // Can thus pick buffer slot based on frame number, cycling through the ring
if (completion.res != sizeof(Buffer)) if (completion.res != sizeof(Buffer))
state.store(STOP, std::memory_order_relaxed); // Insufficient read, possibly end-of-file => signal stop of playback (to ourselves) state.store(STOP, std::memory_order_relaxed); // Insufficient read, possibly end-of-file => signal stop of playback (to ourselves)
else else
state.store(SHOW, std::memory_order_relaxed); // Success; frame data is in the buffer => mark ready for use at the next tick event state.store(FEED, std::memory_order_relaxed); // Success; frame data is in the buffer => mark ready for use at the next tick event
} }
@ -215,12 +239,12 @@ UringVideoPlayer::maybeDisplayFrame()
auto prevState = buffState_[currShow_ % RING_SIZ].load (std::memory_order_relaxed); auto prevState = buffState_[currShow_ % RING_SIZ].load (std::memory_order_relaxed);
auto nextState = buffState_[nextShow_ % RING_SIZ].load (std::memory_order_relaxed); auto nextState = buffState_[nextShow_ % RING_SIZ].load (std::memory_order_relaxed);
if (nextState == SHOW and prevState == FREE) if (nextState == FEED and prevState == FREE)
{ // can hand over this next frame to the VideoDisplay in the GUI-thread { // can hand over this next frame to the VideoDisplay in the GUI-thread
currShow_ = nextShow_; currShow_ = nextShow_;
++nextShow_; ++nextShow_;
// mark state to wait for display to complete; this also creates a write barrier // mark state to wait for display completion; this also creates a write barrier
buffState_[currShow_ % RING_SIZ].store (WAIT, std::memory_order_release); buffState_[currShow_ % RING_SIZ].store (SHOW, std::memory_order_release);
// Notify GUI thread via Glib::Dispatcher // Notify GUI thread via Glib::Dispatcher
dispatchFrame_(); dispatchFrame_();
} }
@ -239,9 +263,9 @@ UringVideoPlayer::Buffer*
UringVideoPlayer::BufferDispatcher::retrieveFrame() UringVideoPlayer::BufferDispatcher::retrieveFrame()
{ {
// retrieve buffer state from proactor-thread; this also creates a read barrier // retrieve buffer state from proactor-thread; this also creates a read barrier
auto frameState = player_.buffState_[player_.currShow_ % RING_SIZ].load (std::memory_order_acquire); auto frameState = getCurrentFrameState().load (std::memory_order_acquire);
if (frameState == WAIT) if (frameState == SHOW)
return & player_.buffer_[player_.currShow_ % RING_SIZ]; return & getCurrentFrame();
else else
return nullptr; return nullptr;
// (can happen only in boundary cases) // (can happen only in boundary cases)
@ -252,7 +276,22 @@ void
UringVideoPlayer::BufferDispatcher::completedFrame() UringVideoPlayer::BufferDispatcher::completedFrame()
{ {
// mark buffer as display complete for the proactor-thread; this also creates a write barrier // mark buffer as display complete for the proactor-thread; this also creates a write barrier
player_.buffState_[player_.currShow_ % RING_SIZ].store (FREE, std::memory_order_release); getCurrentFrameState().store (FREE, std::memory_order_release);
}
UringVideoPlayer::Buffer&
UringVideoPlayer::BufferDispatcher::getCurrentFrame()
{
auto currFrame = player_.currShow_;
return player_.buffer_[currFrame % RING_SIZ];
}
UringVideoPlayer::AtomicBuffState&
UringVideoPlayer::BufferDispatcher::getCurrentFrameState()
{
auto currFrame = player_.currShow_;
return player_.buffState_[currFrame % RING_SIZ];
} }

View file

@ -336,7 +336,7 @@ void
EglDisplay<PIX,WIDTH,HEIGHT>::displayFrame() EglDisplay<PIX,WIDTH,HEIGHT>::displayFrame()
{ {
auto currFrame = pixelFeed_.retrieveFrame(); auto* currFrame = pixelFeed_.retrieveFrame();
if (not currFrame) return; if (not currFrame) return;
// pick up current buffer with RGB data // pick up current buffer with RGB data