3.2 Prozessumschaltung (dispatching) deaktiviert einen Prozess und aktiviert einen anderen. Wann? aktiver Prozess wird vom Prozessor verdrängt zugunsten eines bereiten Prozesses aktiver Prozess blockiert, und somit kann ein bereiter Prozess aktiviert werden aktiver Prozess wird vom Prozessor verdrängt zugunsten eines aufgeweckten Prozesses mit höherer Priorität bs-3.2 1
Die Bereitliste und ihre Operationen: class ReadyList implements Set<Process> {... interface Set<T> { // set of T items, initially empty public void add(t item) {... // enter item into set public T remove() {... // remove and deliver some set element, // if set not empty (else deliver null) bs-3.2 2
Prozessumschaltung, nachdem der zu deaktivierende Prozess bereits wieder in eine Prozessliste (Warteliste oder Bereitliste) eingetragen wurde: static final int timeslice =...; static void dispatch() { current.incruntime(timeslice - GETTIMER()); previous = current; current = readylist.remove(); if(current!= previous) switch(); SETTIMER(timeSlice); mit folgender Prozedur switch, die den notwendigen Kontextwechsel (context switch) bewirkt: bs-3.2 3
static void switch() { previous.status = SAVESTATUS(); LOADSTATUS(current.status);! Pseudocode switch entspricht dem resume für Koroutinen (ALP 4 ), notwendigerweise in Assembler programmiert Im einfachsten Fall (ohne Berücksichtigung von Prozessormodus, Adressraum,...) ändert sich beim Wechsel des Prozessorstatus nur der Kellerzeiger (stack pointer)! bs-3.2 4
Für diesen Fall sieht switch so aus:...; load address of current.status into EAX...; load address of previous.status into EBX MOV 0(EBX), ESP ; SAVE STACK POINTER MOV ESP, 0(EAX) ; LOAD STACK POINTER Beachte: während der Ausführung von dispatch darf der Prozessor nicht unterbrechbar sein (weil die Unterbrechungsbehandlung selbst zu einem dispatch führt! 3.5) bs-3.2 5
Prozess P (previous), noch aktiv! Prozess Q (current) P-SP Q-SP P code P stack Q stack Q code CALL dispatch CALL dispatch SP (stack pointer register) dispatch bs-3.2 6 PC (program counter register)
3.2.1 Zeitscheibenverfahren Aktiver Prozess wird vom Prozessor verdrängt zugunsten eines bereiten Prozesses: typischerweise nach Ablauf einer bestimmten, dem Prozess zugeteilten Zeit, genannt Zeitscheibe (time slice) (z.b. 10 ms), deren Ablauf gemeldet wird durch Zeitgeberunterbrechung (timer interrupt) bs-3.2 7
Zeitgeberunterbrechung bewirkt unerwarteten Prozeduraufruf (unexpected/implicit procedure call) ( 3.5.1): die Unterbrechungsbehandlung aktiviert die folgende Methode in Process: static void timesliceend() { readylist.add(current); dispatch(); (alles mit Unterbrechungsunterdrückung - vgl. S. 5) bs-3.2 8
3.2.2 Blockieren Wenn aktiver Prozess blockiert (typischerweise in einer Synchronisationsoperation), kann ein bereiter Prozess aktiviert werden: void block() { // only meant for use by active process: // Process.current.block(); blocked = true; dispatch(); (ähnelt dem sleep im Unix-Kern) (alles mit Unterbrechungsunterdrückung - vgl. S. 5) bs-3.2 9
3.2.3 Aufwecken Dabei wird der aufweckende Prozess eventuell vom Prozessor verdrängt zugunsten eines aufgeweckten Prozesses mit höherer Priorität: void wake(){ // unblock & put in ready list blocked = false; readylist.add(this); readylist.add(current); dispatch(); (alles mit Unterbrechungsunterdrückung - vgl. S. 5) bs-3.2 10
3.2.4 Mehrprozessorsysteme Symmetrische Mehrprozessorsysteme (SMP) erfordern nur leicht geänderte Verwaltung (3.1 ) der aktiven und bereiten Prozesse bei n Prozessoren so: public static Process current(){ return current[processor_id()]; static Process[] current = new Process[n]; // at system startup time: establish n idle processes: static { for(int i=0; i<n; i++) current[i] = new Process(); while(true) ; // idle Nummer des ausführenden Prozessors bs-3.2 11
Ferner: alle Process Operationen mit Sperren für wechselseitigen Ausschluss versehen: static boolean lock; // spin lock (ALP 4 ; 3.4.2) void block() { LOCK(lock); blocked = true; dispatch(); UNLOCK(lock);... und die anderen Operationen entsprechend bs-3.2 12
Achtung: Wenn ein aufgeweckter Prozess einen der n aktiven Prozesse verdrängt, wird dieser i.a. in einem anderen Prozessor laufen wie wird dann verdrängt? Hardware stellt inter-processor interrupt zur Verfügung, der ähnlich wie die Zeitgeberunterbrechung behandelt wird: static void interprocint() { LOCK(lock); readylist.enter(current()); dispatch(); UNLOCK(lock); (alles mit Unterbrechungsunterdrückung - vgl. S. 5) bs-3.2 13
Auslösung dieser Unterbrechung durch modifiziertes wake : void wake(){ LOCK(lock); blocked = false; readylist.enter(this); readylist.enter(current()); if((p=victim())!= -1) INTERRUPT(p); dispatch(); UNLOCK(lock); prüft, ob bei einem Prozessor p verdrängt werden muß (alles mit Unterbrechungsunterdrückung - vgl. S. 5) bs-3.2 14