[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1 Hintergrundinfos


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.1 Zusammenarbeit mit anderen Programmen

RSYS’ wurde unter Berücksichtigung aller mir bekannten Richtlinien der Programmierung unter AmigaOS 2.0 geschrieben. Alle kritischen Routinen wurden bis zu dreimal abgesichert. Das bläht zwar etwas den Code, gewährleistet aber die Lauffähigkeit auch unter Betriebssystemen >= 2.04.

Besonderer Wert wurde auf die Vermeidung von Speicherfehlern und ‘Enforcer’-Hits gelegt. Bei einem auftretenden Speicherfehler wird in den meisten Fällen das Programm unter Angabe von Quelldatei- und Funktionsname, sowie der Zeilennummer im Quelltext abgebrochen und beendet.

RSYS’ ist darauf ausgelegt, mit allen Programmen so gut wie möglich zusammenzuarbeiten. Das schließt jedoch die Programme aus, die von Haus aus Hacks sind, die sich nicht an die Programmierrichtlinien unter AmigaOS halten. Weiterhin hat ‘RSYS’ keinerlei Problem mit systemkonformen Patches, wie z.B. ‘MagicMenu’ von Martin Korndörfer, oder ‘MFR’ von Stefan Stuntz.

Viele Leute haben mich per EMAIL angeschrieben, daß ich doch bitte OS 3.0-Features verwenden soll. ‘RSYS’ soll eigentlich unter allen Systemen >2.0 laufen, weswegen ich spezielle Features von 3.0 absichtlich vermieden habe. Ausnahmen bilden jedoch einige verwendete Tags, wie z.B. die GTM_NewLookMenus, das die Standard-3.0-Menüfarben einstellt. Diese werden von OS 2.x-System ignoriert, womit also dem Einbau nichts im Wege stand.

Ein weiteres Feature von OS 3.0 ist die Routine GT_GetGadgetAttrsA der ‘gadtools.library’. Damit wird eine vollständige Steuerung der ListView-Gadgets über Pfeiltasten ermöglicht. Diese ist jedoch unter 2.x noch nicht implementiert, sodaß auch dieses Feature in ‘RSYS’ aus Gründen der Kompatibilität nichts zu suchen hat.


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.2 Systemlisten und Schutzprotokolle

Intuition-Objekte werden beim Auslesen der Daten mit dem Protokoll LockIBase() / UnlockIBase() geschützt. Damit werden die jeweiligen Listen vor der Veränderung durch Intuition-Routinen während des Auslesens ausreichend geschützt. Bei der Veränderung der Objekte durch ‘RSYS’ ist selten ein Schutzprotokoll erforderlich, da die Routinen von Intuition dieses meistens selbst erledigen.

Alle Exec-Objekte, wie Tasks, Ports, Libraries, etc., werden während des Auslesens durch ein Forbid()/Permit(), im Falle von Tasks, sogar durch ein Disable()/Enable() vor Veränderung durch Systemroutinen geschützt. Im Falle der Tasks ist zum Auslesen der Taskzeiger das Protokoll Disable()/Enable() zu verwenden, zum Auslesen der Taskstruktur reicht jedoch ein Forbid()/Permit().

Disable()/Enable() sollte deswegen verwendet werden, da die Systemliste in der ExecBase durch den interruptgesteuerten Task-Scheduler laufend in ihrer Anordnung geändert wird (man denke nur an die Aktivierung eines Tasks, also die Umsetzung des entsprechenden Taskknotenzeigers aus der Wait-Liste in die Ready-Liste und dann in den Running-Zustand [ExecBase->ThisTask-Eintrag]).

Die Task-Struktur selber kann jedoch nur von einem Task oder Prozeß aus verändert werden. Daher reicht zum Auslesen der Taskstruktur das Protokoll Forbid()/Permit() aus. Daraus ergibt sich also folgendes Schema:

   Reservieren der eigenen Struktur-Speicherbereiche

   Forbid();

      Disable();
      Auslesen und Merken der Tasknodes
      Enable();

      Auslesen der Taskstrukturen in eigene Strukturen (ohne
      Verwendung von DOS-Routinen, also KEIN FGets(), Open() etc.)

   Permit();

   Auswerten der eigenen Strukturen
   Freigeben der eigenen Struktur-Speicherbereiche

Für die Implementation dieser Routinen könnt Ihr den dokumentierten Quelltext einsehen.

Unter diesen Vorsichtsmaßnahmen sollte es keine Probleme im Zusammenspiel mit anderen Programmen geben, bis auf eine Einschränkung: ‘RSYS’ kann nicht mit Programmen zusammenarbeiten, die nicht systemkonform programmiert wurden. Beispiele dafür sind Programme, die beispielsweise den Namen eines öffentlichen Ports nicht korrekt initialisieren. So kommt es beispielsweise vor, daß ein Programm zwar einen Zeiger auf einen Portnamen ungleich Null hat, diesen Zeiger aber uninitialisiert läßt und dieser dann folglich irgendwohin zeigt. Die Folge ist im harmlosesten Fall ein ‘Enforcer’-Hit des Typs READ-BYTE (beim Auslesen des vermeintlichen Strings), im extremsten Fall ein Guru!

Ich habe das Problem jetzt so gelöst, daß ich bei den auszulesenen Node-Namen das Typen-Flag untersuche. Steht dort der Eintrag NT_UNKNOWN oder nicht das erwartete Flag, lese ich den String einfach nicht aus, sondern trage in das ListView

   <wrong type:0>

ein. Hierbei steht die 0 für den ermittelten Knotentypen. Die möglichen Knotentypen sind:

 Wert       Typ
------------------------------------------------------
   0        Unbekannter Node-Typ
   1        Task
   2        Interrupt
   3        Device
   4        Message Port
   5        Message
   6        freie Message
   7        Message wurde beantwortet
   8        Resource
   9        Library
  10        Memory-Node
  11        Softinterrupt
  12        Font
  13        Prozeß
  14        Semaphor
  15        Signalsemaphor
  16        Boo-Node
  17        Kick-Memory-Node
  18        Graphics-Node (Monitor-Node z.B.)
  19        Death Message (eine tote Nachricht)
 254        Benutzerdefinierter Node
 255        Erweiterung (auch benutzerdefiniert)

Manche Systemutilities (z.B. ARTM) achten darauf nicht und produzieren ‘Enforcer’-Hits en mas. Diese Fehler lassen sich auch nicht vermeiden. Der Aufwand dafür wäre einfach zu groß, da man ja praktisch Teile des Programms ‘Enforcer’ in das eigene Programm implementieren müßte. Solange man nicht davon ausgehen kann, daß JEDER Programmierer systemkonform programmiert, wird es diese Lücke auch weiterhin geben.

Ein weiterer typischer Fehler ist die Verwendung der Compiler-Funktion strcpy() auf Quellstrings vorher unbekannter Länge. Viele Programmierer verwenden diese Routine, um schneller Strings zu kopieren. Dabei wird nicht beachtet, daß man eventuell gar nicht soviel Speicherplatz reserviert hat, um den Quellstring aufzunehmen. Ein signifikantes Beispiel dafür ist das o.g. Port-Namen-Problem. Ist der String uninitialisiert und nicht mit ASCII 0 terminiert, kopiert strcpy() einen solchen Portnamen bis in alle Ewigkeit, bis zum Ende des Speichers, bis zur nächsten Einsprungadresse eines anderen Tasks oder bis zur nächsten Reise von Indian tours :-) Manche Programmierer sagen sich dann, überprüfen wir doch einfach mit strlen() den Quellstring. Nun, da strlen() auch solange zählt, bis ASCII 0 erkannt wurde, ist diese Methode auch für eine Auslandsreise nach Indien durchaus geeignet.

