Betriebssystemtechnik (OSE) - SS 2003
Aufgabe 1: OSE-I/O-Library
In dieser Aufgabe soll eine im Speicherplatzverbrauch skalierbare
Bibliothek zur formatierten Ausgabe von Zeichen, Zeichenketten, Ganzzahlen und
Zeigern erstellt werden.
Ausgabetermin |
Vorgabe |
(spätester) Abgabetermin |
18.04.2003 |
OSE_Vorgabe1.tgz |
02.05.2003 16:00 |
Bearbeitung und Abgabe
Die Bearbeitung der Aufgabe soll wie angekündigt in einer
Dreiergruppe erfolgen. Spätestens jetzt solltet ihr euch also eine
Gruppe suchen. Die Abgabe der Aufgabe erfolgt bei Olaf im
Büro durch ein Mitglied der Gruppe. Wir werden uns dann
per ssh
im CIP Pool anmelden, wo eurer
funktionstüchtiges Implement abgabereif liegen sollte.
Dann müsst ihr mir auch die Gruppenzusammensetzung mitteilen.
Bitte beachtet die unten genannten Anforderungen an den
Speicherplatzverbrauch!
Vorgabe
Die Vorgabe umfasst einen Verzeichnisbaum, in dem ihr eure Entwicklung
durchführen könnt. Die Makefiles sind für die Anwendung
auf den Debian/Linux PCs im CIP Pool gedacht. Wer zu Hause arbeiten
will, muss sie anpassen.
Des weiteren umfasst die Vorgabe drei Testprogramme
test1.cc
bis test3.cc
mit deren Hilfe ihr am
Ende die Skalierbarkeit der Bibliothek nachweisen sollt.
Zur Erstellung der Bibliothek wird im Makefile das Programm
sosp
aufgerufen. Dieses Programm zerlegt den Quellcode,
so dass pro Objektmodul nur noch eine Funktion enthalten ist. Damit
wird das Binden auf Funktionsebene ermöglichst, das sonst mit den
GNU Entwicklungswerkzeugen noch nicht möglich ist. Zudem
implementiert sosp
zusammen mit einigen Skripten (beides
findet man im CIP Pool unter /proj/i4bs/tools/Sosp
) eine
globale Strategie für das "inlining", d.h. die Einbettung von
Funktionsrümpfen an der Aufrufstelle. Leider schränkt
sosp
den nutzbaren Sprachumfang von C++ ein wenig
ein. Mehr dazu weiter unten.
Die einzige vorgegebene C++ Klasse ist OStreamDock
. Sie
hat eine Methode void out(char)
, die mit Hilfe des
Systemaufrufs write()
implementiert wird. Alle
Aufgabefunktionen der zu erstellenden Bibliothek sollen darauf
aufsetzen.
Funktionsumfang
Bei der "I/O-Library" sind lediglich Funktionen zur Ausgabe
bereitzustellen. Eingabefunktionen sind nicht
nötig. Außerdem werden auch Fließkommazahlen nicht
unterstützt.
Wie man den drei Testprogrammen ansieht, sollen Anwendungsprogramme
die Bibliothek mit Hilfe des Datentyps OutputStream
aus
"OutputStream.h"
nutzen. Der Typ stellt die von
cout
her bekannten Ausgabeoperatoren operator <<
für Zeichen, Zeichenketten, Ganzzahlen und Zeiger
zur Verfügung. Ob die Funktionen dieses Typs vielleicht
aus Basisklassen geerbt werden oder mit Hilfe von Hilfsklassen
implementiert werden, bleibt euch überlassen.
Neben den Ausgabeoperatoren, sollen folgende Methoden auf einem
OutputStream
-Objekt anwendbar sein:
void width (int) |
Setzt die Feldbreite für die nächste Ausgabe. |
void fill (char) |
Setzt das Füllzeichen, das ausgegeben wird, wenn das
Ausgabefeld aufgefüllt werden muss (Default: Leerzeichen) |
void left () |
Ausgaben sollen ab sofort im Feld linksbündig erfolgen |
void right () |
Ausgaben sollen ab sofort im Feld rechtsbündig erfolgen |
void showbase (bool) |
Stellt ein, ob bei Integer-Zahlen die Basis ausgegeben wird ("0x"
bei Basis 16, "0" bei Basis 8, "%" bei Basis 2) |
Die Funktionen orientieren sich an der C++ Standardbibliothek. Neben
den Ausgabeoperatoren und den hier genannten Funktionen sind die
bekannten Manipulatoren hex
, bin
,
dec
und endl
zu implementieren.
Speicherplatzverbrauch
Die folgende Tabelle zeigt den Speicherplatzverbrauch der drei
Testprogramme (size test?
) in meiner Implementierung und
den von eurer Implementierung nicht zu überschreitenden Wert
(Angaben in Bytes).
Testprogramm |
Musterlösung |
Obergrenze |
test1 |
263 |
400 |
test2 |
576 |
800 |
test3 |
1544 |
2000 |
Tipps
Um diese harten Anforderungen bzgl. des Speicherplatzverbrauchs zu
erfüllen, sind folgende Hinweise vielleicht hilfreich:
- Virtuelle Funktionen sind zu vermeiden
- Die Aufrufbeziehungen so ordnen, dass möglichst viel
unbenutzte Funktionalität durch das "function-level linking" rausfällt.
- Wo das "function-level linking" nicht reicht, kann man auch
anwendungsspezifisch konfigurieren.
- Mit konfigurierbaren Klassen (typedefs, die eine bestimmte
Variante einer Klassenimplementierung wählen)
- Mit #ifdefs innerhalb des Codes
Hinweise zu SOSP
Zu beachten ist, dass bei Verwendung von sosp
für
jede Klasse zwei Dateien anzulegen sind:
- "Include/Klassenname.h": Klassendefinition mit Deklarationen der
Methoden
- "Source/Klassenname.cc": Implementierungen der Methoden
Die Trennung von Methodendeklarationen und -implementierungen ist
wichtig! |
Folgende C++ Spracheigenschaften werden zur Zeit von
sosp
nicht unterstützt:
Daneben kann der Parser sich auch schon mal bei ganz "normalem" Code
verhaspeln. Dann hilft manchmal, diesen Code vor dem SOSP Parser zu
verbergen:
#ifndef __puma
// Schwieriger Code ...
#endif // __puma