Datalogi 1F: Multiprogrammering[3] 1 Planen for idag Kerner uden afbrydelser (KB4 kap. 6): –akernen: kerne med decentralt processkift –bkernen: kerne med.

Slides:



Advertisements
Lignende præsentationer
Hvordan programmerer man?? STREAM - en model. Programmører arbejder ofte i teams Hver programmør arbejder på sin del af en større helhed.
Advertisements

Udlægning af en ny cache
OS[2]: Processor, tråde og skedulering
07 – Kort om OO Introduktion.
Computerens anatomi! Hvad skal du vide før du køber din egen?
T1 – OPGAVE 14.2 LINETT & SABRINA Klasse Varer namespace Opgave_14._2 { class Varer { private string vare; private string farve; private double.
1 Pentium IA-32 Maskinarkitekturen Kort resume – uge 5.
Almindelige ("hårde") links (i filsystemer med i-noder) opg.txt jens: pia: ln /home/pia/opg.txt /home/jens/opg.txt hård link: ny post får i-node-nummer.
Symbolsk maskinsprog.
Datastrukturer Simple-type structs
Multiprogrammering[1]: Ydre enheder og multiprogrammer Datalogi 1F: Forår 2003 Jørgen Sværke Hansen
Flerbrugermaskine Fælles maskine Root: webserver Peter: uploader filer Pia: programudvikling 1 langvarig proces, evt. med børneprocesser skiftende behov.
Første generation (maskiner/operativsystemer) 45-55: radiorør Kun maskinsprog programmering = skrivning af nullerog ettaller Intet operativsystem programmør.
DS-kursusgang nr. 4 IPC generelt IPC eksempel: beskedkøer IPC tidsforbrug: kontekstskift, skedulering C: abstraktion, funktionsbiblioteker.
Structs Structs allokeres på stakken Memory-allokering sker ved oprettelse af variabel og ikke ved new Der kan defineres metoder incl. Constructor. Eksempel.
Multiprogrammering[2] Datalogi 1F Forår 2003 Synkronisering og grænseflader Jørgen Sværke Hansen
Datalogi 1F: Multiprogrammering[2]
Datalogi 1F: Multiprogrammering[4] 1 Planen for i dag Repetition af kerner med afbrydelser Kerner med tvungent processkift Præsentation af K1.
Hvorfor trådning? Performance Responsivness. Succeskriterier Forbedring af performance –Opgaverne skal være uafhængige –Jo flere afhængige opgaver, jo.
GP 10, 7/ Grundlæggende programmering Efterår 2001 Forelæsning 10 onsdag 7/ kl. 9:15 – 12:00.
Operativsystemer [3]: Synkronisering og baglåse Datalogi 1F: Forår 2003 Jørgen Sværke Hansen
FEN IntroJava AAU1 Java grundelementer Variable og datatyper Sætninger og udtryk Metoder.
Datalogi 1F Forår 2003 Multiprogrammering[4] Kerner og processer Jørgen Sværke Hansen
Datalogi 1F Forår 2003 G1 Jørgen Sværke Hansen
Anvendelser I Leg og spil.
Datalogi 1F Forår 2003 Multiprogrammering[3] Eksempler på multiprogrammeringskerner Jørgen Sværke Hansen
Microcontroller ► Fordele ved anvendelse af microcontroller ► Teori ► Informationsflow i microcontrolleren ► Anvendelses muligheder ► Implementering.
Lektion 7 Læsestof: Kopier fra Caranno
Per P. Madsen- Proces1 Algoritmer og datastrukturer Grundprincipper og analyse af algoritmer. MM1 Lister, stakke og køer. MM2 Træer, og Hash-tabeller.
FEN KbP/seminar2: design11 Kontraktbaseret programmering Seminar 2 Klassedesign – grundprincipper Eksempler: Stack Dictionary.
Beskeder/beskedkøer Afsender- proces hej Modtager- proces.. msgsnd(..,"hej",..);.. msgrcv(..);.. Afsender skal bl.a. angive den besked der ønskes afsendt.
FEN KbP/seminar 1: Specifikationer/Notationen Q 1 Kontraktbaseret programmering: Seminar 1 Om specifikationer Algoritmenotationen Q.
Ingeniørhøjskolen i Århus Slide 1 Newton approximation ”Oversæt” til algoritme - Step 5: Skriv kode - Step 4: Skriv pseudokode - Step 3: Specificér pre-
Use Case Modellering. En form for requirements engeneering – dvs. fastlæggelse af systemkrav.
Procestræ under afvikling af cp init login shell cp cp src dest.
Paradigmer i Programmering 2. Sammensatte typer Tupler og lister Programmering med rekursion Programmering med pipe-lines Programmering med polymorfe.
Comparable Students German Students Composite Pattern State Pattern Observer Pattern Collections Interfaces Abstrakte klasser Design Patterns.
8 RÅD VEDRØRENDE GOD PROGRAMMERING Effective (brown) Java.
Efteruddannelse Embedded C Modul 3 (Onsdag den 21/4-2010)
C#: Udtryk og metoder Kilde: Joe Hummel. 2 Nordjyllands Erhvervakademi – 2008 Indhold “With regards to programming statements and methods, C# offers what.
03 – Udtryk og metoder. 2 NOEA2009Java-kursus – Udtryk og metoder Udtryk i Java Java har standard udtrykene… Værditildeling Subrutiner og funktionskald.
Intro Siden sidst: evaluering på opgaver og virtuel kursus Kursussammensætning: forelæsning – læse – arbejde selvstændigt – newsgroup – øvelsestime – aflevering.
Process Control Hardware baggrund Process begrebet i et OS Process tilstande Context switching.
Per Printz Madsen 1 Linux kernen Monolithic kernel Support for dynamiske moduler Få kerne tråde Preemptive.
9. Interfaces. 2 Nordjyllands Erhvervakademi Objectives “Good class design starts with good application design — how many classes, do they relate.
Per P. MadsenStyresystemer og tjenester1 Threads.
Deadlock Definition deadlock (baglås) er en tilstand som en mængde af processer kan være i en mængde processer er i deadlock hvis alle processerne står.
DComNet1 ISA-niveauet (2). dComNet2 Niveauer af virtuelle maskiner ISA niveauet / maskinkodeniveauet / maskinniveau.
Paradigmer i Programmering 3. Højere ordens funktioner Idag: Højere ordens funktioner Algebraiske datatyper Næste gang: I/O, Filer, interaktive programmer.
Effective Java Blå gruppe. Item 18: Interfaces frem for abstrakte klasser Kan implementeres i klasser der ikke nedarver Eksisterende klasser kan nemt.
Begreber og Redskaber 4. Plan for idag Om metoder, parametre, returværdier Et par ord om objekt-orientering Håndkøring af programmer.
Begreber og Redskaber 3. Plan for idag Om metoder, parametre, returværdier Overblik over klasser,objekter,nedarvning Et par ord om objekt-orientering.
1 Processer. 2 fork int fork(); Danner en ny proces med samme indhold som forældre processen. I begge processer er programtælleren placeret lige efter.
I o p o DAIMI, AU, November 1999Programkonstruktion I9E.1 Konstruktion og brug af klasser – en stak og en HP-regnemaskine push pop.
DAIMIIntroducerende objektorienteret programmering3B.1 Definition af klasser Klasseskelet, metoder, et eksempel: dato.
 Michael E. Caspersen, 2000Introducerende objektorienteret programmering6A.1 Programmering med interfaces – en stak og en HP-regnemaskine push pop.
DAIMIProgrammering af Store Systemer1 Concurrency i Java – Samarbejdende tråde.
Indledende Programmering Uge 6 - Efterår 2006
Programmering med interfaces Separering af specifikation, anvendelse og implementation.
Programmering med interfaces – en stak og en HP-regnemaskine push pop.
I o p o DAIMI, AU, September 1999Introducerende objektorienteret programmering5B.1 Sweep-algoritmer Programmering med invarianter og uden kaniner.
Multiple processer på web-site Web- server filer Kunde 1 Kunde 2 Kunde p1p2p internet.
Programmering med interfaces – en stak og en HP-regnemaskine push pop.
Port access I det efterfølgende vil vi anvende databladsoplysninger frem for anvende de færdige metoder.
Nu har du installeret uVision og set at både programmet og boardet virker. Man kan ikke lære at cykle ved at se på andre, så i det efterfølgende skal du.
1587 Server - Blandet miljø Embedded I
Embedded SW – C & picoBlaze
Lav et nyt projekt og tilføj denne gang pakken Graphic LCD.
”Avanceret” Programmering
Tre lags arkitektur.
Præsentationens transcript:

Datalogi 1F: Multiprogrammering[3] 1 Planen for idag Kerner uden afbrydelser (KB4 kap. 6): –akernen: kerne med decentralt processkift –bkernen: kerne med centralt processkift Kerne med afbrydelser (KB4 kap. 7): –ckernen: løst koblede drivprogrammer –dkernen: kerne med tætkoblede drivprogrammer

Datalogi 1F: Multiprogrammering[3] 2 Kernestruktur: akernen KInitProc(…)KWaitQ KPause()KCurProc KSelectNewProcess() KInitSem()KReadChar() KWait()KWriteChar() KSignal() KReadLine() KWriteLine() readerProc writerProc

Datalogi 1F: Multiprogrammering[3] 3 Brugerprogrammerne void reader() { rsem.Init(1); wsem.Init(0); for(;;) { rsem.Wait(); buf.Read(); wsem.Signal(); } void Writer() { for(;;) { wsem.Wait(); if(buf == ”exit\r”) asm(”call_pal 0xAD”); buf.Write(); rsem.Signal(); }

Datalogi 1F: Multiprogrammering[3] 4 Processer i akerne Proces kontrolblokken i akerne: –CPU registre (gemt på stakken) –Vi gemmer kun stakpeger –Køpegere beregnet for ventekø struct Process : public Queueable { Registers *sp; }

Datalogi 1F: Multiprogrammering[3] 5 Processkift akernen: –har frivilligt processkift –benytter aktiv venten En proces kalder KPause hvis den venter på en hændelse (fungerer som yield() i Java) Aktiv venten: void KGenericProcedure() { while( ) KPause(); <udfør aktion efter hændelse er indtruffet>; }

Datalogi 1F: Multiprogrammering[3] 6 KPause KPause foretager skiftet fra en proces til en anden: void KPause() { ; }

Datalogi 1F: Multiprogrammering[3] 7 Ventende processer AP: KPause registre P1 AP: ProcA AP: KPause registre P2 AP: ProcX AP: KPause registre P3 AP: ProcY PCB P1: sp PCB P2: sp PCB P3: sp struct process AP: ProcB

Datalogi 1F: Multiprogrammering[3] 8 Opfrisker: tællesemaforer void TælleSem::vent() { if(tæller > 0) tæller--; else { ventende++; ; } void TælleSem::signaler() { if(ventende > 0) { ; ventende--; } else tæller++; }

Datalogi 1F: Multiprogrammering[3] 9 Akerneversionen af tællesemaforoperationer void KSignal(KSem& sem) { sem++;// Aktivering af ventende } // sker ved aktiv venten void KWait(KSem& sem) { while (!sem) // Aktiv venten KPause(); sem--; }

Datalogi 1F: Multiprogrammering[3] 10 I/O operationer char KReadChar() { while(!(rdio(com1Lsr) & 0x01)) KPause(); return rdio(com1Rbr); } void KWriteChar(char ch) { while(!(rdio(com1Lsr) & 0x20)) KPause(); wrio(com1Thr, ch); }

Datalogi 1F: Multiprogrammering[3] 11 Kontrolregistre på UART

Datalogi 1F: Multiprogrammering[3] 12 I/O operationer (2) void KReadLine(char* p, int max) { for (int i = 0; i < max-1; i++) if((*p++ = KReadChar()) == ’\r’) break; *p = ’\0’; } void KWriteLine(char *p, int max) { for (int i = 0; (i < max) && *p; i++,p++) KWriteChar(*p); }

13 Ventende processer: igen PCB P1: sp PCB P2: sp PCB P3: sp struct process AP: KReadLine AP: KWriteLine AP: KPause registre P1 AP: KWait AP: KPause registre P2 AP: KReadChar AP: KPause registre P3 AP: KWriteChar

Datalogi 1F: Multiprogrammering[3] 14 KPause: implementation ( kblib.s ) KPause: ldgp gp, (pv) lda sp,-STAKRAMME(sp) stq $0, 0(sp) stq $1, 8(sp) … stq $29, 0xE8(sp) bis sp, 0, a0 // stakpeger er // parameter lda pv, KSelectNewProcess jsr ra, (pv) bis v0, 0, sp // ny stakpeger er // returværdi ldq $0, 0(sp) ldq $1, 8(sp) … ldq $29, 0xE8(sp) lda sp, STAKRAMME(sp) ret (ra) SAVE_REGS REST_REGS

Datalogi 1F: Multiprogrammering[3] 15 KPause(): et par kommentarer Tæl stakpeger ned inden registre lægges på stakken: –en afbrydelse vil bruge samme stakpeger og kan overskrive værdier hvis sp er for høj Tæl stakpeger op EFTER registre er fjernet fra stakken Selve skiftet af KCurProc sker ikke i KPause men i KSelectNewProcess

Datalogi 1F: Multiprogrammering[3] 16 KSelectNewProcess Registers* KSelectNewProcess(Registers* sp) { KCurProc->sp = sp; KWaitQ.Put(KCurProc); KCurProc = KWaitQ.Get(); return KCurProc->sp; } Skedulering foregår round-robin Hvad er det for noget med Registers* ? Var det ikke stakpegeren???

17 struct Registers struct Registers { unsigned long r [30]; unsigned long ps, pc, gp, a0, a1, a2; }; r[0] r[1] r[29] ps a2 struct registers placering i lageret r[0] r[1] r[29] AP: KPause en processtak ved kald af KSelectNewProcess PAL kald stakramme Registers*

18 KCurProc PCB P3: sp PCB P2: sp PCB P1: sp void KWriteChar(char ch) { while(!(rdio(com1Lsr) & 0x20)) KPause(); wrio(com1Thr, ch); } void KWait(KSem& sem) { while (!sem) KPause(); sem--; } char KReadChar() { while(!(rdio(com1Lsr) & 0x01)) KPause(); return rdio(com1Rbr); } Ventende processer: igen igen AP: KPause registre P1 AP: KWait AP: KPause registre P2 AP: KReadChar AP: KPause registre P3 AP: KWriteChar struct process AP: KReadLine AP: KWriteLine KCurProc AP: KSelectNewP… AP: KSelectNewP… AP: KSelectNewP…

19 KCurProc PCB P3: sp PCB P2: sp PCB P1: sp void KWriteChar(char ch) { while(!(rdio(com1Lsr) & 0x20)) KPause(); wrio(com1Thr, ch); } void KWait(KSem& sem) { while (!sem) KPause(); sem--; } char KReadChar() { while(!(rdio(com1Lsr) & 0x01)) KPause(); return rdio(com1Rbr); } Ventende processer: igen igen AP: KPause registre P1 AP: KWait AP: KPause registre P2 AP: KReadChar AP: KPause registre P3 AP: KWriteChar AP: KReadLine AP: KWriteLine KCurProc AP: KSelectNewP… AP: KSelectNewP… AP: KSelectNewP…

Datalogi 1F: Multiprogrammering[3] 20 OK – nok show: hvordan starter vi akernen? // Reader processens kernedatastrukturer extern void Reader (); Process readerProc; unsigned long readerStack [stackSize]; void main() { KWait.Init(); KInitProc(Reader, readerStack, &readerProc); KInitProc(Writer, writerStack, &writerProc); KCurProc = KWaitQ.Get(); KFirst(KCurProc->sp); }

Datalogi 1F: Multiprogrammering[3] 21 Hvad sker der i KInitProc? KInitProc initialiserer en proces’ stak, så det ser ud som om den har kaldt KPause(): void KInitProc(void (*startAddr) (), void *Stack, Process *proc) { Stack += (stackSize * sizeof(unsigned long) – sizeof(Registers) ); proc->sp = (Registers *) Stack; proc->sp->r[26] = proc->sp->r[27] = (unsigned long) startAddr; // ra & pv KWaitQ.Put(proc); }

Datalogi 1F: Multiprogrammering[3] 22 Processtak efter KInitProc r[0] r[1] startAddr r[28] r[29] startAddr return address procedure value stackSize sp PKB

Datalogi 1F: Multiprogrammering[3] 23 KSelectNewProcess Registers* KSelectNewProcess(Registers* sp) { KCurProc->sp = sp; KWaitQ.Put(KCurProc); KCurProc = KWaitQ.Get(); return KCurProc->sp; }

Datalogi 1F: Multiprogrammering[3] 24 KPause: implementation ( kblib.s ) KPause: ldgp gp, (pv) lda sp,-STAKRAMME(sp) stq $0, 0(sp) stq $1, 8(sp) … stq$29, 0xE8(sp) bis sp, 0, a0 // stakpeger er parameter lda pv, KSelectNewProcess jsr ra, (pv) bis v0, 0, sp // ny stakpeger er returværdi ldq $0, 0(sp) ldq $1, 8(sp) … ldq $29, 0xE8(sp) lda sp, STAKRAMME(sp) ret (ra) SAVE_REGS REST_REGS

Datalogi 1F: Multiprogrammering[3] 25 Og så skal det hele sættes igang KCurProc = KWaitQ.Get(); KFirst(KCurProc->sp); hvor KFirst er defineret ved: KFirst:ldgp gp, (pv) ldq pv, 0xD8(a0) // Pop pv addq a0, 0xF0,a0 // Skip registre bis a0, 0, sp // Sæt sp jmp (pv) // Hop til processtart

Datalogi 1F: Multiprogrammering[3] 26 OK, hvad var det for noget med decentralt skift? Venteløkkerne for de enkelte I/O og semaforoperationer var spredt ud over kernen: –ineffektivt: registre skal poppes og pushes hele tiden –svært at vedligeholde: hvad nu hvis vi gerne vil ændre vores aktiv venten strategi –ugennemsigtigt: vi ved ikke hvilke hændelser de enkelte processer venter på

Datalogi 1F: Multiprogrammering[3] 27 Kerne med centralt processkift I modsætning til akerne.cc ønsker vi at have en central venteløkke og processkift Hvordan specificerer en proces hvad den venter på? Vi indfører operationen KSleep(), der venter på at en specifik hændelse indtræder

Datalogi 1F: Multiprogrammering[3] 28 Hændelser En proces kan vente på: –CPU (den er klar til at blive udført) –Ydre enheder (en operation bliver færdigbehandlet) –Semafor (ankomst af et signal) Specifikationen af en hændelse skal kunne omfatte alle ovenstående hændelser

Datalogi 1F: Multiprogrammering[3] 29 struct Event struct Event { enum { IO, SEM, CPU } id; union { struct { int addr; char mask; } io; struct { KSem* addr; } sem; } Event(int, char);// vent på I/O Event(KSem&);// vent på semafor Event();// vent på CPU }

Datalogi 1F: Multiprogrammering[3] 30 Proceskontrolblokken Nu bliver processens tilstand udvidet med hvilken hændelse en proces venter på: struct Process { Registers* sp; Event waitsFor; } *KCurProc;

Datalogi 1F: Multiprogrammering[3] 31 KSleep() En ”overbygning” til KPause(), der registerer hvilken hændelse en proces venter på: void KSleep(Event e) { KCurProc->waitsFor = e; KPause(); }

Datalogi 1F: Multiprogrammering[3] 32 Ny udgave af semaforoperation Ny udgave: void KWait (KSem& sem) { if(!sem) KSleep( Event(sem) ); sem--; } Gammel udgave: void KWait(KSem& sem) { while (!sem) // Aktiv venten KPause(); sem--; }

Datalogi 1F: Multiprogrammering[3] 33 I/O operationerne char KReadChar() { if (!rdio(com1Lsr) & 0x01) KSleep( Event(com1Lsr, 0x01) ); return rdio(com1Rbr); } void KWriteChar(char ch) { if (!rdio(com1Lsr) & 0x20) KSleep( Event(com1Lsr, 0x20) ); wrio(com1Thr, ch); }

Datalogi 1F: Multiprogrammering[3] 34 Den centrale venteløkke Registers* KSelectNewProcess(Registers* sp) { KCurProc->sp = sp; for(int found = 0; !found; ) { KWaitQ.Put(KCurProc); KCurProc = KWaitQ.Get(); switch(KCurProc->waitsFor.id) { case Event::CPU: found = 1; break; case Event::IO: if(rdio(KCurProc->waitsFor.io.addr)& KCurProc->waitsFor.io.mask) found = 1; break; case Event::SEM: if(*KCurProc->waitsFor.sem.addr) found = 1; break; } return KCurProc->sp; }

35 Ventende processer: igen igen igen AP: KPause registre P1 AP: KWait AP: KPause registre P2 AP: KReadChar AP: KPause registre P3 AP: KWriteChar AP: KSleep PCB P1: sp waitsfor = SEM struct process PCB P2: sp waitsfor = IO PCB P3: sp waitsfor = IO KCurProc AP: KSelectNewP… AP: KSelectNewP… AP: KSelectNewP… void KWriteChar(char ch) { if (!rdio(com1Lsr) & 0x20) KSleep( Event(com1Lsr, 0x20); wrio(com1Thr, ch); }

Datalogi 1F: Multiprogrammering[3] 36 Kerne med centralt processkift KInitProc(…)KWaitQ KSleep()KCurProc KPause() KSelectNewProcess() KInitSem()KReadChar() KWait()KWriteChar() KSignal() KReadLine() KWriteLine() readerProc writerProc

Datalogi 1F: Multiprogrammering[3] 37 Kerner med aktiv venten Vi har flere gange diskuteret at aktiv venten ikke er den mest effektive måde at opdage en hændelse på: –selv med en central venteløkke spilder vi tid på at undersøge ydre enheders statusregistre når der ikke er behov for det forsinker aktivering af processer, der enten venter på CPU eller har modtaget en hændelse Men det giver simple kerner: –det hele kan forstås som en sekventiel proces

Datalogi 1F: Multiprogrammering[3] 38 Kerner med afbrydelser Slut med aktiv venten Afbrydelsesprocedure aktiverer ventende processer Men alting bliver mere uforudsigeligt, idet afbrydelser kan indtræde når som helst: –data kan deles mellem afbrydelsesprocedurer og resten af kernen –brug for udelelig adgang til delt data

Datalogi 1F: Multiprogrammering[3] 39 Processkift Da vi ikke har aktiv venten, skal vi holde rede på de ventende processer. Vi benytter to proceskøer: –KWaitQ: kø af processer der venter på en hændelse (semaforsignal eller ydre enhed) –KReadyQ: kø af processer der er klar til at blive udført (venter på at få adgang til CPU) Processer bør først forlade KWaitQ når hændelsen de venter på er indtrådt

Datalogi 1F: Multiprogrammering[3] 40 Suspendering af processer KPause kalder KSelectNewProcess, der sætter den aktive proces til at vente: Registers* KSelectNewProcess(Registers* sp) { KCurProc->sp = sp; KWaitQ.Put(KCurProc); KCurProc = KReadyQ.Get(); // Her er forskellen return KCurProc->sp; }

Datalogi 1F: Multiprogrammering[3] 41 Aktivering af processer Vi aktiverer processerne når vi får en afbrydelse: void KInterruptHandler() { while(!KWaitQ.isEmpty()) KReadyQ.Put(KWaitQ.Get()); } Men hov? alle processerne startes? Ja, for vi genbruger vores kerne med decentralt processkift

Datalogi 1F: Multiprogrammering[3] 42 I/O operationer char KReadChar() { while(!(rdio(com1Lsr) & 0x01)) KPause(); return rdio(com1Rbr); } void KWriteChar(char ch) { while(!(rdio(com1Lsr) & 0x20)) KPause(); wrio(com1Thr, ch); } Alle ventende processer aktiveres og udfører check på om hændelse er indtrådt decentralt

Datalogi 1F: Multiprogrammering[3] 43 Afbrydelseshåndtering i ckerne Afbrydelse fra ydre enhed aktiverer afbrydelseshåndtering via PAL kode: –først aktiveres ent_int –ent_int kalder KInterruptHandler –derefter returneres til ent_int –ent_int returnerer fra afbrydelse ent_int specificeres i ckernens main funktion via PAL_wrent

Datalogi 1F: Multiprogrammering[3] 44 ent_int ent_int:SAVE_REGS br t0, 1f 1:ldgp gp, (t0) lda pv, KInterruptHandler jsr ra, (pv) REST_REGS call_pal PAL_rti

Datalogi 1F: Multiprogrammering[3] 45 Stak under afbrydelse AP: buf.Write() AP: KWriteLine proces Write() void KWriteLine(char *p, int max) { for (int i=0; (i<max) && *p; i++,p++) KWriteChar(*p); } PAL stakramme AP: ent_int ent_int: SAVE_REGS br t0, 1f 1: ldgp gp, (t0) lda pv, KInterruptHandler jsr ra, (pv) REST_REGS call_pal PAL_rti void KInterruptHandler() { while(!KWaitQ.isEmpty()) KReadyQ.Put(KWaitQ.Get()); } AP: KInterruptHa… AP: KReadyQ.Put… void KReadyQ.Put() {…} AP: KWriteChar Stak for Proces Writer

Datalogi 1F: Multiprogrammering[3] 46 Synkronisering med ydre enheder char KReadChar() { while(!(rdio(com1lsr) & 0x01)) KPause();// Opdaterer KWaitQ indirekte return rdio(com1Rbr); } void KInterruptHandler() { while(!KWaitQ.isEmpty()) KReadyQ.Put(KWaitQ.Get()); } Test på LSR og ventekøoperation i KReadChar skal udføres udeleligt, ellers kan følgende ske …

Datalogi 1F: Multiprogrammering[3] 47 Uheldig rækkefølge while(!(rdio(com1lsr) & 0x01)) sætter ready-bit while(!KWaitQ.isEmpty()) KPause(); AAAAARGH: vi opdager ikke at tegnet er læst

Datalogi 1F: Multiprogrammering[3] 48 Implementering af udelelighed Luk for afbrydelser: char KReadChar() { forbid(); while(!(rdio(com1lsr) & 0x01)) KPause(); char ch = rdio(com1Rbr); permit(); return ch; } Nu bliver vi ikke afbrudt mellem check af statusregister og KWaitQ.Put()

Datalogi 1F: Multiprogrammering[3] 49 Køoperationerne skal også beskyttes Eksempel: int isEmpty() { int oldipl = forbid(); int b = (size == 0); permit(oldipl); return b; }; Gem ipl – så undgår vi at lukke op for afbrydelser ved et uheld Vigtigt hvis operationer kan benyttes af afbrydelsesprocedurer

Datalogi 1F: Multiprogrammering[3] 50 Hvad gør vi når klarkøen er tom? En tomgangsproces: –en proces som aldrig kommer i ventekøen, men som hele tiden frivilligt opgiver CPU’en En tomgangsløkke i KSelectNewProcess: while( KReadyQ.isEmpty() ) { permit(); /* Do nothing */; forbid() }

Datalogi 1F: Multiprogrammering[3] 51 Tætkoblede drivprogrammer I stedet for at vække alle processer ved en afbrydelse kan vi have en ventekø for hver hændelse: char KReadChar() { while(!(rdio(com1lsr) & 0x01)) KPause(KReadQ); return rdio(com1Rbr); }

Datalogi 1F: Multiprogrammering[3] 52 KSelectNewProcess tager en ventekø som argument Registers* KSelectNewProcess(Registers* sp, Queue & blockOn) { KCurProc->sp = sp; blockOn.Put(KCurProc); while( KReadyQ.isEmpty() ) /* Do nothing */; KCurProc = KReadyQ.Get(); return KCurProc->sp; }

Datalogi 1F: Multiprogrammering[3] 53 Afbrydelsesprocedure ved tæt kobling void KInterruptHandler() { if( rdio(com1Iir) & 2) while(!KReadQ.isEmpty()) KReadyQ.Put(KReadQ.Get()); else if( rdio(com1Iir) & 3) while(!KWriteQ.isEmpty()) KReadyQ.Put(KWriteQ.Get()); }

Datalogi 1F: Multiprogrammering[3] 54 Opsummering Kerner uden afbrydelser: –baseret på aktiv venten Kerne med decentralt processkift: –venteløkker i styreprogrammer og semaforoperationer Kerne med centralt processkift –processer specificere en hændelse de venter på –én venteløkke der undersøger om hændelser er sket for alle ventende processer Kerne med afbrydelser: –afbrydelser aktiverer ventende processer –tæt koblede drivprogrammer: en kø per hændelse

Datalogi 1F: Multiprogrammering[3] 55 Kilder Disse slides er baseret på indholdet i Datalogi 1F kursusbog bind 4, kapitlerne 6 & 7.