Das einfachste und probateste Mittel in diesem Fall, ist die Compiler-Funktion strncpy(). Damit kann man einfach festlegen, wieviel Zeichen denn nun kopiert werden sollen. Das einzige, was jetzt noch stört, ist der READ-BYTE-Hit den man bekommt, wenn man merkwürdige Adressen an strncpy() übergibt.

Ein weitere Fehlerquelle ist die Verwendung von printf() in allen seinen Erscheinungsformen (sprintf(), vsprintf() etc.) im Zusammenhang mit Systemlisten. Da die printf()-Routinen auch auf DOS-Routinen zugreifen, sind sie zum zügigen Kopieren von mehreren Systemeinträgen ungeeignet. Die Routine RawDoFmt() der Exec-Library ist jedoch sicher. Mit ihr kann man sich selbst ein sprintf() zusammenbauen, was ich auch getan habe. Normalerweise befindet sich aber diese Routine in der ‘amiga.lib’.

Sicher ist weiterhin die Verwendung der str...()-Routinen zwischen Schutzprotokollen, da diese nur Speicherbereiche kopieren oder verschieben. Möchte man es trotzdem noch schneller haben, gibt es noch die Funktionen CopyMem() und CopyMemQuick(). Bei letzterer ist zu beachten, daß die Daten auf longwords ausgerichtet sein müssen. Beide Routinen gehören zur ‘exec.library’, können also bei Systemlistenuntersuchungen verwendet werden.


[Top] [Contents] [Index] [ ? ]

About This Document

This document was generated on February 6, 2023 using texi2html 5.0.

The buttons in the navigation panels have the following meaning:

Button Name Go to From 1.2.3 go to
[ << ] FastBack Beginning of this chapter or previous chapter 1
[ < ] Back Previous section in reading order 1.2.2
[ Up ] Up Up section 1.2
[ > ] Forward Next section in reading order 1.2.4
[ >> ] FastForward Next chapter 2
[Top] Top Cover (top) of document  
[Contents] Contents Table of contents  
[Index] Index Index  
[ ? ] About About (help)  

where the Example assumes that the current position is at Subsubsection One-Two-Three of a document of the following structure:


This document was generated on February 6, 2023 using texi2html 5.0.