Ein mehrf adiger Java-Mikrocontroller f ur eingebettete Systeme 1

Werbung
Ein mehrfadiger Java-Mikrocontroller fur
eingebettete Systeme
U. Brinkschulte, C. Krakowski
Institut fur Prozerechentechnik,
Automation und Robotik
Universitat Karlsruhe
D-76128 Karlsruhe
J. Kreuzinger, Th. Ungerer
Institut fur Rechnerentwurf
und Fehlertoleranz
Universitat Karlsruhe
D-76128 Karlsruhe
In der vorliegenden Arbeit werden der Einsatz von Java in eingebetteten Systemen analysiert und Techniken fur eine echtzeitfahige Behandlung mehrerer sich uberlappender Ereignisse durch JavaThreads vorgeschlagen. Diese Techniken werden hardwaremaig
durch einen mehrfadigen Java-Mikrocontroller unterstutzt.
1 Einleitung
Der Markt fur eingebettete Systeme ist einer raschen Ausdehnung unterworfen. Als Folge hiervon verfugen Mikrocontroller derzeit uber eine groere Zuwachsrate als Mikroprozessoren. Schatzungen zufolge wird um das Jahr 2000
das durchschnittliche Haus in den USA 50 bis 100 Mikrocontroller umfassen.
Daruber hinaus wird es Millionen von Handies, Set-top-Boxen, Personal digital
assistants, Netzwerkterminals und weitere Internet-Gerate geben, die in einer
Netzwerkumgebung arbeiten und fur spezische Anwendungen optimiert sind.
Auch im Bereich der Automatisierungstechnik werden eingebettete Systeme zunehmend untereinander vernetzt. Ein wesentliches kunftiges Merkmal solcher
Systeme ist die Notwendigkeit zur umfassenden Ferndiagnose und Fernwartung.
Aus diesen Grunden wird in letzter Zeit zunehmend der Einsatz von Java Softund Hardware fur eingebettete Systeme untersucht.
Die objektorientierte Sprache Java [1] war zunachst als Sprache fur eingebettete Systeme konzipiert, bevor der Aspekt der Internet-Unterstutzung den Vorrang erhielt und dadurch die schnelle Verbreitung von Java hervorgerufen wurde. Die Objektorientierung von Java fuhrt zu einer einfachen Programmierung,
klaren Schnittstellen und unterstutzt die Wiederverwendbarkeit von Software
sowie die Entwicklung robuster Programme. Es existiert eine sehr umfangreiche,
genormte Klassenbibliothek. Java Bytecode ([2], [3]) ist die Java Maschinensprache der Java Virtual Machine (JVM). Java Bytecode ist rechnerunabhangig, er
kann problemlos auf alle Arten von Prozessoren geladen werden. Dieser Aspekt
ist insbesondere fur die Fernwartung und -diagnose in eingebetteten Systemen
von groer Bedeutung. Durch den Bytecode-Verier konnen Java Programme
sicher verwendet werden, d.h. ein Mibrauch auf dem ausfuhrenden Rechner
durch ein fehlerhaftes oder mibrauchlich verandertes Programm wird verhindert.
Eine spezielle Anforderung an eingebettete Systeme in der Automation ist
die Echtzeitfahigkeit. Die hier vorgestellte Arbeit betrachtet den Einsatz von
Java sowie spezieller Java-Hardware fur eingebettete Systeme in der Automa-
tion. Wesentlicher Schwerpunkt ist hierbei die echtzeitfahige Behandlung konkurrierender Ereignisse aus Sicht von Java Hard- und Software. Hierauf aufbauend wird die Konzeption einer Architektur und Mikroarchitektur fur einen
mehrfadigen Java-Mikrocontroller vorgestellt.
2 Java und Echtzeit
Fur den Bereich der Echtzeitsyteme ist Java in seiner ursprunglichen Form
zunachst wenig geeignet [4]. Die Sprache enthalt zum einen keinerlei Konstrukte zur Denition von Echtzeitbedingungen fur die Programmausfuhrung, zum
anderen ist die Ausfuhrungsgeschwindigkeit in vielen Java-Implementierungen
durch Interpretation des Java Bytecode sehr langsam bzw. durch Just-in-timeCompiler und Speicherbereinigung wenig vorhersagbar. Um diese Nachteile zu
beseitigen, gibt es eine Reihe von Losungen:
Im einfachsten Fall wird die Sprache Java in hybrider Form mit einem Echtzeitbetriebssystem kombiniert. Beispiele hierfur sind JWorks von WindRiver [5],
Java auf OS-9 [6] oder JavaOS [7]. Die Vorteile von Java werden hierbei fur die
nicht echtzeitkritischen Anwendungsteile eingesetzt, wahrend echtzeitkritische
Anwendungsteile in konventioneller Form, z. B. in C, realisiert werden und als
Echtzeit-Tasks auf dem Echtzeitbetriebssystem ablaufen. Java selbst ist hierbei
jedoch nicht echtzeitfahig.
Weitergehende Losungen bestehen darin, Java selbst echtzeitfahig zu machen. Hierbei konnen zwei Typen unterschieden werden:
Der erste Typ basiert auf einer echtzeitfahigen Java Virtual Machine (JVM).
Diese ist in der Lage, Java Bytecode echtzeitfahig auszufuhren. Minimal notwendig ist hierzu eine echtzeitfahige Speicherbereinigung sowie die echtzeitfahige
Ausfuhrung von Java Threads. Dieses Ziel wird z. B. in der in [8] beschriebenen Realisierung von Java Realtime Threads verfolgt. Hier wird eine JVM
auf der Basis des RT-Mach Mikrokernels [9] realisiert. Java-Threads werden
auf RT-Mach Threads abgebildet, welche die Denition von Startzeit, Periode und Deadline fur einen Thread erlauben. Die Synchronisation zwischen
Threads wird auf Echtzeit-Mutexe abgebildet, welche Prioritateninversionen
durch Prioritatenvererbung vermeiden. Ein weiterer Vertreter dieses Typs ist
PERC [10]. PERC bietet verschiedene Klassen von Echtzeit-Tasks (periodisch,
spontan, sporadisch, fortlaufend) sowie Mechanismen zur Aushandlung und Reservierung von Ressourcen. Daruber hinaus besteht durch Spracherweiterungen die Moglichkeit zur zeitlichen Beschrankung von Code-Abschnitten sowie
die Denition atomarer Code-Abschnitte. Schlielich erlaubt PERC fur einen
eingeschrankten Sprachumfang eine Worst-case-Laufzeitanalyse. PERC erzeugt
annotierten Bytecode, der auf der echtzeitfahigen PERC Virtual Machine ausgefuhrt wird. Es besteht auch die Moglichkeit, diesen annotierten Bytecode ohne
Einhaltung der Echtzeitbedingungen auf einer beliebigen JVM auszufuhren.
Alle Losungen dieses Typs haben als gemeinsame Eigenschaft die Interpretation des Java Bytecode. Dies fuhrt jedoch im Vergleich zu konventionellen
Sprachen wie etwa C zu einer deutlich schlechteren Verarbeitungsgeschwindigkeit, welche insbesondere im Bereich der eingebetteten Systeme durch die dort
verwendete eher schwache Hardware problematisch ist.
Der zweite Typ von Systemen vermeidet diesen Nachteil, dadurch da Java Bytecode weiter auf Maschinencode u bersetzt wird. Ein Vertreter hiervon
ist JBed [11]. Hierdurch konnen Ausfuhrungszeiten erreicht werden, die durchaus im Bereich von C++ Programmen liegen. Durch die Umgehung des Java
Bytecode verlieren diese Systeme jedoch dessen wesentliche Vorteile von Plattformunabhangigkeit und Sicherheit. Will man den Bytecode beibehalten und
die Java-Klassen zur Laufzeit laden aber auch die Performance von compiliertem Code nutzen, gibt es zwei Moglichkeiten. Ein Just-in-time-Compiler fuhrt
die U bersetzung wahrend der Ausfuhrung durch. Dies ist jedoch durch mangelnde zeitliche Vorhersagbarkeit fur Echtzeitsysteme problematisch. Die zweite Moglichkeit besteht darin, die ganze Klasse nach dem Laden zu u bersetzen
(durch einen sogenannten Flash-Compiler). Dies fuhrt zu verbesserter Vorhersagbarkeit, bewirkt jedoch verlangerte Ladezeiten und im allgemeinen einen
\schlechteren" Code, da der Compiler auf dem eingebetteten System nicht so
gut optimieren kann. Daruber hinaus benotigen beide Varianten nicht unerheblich zusatzlichen Speicher, welcher gerade im Bereich der eingebetteten Systeme
meist knapp bemessen ist.
3 Java-Prozessoren
Java-Prozessoren konnen durch die direkte Ausfuhrung der Bytecode-Befehle
eine vergleichsweise schnelle Ausfuhrung mit geringem Speicherbedarf realisieren [12]. Durch die Spezialisierung des Prozessors auf die Sprache Java
konnen beim Entwurf Optimierungen entwickelt werden, die zu einer weiteren
Leistungssteigerung fuhren. Besonderheiten, die bei der Ausfuhrung von Java
auftreten, sind im wesentlichen die stack-basierte Verarbeitung der BytecodeBefehle und die Speicherbereinigung. Im picoJava I von Sun [13] wird daher
statt eines wahlfrei zugreifbaren Registersatzes ein Stack-Registersatz mit 64
Eintragen auf dem Chip integriert. Der Stack-Registersatz kann durch Methodenaufrufe und Operanden immer weiter wachsen und ist daher in seiner Groe
nicht begrenzt. Der Dribbler [14] ist ein Hardware-Mechanismus, der den aktuellen Fullstand des Stacks uberwacht und bei einem drohenden U berlauf Daten in
den Speicher auslagert. Umgekehrt werden beim Erreichen einer unteren Fullmarke die Daten wieder aus dem Speicher gelesen und auf dem Stack abgelegt.
Eine weitere Technik, die als Hardware-Optimierung von Sun eingefuhrt
wurde, ist das Folding. Bei einer Stackarchitektur bezieht sich jede Berechnung
auf die Operanden \oben" auf dem Stack, d.h., eine Addition nimmt zwei Operanden vom Stack, berechnet das Ergebnis und legt diese wieder auf den Stack.
Sind die Operanden nun lokale Variablen, liegen diese tief im Stack verborgen
und mussen erst durch einen speziellen Befehl auf den Stack geholt werden.
Gleiches gilt fur das Ergebnis, wenn es in einer lokalen Variablen abgelegt werden soll. Eine Addition zweier lokaler Variablen in eine lokale Variable benotigt
also vier Befehle. Das Folding kann diese Situation beim Decodieren erkennen
und einen RISC-ahnlichen Befehl mit Quell- und Zieloperanden daraus erzeugen, der nur einen statt vier Takte benotigt [15]. Diese Technik kann auch bei
weniger optimalen Fallen eingesetzt werden, wenn z. B. schon ein Operand auf
dem Stack zur Verfugung steht.
Zur Unterstutzung von Speicherbereinigungsalgorithmen, die mit mehreren
Speichersegmenten arbeiten (z. B. generationelle Speicherbereiniger), konnen
sogenannte Schreibbarrieren [15] in Hardware implementiert werden. Diese losen
eine Unterbrechung aus, wenn beim Schreiben von Daten eine Speicherreferenz
zwischen den Segmenten erzeugt oder verandert wird. Damit konnen die Wurzelzeiger, welche die Basis fur das Durchsuchen der Segmente nach benutzten
Speicherblocken bilden, akualisiert werden. Ohne Schreibbarrieren sind fur diese
U berprufung zusatzliche Befehle fur alle Schreibbefehle notig.
Sun gilt als Vorreiter im Bereich der Java-Prozessoren. Mit dem picoJava
I und II, microJava-701 und ultraJava sollen Java-Prozessoren angefangen von
eingebetteten Systemen bis hin zu Arbeitsplatzrechnern zum Einsatz kommen.
Das Interesse an Suns Technologie wird durch die Lizenzabkommen mit Fujitsu Limited, IBM Corporation, LG Semicon Co, Ltd. NEC Corporation und
Rockwell Collins, Inc. deutlich. Es ist daher zu erwarten, da sich die JavaProzessoren in naher Zukunft rasch verbreiten werden.
4 Ereignisbehandlung in eingebetteten Systemen
Eingebettete Systeme zeichnen sich unter anderem auch dadurch aus, da sie
in Umgebungen mit vielen synchronen und asynchronen Ereignissen operieren.
Eine wesentliche Anforderung an eingebettete Systeme ist eine schnelle Reaktionszeit auf Ereignisse innerhalb eines vordenierten Zeitfensters (Echtzeiteigenschaft).
Die Behandlung von Ereignissen (externe oder interne Signale) erfolgt bei
eingebetteten Systemen meist durch Interrupt-Service-Routinen (ISRs). Dabei
wird die momentane Programmausfuhrung unterbrochen, der Kontext gesichert
und die ISR gestartet. Die Kontextsicherung wird haug durch das Vorhandensein von mehreren Registersatzen beschleunigt. Ein paar Takte Kontextwechselaufwand werden jedoch fur den Aufruf trotzdem benotigt.
Treten mehrere Ereignisse zeitgleich auf, so werden diese nach Prioritaten
geordnet verarbeitet, d.h., die ISR des hochstprioren Ereignisses wird sofort
ausgefuhrt und die anderen mussen auf deren Ende warten. Dies entspricht
dem sogenannten Fixed-priority-preemptive-Scheduling, welches nur eine Prozessorauslastung von etwa 70% ermoglicht [16]. Desweiteren konnen nur fur das
Ereignis hochster Prioritat in jedem Fall Zeitschranken garantiert werden, Ereignisse niederer Prioritat konnen auf unabsehbare Zeit unterbrochen werden.
Fur dieses Problem gibt es mehrere Losungen:
1. Samtliche ISRs werden so kurz wie moglich gehalten, um Unterbrechungszeiten zu minimieren. Dies erfordert jedoch, da ein Groteil der Aktivitaten aus den ISRs in die normale Programmausfuhrung verlagert wird,
was zu erhohtem Kommunikationsaufwand, komplexer Programmierung
und schwierigen Tests fuhrt. Dieser Aspekt wirkt sich negativ auf die Zuverlassigkeit des Systems aus.
2. Der Einsatz eines Echtzeitbetriebssystems vereinfacht die Entwicklung,
kann jedoch bei kleinen Systemen durch die Lizenzgebuhren den Gesamtpreis erheblich erhohen. Dies ist bei hohen Stuckzahlen oft nicht akzeptabel. Desweiteren ist in diesem Fall mehr Speicher erforderlich.
3. Pro Ereignis mit Echtzeitbedingung wird ein eigener Mikrocontroller eingesetzt. Auch hier steigen die Kosten je nach Anforderung an den Mikrocontroller.
4. Pro Ereignis wird ein eigener Kontrollfaden ausgelost, der konkurrent
auf demselben Mikrocontroller ablauft. Schon in Bearbeitung bendliche
Kontrollfaden werden nicht unterbrochen, jedoch wird entsprechend der
Prioritat eine Ressourcenzuteilung auf der Ebene einzelner Prozessortakte durchgefuhrt. Diese Vorgehensweise entspricht der Proportional-share
Schedulingstrategie in Echtzeitbetriebssystemen [17].
Die vierte Variante stellt eine neue Technik dar. Hierbei werden ISRs durch
Interrupt Service Threads (ISTs) ersetzt. Dies ist jedoch nur auf mehrfadigen
Prozessoren moglich und wird im nachsten Abschnitt betrachtet.
Auf konventionellen Prozessoren besteht jedoch die Moglichkeit, diese Technik nachzubilden, indem eine ISR einen Betriebssystem-Thread zur Ereignisbehandlung startet. So erlaubt es z. B. der in [18] beschriebene AST-Mechanismus
(Asynchronous System Traps), ein asynchrones Ereignis an einen Proze weiterzuleiten. Ein Nachteil dieser und ahnlicher Software-Erweiterungen ist die
hohe Latenzzeit, die durch das Weiterreichen des Ereignisses entsteht.
Die hohen Latenzzeiten konnen durch die Behandlung der Ereignisse mit
ISTs, die direkt von der Hardware unterstutzt werden, vermieden werden, wenn
der Kontextwechsel zwischen den ISTs sehr schnell ist.
5 Die Architektur eines mehrfadigen Java-Mikrocontrollers
Die Idee, Echtzeitereignisse mit Threads zu behandeln, erfordert einen sehr
schnellen Kontextwechsel. Dies ist im allgemeinen nur mit einer mehrfadigen
Prozessorarchitektur moglich [19], wobei diese Technik bisher fast nur zur U berbruckung von Latenzen eingesetzt wurde. Ein mehrfadiger Prozessor kann Befehle mehrerer Threads gleichzeitig in der Prozessor-Pipeline ausfuhren. Er besitzt mehrere Befehlszahler und meist auch mehrere Registersatze, die den geladenen Threads zugeordnet sind, so da ein Kontextwechsel einfach moglich
ist.
Die Ausfuhrungs-Pipeline des mehrfadigen Java-Mikrocontrollers (siehe
Abb. 1) ist ahnlich der von Suns picoJava-I Prozessor:
Befehl holen,
Befehl decodieren und Operanden bereitstellen,
Befehl ausfuhren bzw. Lade-Speicherzugri und
Resultat oder geladener Wert auf dem Stack ablegen.
Die Befehlsholestufe (instruction fetch) beinhaltet fur jeden der vier Threads
einen Befehlszahler (PC) mit zugehorigen Statusbits (z. B. Thread aktiv, PC
gultig). Anhand der Statusbits und den Fullstanden der Befehlsfenster wird
entschieden, u ber welchen PC neue Befehle geladen werden. Mit einem Takt
werden 4 Bytes uber die Speicherschnittstelle (memory interface) geholt und
in das entsprechende Befehlsfenster (IW) geschrieben. Da ein Bytecode-Befehl
im Durchschnitt 1.8 Byte lang ist, sind in den 4 Bytes meist mehrere Befehle
enthalten.
instruction fetch
address
PC1 PC2 PC3 PC4
memory interface
instructions
IW1 IW2 IW3 IW4
priority manager
micro-ops
ROM
data path
signal
unit
extern
signals
instruction decode
MEM
ALU
stack register sets
Abbildung 1: Struktur des Java-Mikrocontrollers
Zu der Decodierstufe (instruction decode) gehoren die bereits erwahnten Befehlsfenster, verschiedene Statusbits (z. B. Prioritat, letzter Befehlstyp) und Zahler fur die Anzahl Befehle pro Zeitscheibe zur Unterstutzung
des Proportional-share Schedulings. Der Prioritatenmanager bestimmt, in
Abhangigkeit von den Statusbits und Zahlern, von welchem der Befehlsfenster der nachste Befehl decodiert werden soll. Damit lassen sich verschiedene
Schedulingmechanismen (z. B. Fixed-priority, Proportional-share) implementieren. Ein Bytecode-Befehl wird je nach Komplexitat direkt oder in eine Sequenz
von Mikrobefehlen aufgelost, oder es wird eine Trap-Routine aufgerufen. Jeder
Befehl in der Pipeline ist mit einer Thread-Kennung versehen, damit Befehle
von unterschiedlichen Threads in der Pipeline gleichzeitig verarbeitet werden
konnen.
Befehle, die auf den Speicher zugreifen, werden von der Speichereinheit
(MEM) verarbeitet. Ist pro Takt nur ein Zugri u ber die Speicherschnittstelle
moglich, mu ein Arbiter den Konikt zwischen dem Holen der Befehle und dem
Datenzugri auosen. Alle anderen Befehle werden von der ALU ausgefuhrt.
Abschlieend werden die Ergebnisse oder geladenen Werte auf dem entsprechenden Stack abgelegt.
Externe Signale von Zeitgebern, seriellen Schnittstellen oder Peripheriegeraten werden u ber die Signaleinheit auf den Prozessorkern gebracht. Tritt
ein solches Signal auf, wird der zugehorige Interrupt-Service-Thread (IST) aktiviert und kann nun vom Prioritatenmanager ausgewahlt werden. Sobald die
Arbeit des IST vollendet ist, wird der zugehorige Echtzeit-Thread angehalten
und sein Status gesichert. Tritt das Signal erneut auf, wird er wieder aktiviert.
Damit keine Pipeline-Hemmnisse entstehen, konnen in jedem Takt Befehle
aus unterschiedlichen Threads in die Pipeline eingefuttert werden. Grunde fur
Leerlaufzeiten konnten Sprunge oder Speicherzugrie sein. Die Decodierstufe
kann anhand der Befehle solche Latenzen erkennen und mit einem anderen
Befehlsfenster fortfahren. Solch ein Kontextwechsel benotigt keinen zusatzlichen
Zeitaufwand. Es mussen weder Register gerettet oder geladen, noch Befehle aus
der Pipeline verworfen werden. Fur jeden Thread ist ein eigener Kontext auf
dem Prozessor vorhanden.
Hardwareoptimierungen wie sie von Sun vorgeschlagen werden (siehe Abschnitt 3) sollen bei diesem Entwurf ebenfalls zum Einsatz kommen. Der Dribbler kann jedoch nicht auf die Stack-Registersatze der Echtzeit-Threads angewandt werden, da er in seiner Arbeitsweise zeitlich nicht vorhersagbar ist.
6 Zusammenfassung
Java bietet durch seine Objektorientierung und den Bytecode viele Vorteile.
Beim Einsatz von Java in eingebetteten Echtzeitsystemen zeigt sich jedoch,
da interpretierter Bytecode in der Regel zu langsam ist und JIT-Compiler
zu viel Speicher benotigen und Antwortzeiten schwer vorhersagbar sind. Bei
vollcompilierten Losungen gehen die Vorteile des Java Bytecode verloren.
Diese Probleme sollen in einem dedizierten Systementwurf aus Anwendung, angepater Java-Umgebung und einem echtzeitfahigen, mehrfadigen
Java-Mikrocontroller untersucht werden. Statt Interrupt-Service-Routinen sollen Java-Threads als Interrupt-Service-Threads (ISTs) fur die Ereignisbehandlung eingesetzt werden.
Der vorgeschlagene Java-Mikrocontroller ist kompatibel zu Suns picoJava-I
gehalten, jedoch um Mehrfadigkeit, eine Signaleinheit und einen Prioritatenmanager erweitert. Derzeit wird der mehrfadige Java-Mikrocontroller in Software
simuliert und fur seinen Einsatz in einer eingebetteten Echtzeitumgebung getestet. Geplant ist eine Hardware-Realisierung auf einem FPGA-Board und sein
Einsatz in einem fahrerlosen Transportsystem (FTS).
Literatur
[1] D. Flanagan. Java in a Nutshell. OReilly, 2nd edition, 1997.
[2] J. Gosling. Java Intermediate Bytecodes. Sigplan Notices, 30, March 1995,
111-118.
[3] J. Meyer, T. Downing. Java Virtual Machine. OReilly, Cambridge, 1997.
[4] K. Nilsen. Java for Real-Time. Real-Time Systems Journal, 11(2), 1996.
[5] Wind River Systems. Tornado for Embedded Internet.
http://www.wrs.com/embedweb/html/white.html.
[6] Microware Systems Corporation. Java for OS-9.
http://spin.microware.com/html/wp index.html.
[7] Sun Microsystems. JavaOS for Consumers.
http://www.sun.com/javaos/consumers.
[8] A. Miyoshi, T. Kitayama, H. Tokuda. Implementation and Evaluation of
Real-Time Java Threads. IEEE Real-Time Systems Symposium, San Francisco, 1992.
[9] H. Tokuda, T. Nakajiama, P.Rao. Real-Time Mach: Towards a Predictable
Real-Time System. Proceedings of USENIX 2nd Mach Symposium, Oct.
1991.
[10] NewMonics, Inc. PERC Virtual Machine 1.0.
http://www.newmonics.com/WebRoot/perc.info/data.sheets/percvm.html.
[11] Cuno Pster, Oberon microsystems. JBed Whitepaper: Component Software and Real-Time Computing.
http://www.oberon.ch/rtos/whitepaper.
[12] P. Wayner. Sun Gambles on Java Chips. BYTE, November 1996, 79-88.
[13] Sun: Picojava-I Microprocessor Core Architecture. Sun Microsystems,
Hardware and Networking Microelectronic Whitepapers, WPR-0014-01,
1997.
[14] J. M. O'Connor, M. Tremblay. PicoJava-I: The Java Virtual Machine in
Hardware. IEEE Computer, March/April 1997, 45-53.
[15] H. McGhan, M. O'Conner PicoJava: A Direct Execution Engine For Java
Bytecode. IEEE Computer, October 1998, 22-30.
[16] C. L. Liu, J. W. Layland. Scheduling Algorithms for multiprogramming in
a hard real-time environment. JACM, 20(1), 46-61, 1973.
[17] I. Stoica, H. Abdel-Wahab, J.E. Gehrke, K. Jeay, S. K. Baruah, C.
G. Plexton. A Proportional Share Resource Allocation Algorithm for RealTime, Time-Shared Systems. Proceedings of the 17th IEEE Real-Time Systems Symposium Washington, DC, December 1996 pages 288-299.
[18] Digital Equipment Corporation. Guide to DECthreads. Digital Equipment
Corporation, March 1996.
[19] J. Silc, B. Robic, T. Ungerer. Processor Architecture: From Dataow to
Superscalar and Beyond. Springer-Verlag, Heidelberg, 1999.
Herunterladen