Hello, Guest the thread was viewed363 times and contains 17 replies

last post from DS65 at the

Interrupt-Handling im Zusammenhang mit der Garbage Collection?

  • Bekanntermaßen friert während einer Garbage Collection der C-64 sozusagen ein und lässt sich auch durch die Betätigung der STOP-Taste nicht aus dem Konzept bringen. Das legt den Schluss nahe, dass entweder der IRQ-Vektor verbogen oder aber der Interrupt mittels eines SEI-Befehls unterdrückt wird.


    Ich befinde mich in der Planungsphase für einen Bildschirmschoner, der nach dem Abschalten der Bildschirmanzeige eine vorbeugende Garbage Collection aufrufen soll. Nun soll dieser Bildschirmschoner aber natürlich als Interrupt-Routine implementiert werden. In Erwartung möglicher Konflikte habe ich mir (nach umfangreichen Recherchen zum Thema Garbage Collection im Allgemeinen) die Garbage Collection im ROM-Listing (ab $B526) näher angesehen. Sowohl dort als auch in den aufrufenden Routinen konnte ich allerdings keinen Hinweis darauf finden, dass der IRQ auf irgendeine Weise beeinflusst wird.


    Sehe ich da den Wald vor lauter Bäumen nicht oder gehe ich vielleicht von falschen Grundannahmen aus? Ich wäre Euch sehr dankbar für nützliche Hinweise! :)

  • Ich GLAUBE, die IRQ-Routine setzt nur ein Flag, wenn die Stop-Taste gedrückt wurde, oder schreibt sogar nur was in den Tastaturpuffer. Die große Basic-Schleife guckt hin und wieder nach, ob Stop gedrückt wurde, aber dazu kommt sie grad nicht, weil die GC läuft.


    Verloren sein sollte das STOP aber nicht, nach der GC sollte es ausgeführt werden. Das könntest Du kurz testen.

    Und ansonsten könntest Du in der IRQ-Routine zur Tastaturabfrage suchen, oder die CIA-Registerzugriffe... Kann sein, dass die Stop-Taste eine Extra-Abfrage war.

  • Bekanntermaßen [...] Das legt den Schluss nahe, dass entweder der IRQ-Vektor verbogen oder aber der Interrupt mittels eines SEI-Befehls unterdrückt wird.

    Weder, noch.


    Der Interrupt ist nach wie vor erlaubt, und auch der Status der STOP-Taste wird beständig aktualisiert.


    Die von dir erwähnte Wirkung der STOP-Taste findet im wesentlichen *) nur an einer bestimmten Stelle im Interpreter statt, nämlich unmittelbar bevor ein neuer Befehl ausgeführt wird:


    $A7AE/42926: BASIC Warm Start - All_About_Your_64-Online-Help Version 0.64


    Da sich während einer GC der Interpreter aber sozusagen mitten in einem Befehl (Zeichenkettenauswertung, ggfs. mit Zuweisung an eine Stringvariable) befindet, wird die STOP-Taste eben "zur Zeit" nicht abgefragt, und darum läßt sich das BASIC-Programm auch nicht unterbrechen.


    Ähnliche Situationen hast Du während der Ausführung eines INPUT-Befehls (also, wenn der Rechner mit einem blinkenden Cursor auf deine Eingabe + RETURN wartet) oder beim der Ausführung des WAIT-Befehls - solange die Bedingung nicht erfüllt ist. Kann sie bei WAIT nicht erfüllt werden, dann "hängt" der Rechner aus dem gleichen Grund.


    In all diesen Fällen hilft immer noch die Tastenkombination STOP/RESTORE. Die löst dann einen Warmstart von BASIC aus.



    *) Eine Ausnahme sind hier diverse Datei-Operationen. LOAD und SAVE fragen auch während des laufenden Dateizugriffs regelmäßig die STOP-Taste ab und erlauben dadurch ebenfalls eine Unterbrechung dieser Vorgänge.

  • Noch als Ergänzung, warum die STOP-Taste im allgemeinen so "selten" abgefragt wird: dadurch ist gewährleistet, daß sich der Interpreter, das Programm und der Variablenspeicher beim Anhalten des Programm nicht in einem Zwischenzustand befinden. Der Nutzer sieht ja dann den Direktmodus und kann das Programm LISTen, sich Variablen anschauen, sogar neue Variablen zuweisen und das Programm mit CONT fortsetzen. Diese Debugging-Möglichkeiten wären mit einem Variablenspeicher, auf dem gerade eine Garbage-Collection arbeitet, ein sehr interessantes (heißt: schwieriges) Unterfangen.

  • Und ich brauche die Garbage Collection einfach nur aufzurufen.

    Es gibt keinen sinnvollen Grund für einen Bildschirmschoner, eine GC auszulösen. Das macht der Interpreter schon selbst wenn es nötig ist. Aus einer Interrupt-Routine heraus ist das sogar sehr gefährlich, weil überhaupt nicht garantiert ist, daß sich der Interpreter gerade in einem Zustand befindet in dem gefahrlos eine GC ausgeführt werden kann!


    Generell gilt für Interrupt-Routinen, daß sie tunlichst weitergehende Eingriffe in den Zustand des Rechners vermeiden sollten sofern das nicht mit dem im Vordergrund laufenden Programm abgestimmt ist. So ein Bildschirmschoner ist da schon ziemlich grenzwertig. Alle Speicheradressen, die möglicherweise vom Vordergrundprozeß in Anspruch genommen werden, müssen exakt wieder so hergestellt werden, wie sie es vorher waren. Gleiches gilt sinngemäß für die Einstellung des Videochips und den beanspruchten Bildschirmspeicher.


    Du solltest dir abschließend vorstellen, wie 'lustig' das ist, wenn der Bildschirmschoner eine bereits laufende GC unterbricht und seinerseits eine GC startet. Letztere beginnt dann ihre Arbeit auf einem im wesentlichen undefinierten Zustand des Variablenspeichers, und was die "Interrupt-GC" dann auch immer als Ergebnis hinterläßt, trifft dann auf die zuvor laufende GC, die jetzt mit völlig falschen Voraussetzungen weiterarbeiten soll. Das Ergebnis: Datensalat.

  • Und ich brauche die Garbage Collection einfach nur aufzurufen.

    Es gibt keinen sinnvollen Grund für einen Bildschirmschoner, eine GC auszulösen. Das macht der Interpreter schon selbst wenn es nötig ist. Aus einer Interrupt-Routine heraus ist das sogar sehr gefährlich, weil überhaupt nicht garantiert ist, daß sich der Interpreter gerade in einem Zustand befindet in dem gefahrlos eine GC ausgeführt werden kann!

    Beim zweiten Teil Deiner Antwort kann ich Dir folgen, das habe ich wohl nicht ganz zu Ende gedacht und werde das noch ein bisschen begrübeln.


    Allerdings habe ich, was den ersten Teil angeht, eine andere Sicht auf die Dinge. Ich halte es durchaus für sinnvoll, von Zeit zu Zeit eine kontrollierte Garbage Collection auszulösen, bervor der Müllberg so groß ist, dass sie automatisch in Gang gesetzt wird und dabei evtl. schmerzhaft auffällt. Und aus meiner Sicht gibt es dafür keinen besseren Zeitpunkt, als wenn der Rechner eh inaktiv ist.


    Aber vielen Dank für die Warnung bezüglich des Aufrufs aus einem Interrupt heraus.

  • Generell gilt für Interrupt-Routinen, daß sie tunlichst weitergehende Eingriffe in den Zustand des Rechners vermeiden sollten sofern das nicht mit dem im Vordergrund laufenden Programm abgestimmt ist. So ein Bildschirmschoner ist da schon ziemlich grenzwertig. Alle Speicheradressen, die möglicherweise vom Vordergrundprozeß in Anspruch genommen werden, müssen exakt wieder so hergestellt werden, wie sie es vorher waren. Gleiches gilt sinngemäß für die Einstellung des Videochips und den beanspruchten Bildschirmspeicher.

    Mein Plan ist bisher lediglich, die Bildschirmanzeige mit POKE53265,PEEK(53265)AND239 (das wäre die BASIC-Entsprechung) komplett auszuschalten. Siehst Du in einem solchen Fall auch Probleme?

  • wenn der Rechner eh inaktiv ist

    Das verleitet mich zu einer Gegenfrage: Woran wirst Du festmachen, wann ein C64 aktiv oder inaktiv ist?

    Wenn der Nutzer ihn in Ruhe lässt (keine Taste drückt), hat der Rechner ein bissel Spielraum. Natürlich befindet er sich dann nicht wirklich in einer Ruhephase, aber die Garbage Collection dürfte weniger nerven, während der Rechner nicht genutzt wird und zudem der Bildschirm dunkel und leer ist - weil gerade der Bildschirmschoner aktiviert ist. Aber das Thema Garbage Collection aus einer Interrupt-Routine heraus hat sich ja eh inzwischen erledigt.

  • Gibt es denn eine Art FLAG dass die GC des Systems gerade läuft oder DONE oder so :nixwiss:

    "Was heute noch wie ein Märchen klingt,kann morgen Wirklichkeit sein.Hier ist ein Märchen von übermorgen.Es gibt keine Kupferka­bel mehr,es gibt nur noch die Glasfaser und Terminals in jedem Raum.Man siedelt auf fernen Rech­nern.Die Mailboxen sind als Wohnraum erschlossen.Mit heute noch unvorstellbaren Geschwindigkeiten durcheilen Computerclubs unser Da­tenverbundsystem.Einer dieser Com­puterclubs ist der CCC.Gigantischer Teil eines winzigen Sicher­heitssystems,das die Erde vor Bedrohungen durch den Gilb schützt.Begleiten wir den CCC und seine Mitglieder bei ihrem Patrouillendienst am Rande der Unkenntlich­keit. CCC'84 nach ORION'64"

  • Gibt es denn eine Art FLAG dass die GC des Systems gerade läuft oder DONE oder so :nixwiss:

    Die Frage hatte ich mir auch schon gestellt. Ich erinnere mich, bei meinen Vorrecherchen auf ein Flag gestoßen zu sein, das anzeigt, ob eine GC gerade frisch durchgeführt wurde und deswegen eine weitere überflüssig ist. Das hilft hier natürlich nicht weiter, aber vielleicht lässt sich etwas Ähnliches in dieser Art finden. Zumindest bin ich jetzt sensibelisiert für die Problematik.


    Allerdings könnte die Interrupt-GC ja auch in ganz normale String-Operationen des Hauptprogramms reinknallen. Das lässt es dann wirklich schwierig werden ... ;(

  • Nit-Picking: Im BASIC-Interpreter findet das Abfragen der Wirkung der STOP-Taste wirklich nur an dieser Stelle statt.

    Für LOAD und SAVE hat der KERNAL (!) aber noch zusätzliche Abfragen eingebaut. Streng genommen ist es also keine Ausnahme, weil die Unterbrechung nicht im BASIC-Interpreter stattfindet. ;)


    Diese Debugging-Möglichkeiten wären mit einem Variablenspeicher, auf dem gerade eine Garbage-Collection arbeitet, ein sehr interessantes (heißt: schwieriges) Unterfangen.

    Wirklich? Die Original-GC verschiebt, passt Pointer an, und dann wird der nächste String gesucht. Vor der Suche des nächsten Strings könnte sehr wohl eine Unterbrechung stattfinden, weil der Speicher in einem konsistenten Zustand ist.


    Problematisch ist vielmehr der Aufruf, der zur GC geführt hatte: Da sollte ja offenbar eine String-Operation stattfinden. Diese wäre zu dem Zeitpunkt inkonsistent.

    Bis auf CONT sollte aber alles von dir benannte soweit funktionieren.

    Vielleicht könnte man CONT sogar noch irgendwie retten, aber das wäre tatsächlich etwas mehr Aufwand.

  • Ich halte es durchaus für sinnvoll, von Zeit zu Zeit eine kontrollierte Garbage Collection auszulösen, bervor der Müllberg so groß ist, dass sie automatisch in Gang gesetzt wird und dabei evtl. schmerzhaft auffällt.

    Wie lange die Garbage Collection braucht, ist in erster Linie von der Anzahl der tatsächlich genutzten Strings abhängig, nicht von der Menge des "Mülls". Man will die also wirklich eher nur so selten wie möglich aufrufen.


    In der Praxis fällt die GC aber erst so richtig ab sagen wir mehr als 100 Strings auf (dann braucht sie etwa eine Sekunde, bei 200 Strings vier Sekunden etc.). Hier im Forum wird gerne übertrieben, und überhaupt sollte man das eigene Programm überdenken, wenn man so viele aktive Strings hat...


    Steht alles auch auf

    https://www.c64-wiki.de/wiki/Garbage_Collection

  • Das war eine der ersten Adressen, bei denen ich meine Recherche angefangen habe. Und unter anderem dort bin ich auf diese Aussage gestoßen:


    "Die Garbage Collection kann kaum durch Programmierstil und -techniken beeinflusst, geschweige denn dauerhaft verhindert werden. Der Einsatz der GC kann lediglich durch das Vermeiden gewisser String-Ausdrücke hinausgezögert, durch möglichst geringe Anzahl von Strings in Variablen und Arrays in der Laufzeit geringer gehalten und zu gewissen Zeitpunkten kontrolliert ausgelöst werden."


    Ich beziehe mich auf den letzten Punkt in dieser Aufzählung. Selbstverständlich nutze ich so viele Konstanten und so wenig dynamische Strings wie möglich und manipuliere Strings wo es sich anbietet durch Direktzugriffe. Und eine Aktivierung des Bildschirmschoners kommt ja auch eher selten vor.


    Aber wie gesagt, das Thema hat sich ja aus anderen Gründen erledigt. Ich beschränke mich auf das Ausschalten der Bildschirmanzeige. Die Röhre wird's mir danken.

  • Ja den Artikel hatte ich schonmal etwas versucht zu entschärfen, aber da waren sich die Wiki-Autoren dann nicht einig.


    Ich wäre durchaus interessiert, welches nicht völlig kaputt implementierte Programm am C64 mehr als ein paar dutzend dynamische Strings aktiv hat.


    Gold Quest 6 z.B. ist nun wahrlich kein kleines Programm, da wird auch ständig die GC angestoßen. Merkt niemand, weil die eben doch in dem Rahmen fix läuft.

  • Nur weil man keine Taste drückt, heißt das nicht, dass der c64 nichts tut. Es kann sein, dass z.b. basic gerade beim Abarbeiten eines Programms ist (und dabei die GC loslegt) und der User vorher halt aus dem Zimmer ist, weil Kaffee kochen oder ähnliches.;)


    Es soll ja auch Programme geben, die von sich aus die GC provozieren, damit es keine Wartezeiten gibt.


    Edit: schon erledigt. Daher Beitrag bitte ignorieren.