1 / 49

Planen for i dag

Planen for i dag. Repetition af kerner med afbrydelser Kerner med tvungent processkift Præsentation af K1. Kerner med afbrydelser. Vi erstattede aktiv venten med: ventende processer placeres i ventekøer afbrydelser aktiverer ventede processer ved at flytte dem til klarkøen

iain
Download Presentation

Planen for i dag

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Planen for i dag • Repetition af kerner med afbrydelser • Kerner med tvungent processkift • Præsentation af K1 Datalogi 1F: Multiprogrammering[4]

  2. Kerner med afbrydelser • Vi erstattede aktiv venten med: • ventende processer placeres i ventekøer • afbrydelser aktiverer ventede processer ved at flytte dem til klarkøen • Bedre udnyttelse af CPU • Introduktion af parallelisme i kernen: • afbrydelsesroutiner kan udføres når som helst (undtagen når vi lukker for afbrydelser) • fokus på kritiske regioner Datalogi 1F: Multiprogrammering[4]

  3. Kerne med afbrydelser readerProc writerProc KReadLine() KWriteLine() KInitSem() KReadChar() KWait() KWriteChar() KSignal() KReadQ KWriteQ KInitProc(…) KReadyQ KSleep() KCurProc KPause() KSelectNewProcess() KInterruptHandler() Datalogi 1F: Multiprogrammering[4]

  4. Tætkoblede drivprogrammer • Hver slags hændelse (tegn skrevet, tegn læst, …) er tilknyttet en ventekø: char KReadChar() { while(!(rdio(com1lsr) & 0x01)) KPause(KReadQ); return rdio(com1Rbr); } Datalogi 1F: Multiprogrammering[4]

  5. Synkronisering med ydre enheder void KInterruptHandler() { if( rdio(com1Iir) & 2) while(!KReadQ.isEmpty()) KReadyQ.Put(KReadQ.Get()); else if( rdio(com1Iir) & 4) while(!KWriteQ.isEmpty()) KReadyQ.Put(KWriteQ.Get()); } Datalogi 1F: Multiprogrammering[4]

  6. Uheldig rækkefølge <KReadChar> while(!(rdio(com1lsr) & 0x01)) <UART> sætter ready-bit <KInterruptHandler> while(!KWaitQ.isEmpty()) <KReadChar> KPause(KReadQ); <KSelectNewProcess> <sætter proces i ventekø> AAAAARGH: vi opdager ikke at tegnet er læst Datalogi 1F: Multiprogrammering[4]

  7. Problem • Vi har to parallelle processer: • brugerproces • afbrydelsesroutine der deler data: • kontrolregistre • proceskøer • Vi må sikre udelelig udførsel af kritiske regioner Datalogi 1F: Multiprogrammering[4]

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

  9. Ny KPause • KPause skal skifte afbrydelsesniveau (ipl er en del af processens tilstand): void KPause() { <gem afbrydelsesniveau i PKB>; <gem registre på stakken>; <gem stakpeger i PKB>; <find ny proces>; <gendan stakpeger fra PKB>; <gendan registre>; <gendan afbrydelsesniveau fra PKB>; } Datalogi 1F: Multiprogrammering[4]

  10. Andre routiner derskal beskyttes? • Afbrydelsesroutiner og alm. kernefunktioner deler køstrukturer • Beskyt køoperationerne: int isEmpty() { int oldipl = forbid(); int b = (size == 0); permit(oldipl); return b; }; Datalogi 1F: Multiprogrammering[4]

  11. Kerner med tvungent processkift • Indtil nu har vi kun set på kerner med frivilligt processkift via KPause() • En afbrydelsesroutine sætter processen i klarkøen, men der kan gå lang tid inden den aktive proces opgiver CPU’en • Vi vil tvinge et processkift som en del af afbrydelsen: • dette sikrer hurtigere behandling af afbrydelser Datalogi 1F: Multiprogrammering[4]

  12. Ny afbrydelsesprocedure void KInterruptHandler() { if(rdio(com1Iir) & 2) KSleep (KReadyQ, KWriteQ); else if(rdio(com1Iir) & 4) KSleep (KReadyQ, KReadQ); …… } Datalogi 1F: Multiprogrammering[4]

  13. KSleep og venner Queue<Process>* KPutQ, KGetQ; void KSleep(Queue<Process>& put, Queue<Process>& get) { KPutQ = &put, KGetQ = &get; KPause(); } Registers* KSelectNewProcess (Registers* sp) { KCurProc->sp = sp; KPutQ->Put(KCurProc); KCurProc = KGetQ->Get(); return KCurProc->sp; }

  14. a2 a1 a0 gp pc ps Tvungent processkift - eksempel BP2 sp BP1 sp afbrydelse AP:BP2_start() AP:BP1_start() AP: Wait(sem) AP: printl() PAL stakramme P2 AP: KWriteLine AP: ent_int AP: KWriteChar Registre P2 Processkift sker EFTER behandling af og kvittering for afbrydelse AP: KPause AP: KInterruptH… AP: KSelectNewP… AP: KSleep • Skift: • stakpeger • afbrydelsesniveau AP: KPause AP: KSelectNewP…

  15. Semaforroutiner Nu kan vores semaforroutiner også blive afbrudt: void KWait (KSem *sem) { if (!sem->value) KSleep(sem->WaitQ, KReadyQ); sem->value--; } • Førhen var dette sikkert fordi afbrydelser ikke rørte ved semaforerne • Men nu kan en vilkårlig proces blive afbrudt Datalogi 1F: Multiprogrammering[4]

  16. En anden uheldig rækkefølge <BP1> if(!sem->value) <antag sem->value == 1> <Afbrydelse> KPause(KReadyQ, KReadQ); . . . . . . <BP2> if(!sem->value) <sem->value stadig == 1> <BP2> sem->value--; <Afbrydelse> KPause(KReadyQ, KWriteQ); . . . . . . <BP1> sem->value--; UUUPS: der er 2 processer i kritisk region!!

  17. Nye semaforroutiner Nu kan vores semaforroutiner ikke mere blive afbrudt: void KWait (KSem *sem) { forbid(); if (!sem->value) KSleep(sem->WaitQ, KReadyQ); sem->value--; permit(); } Datalogi 1F: Multiprogrammering[4]

  18. Andre routiner derhar problemer? • Måske KSleep generelt? • Kan vi klare at skifte proces mens vi skifter proces? Registers* KSelectNewProcess (Registers* sp) { KCurProc->sp = sp; KPutQ->Put(KCurProc); KCurProc = KGetQ->Get(); return KCurProc->sp; } • De to globale variable KPutQ og KGetQ ser suspekte ud Datalogi 1F: Multiprogrammering[4]

  19. Endnu en uheldig rækkefølge <BP1> < KSleep(KReadyQ, myWaitQ) > < KPutQ = KReadyQ, KGetQ = myWaitQ > <Afbrydelse> < KSleep(KReadyQ, KReadQ) > < KPutQ = KReadyQ, KGetQ = KReadQ > <BP4> . . . . . . < KSleep(KReadQ, KReadyQ) > < KPutQ = KReadQ, KGetQ = KReadyQ > <BP1> < KSelectNewProcess > < Sætter sig selv på KReadQ men aktiverer proces fra KReadyQ > Datalogi 1F: Multiprogrammering[4]

  20. Morale • Man skal være forsigtig!!!! • Identificer alle variable der deles mellem afbrydelsesroutiner og alm. kerneroutiner • Foretag sikring af kritiske regioner • Ved aflusning af kerner (f.eks. K1) kan det være en god ide at starte med helt at lukke for afbrydelser i kernen og så langsom bløde det op Datalogi 1F: Multiprogrammering[4]

  21. Kerner med periodisk processkift • Hidtil har vi udskiftet den kørende proces ved afbrydelse fra I/O enhed: • Har vi kun en CPU tung proces, er det fint nok, da den vil blive afbrudt • Men hvis vi har flere, kan der stadig gå lang tid inden en ventende proces ”kommer til fadet” • KPause() kaldes typisk som led i et systemkald: • ved hvert systemkald kunne man undersøge om en proces har kørt for længe, og derefter kalde KPause • Hvad med beregningstunge processer, der sjældent bruger systemkald? • Kræv at de skal indsætte frivillige processkift • Tving dem væk fra CPU’en Datalogi 1F: Multiprogrammering[4]

  22. Implementering af periodisk processkift void KInterruptHandler (ulong a0) { if ( a0 & 0x01) KSleep(KReadyQ, KReadyQ); else . . . . . . } • Hver gang uret afbryder puttes den aktive proces bagerst i klarkøen (round robin) • Men hvad hvis der ingen aktiv proces er? Datalogi 1F: Multiprogrammering[4]

  23. Tomgangsprocessen • For at sikre, at der altid er en proces i klarkøen, har vi en tomgangsproces: void KIdleProcess { for(;;;) KSleep(KReadyQ,KReadyQ); } • men man kunne nu stadig bruge en venteløkke i selve KSelectNewProcess Datalogi 1F: Multiprogrammering[4]

  24. Brug af to sikkerhedsniveauer • Hardware indeholder en eller flere bits, der viser sikkerhedsniveau, f.eks. (0) brugertilstand og (1) kernetilstand • Ved afbrydelser skiftes til kernetilstand, f.eks. ved en trap operation • Specielle privilegerede instruktioner kan kun udføres i kernetilstand, typisk instruktioner der har med ressourcedeling at gøre kernetilstand skift til brugerniveau trap/ exception brugertilstand Datalogi 1F: Multiprogrammering[4]

  25. 2 slags stakke • Når brugerprogrammer udføres i brugertilstand benytter de en brugerstakpeger • Systemkald samt afbrydelser udføres i kernetilstanden og benytter en kernestakpeger • Kernestakpegeren peger på et andet lagerområde end brugerstakpegeren • Kerne sp vil typisk være beskyttet mod skrivning og læsning fra brugertilstand • Skiftet mellem stakpegerne foretages på Alphaerne af PAL koden ved skift mellem bruger og kernetilstand Datalogi 1F: Multiprogrammering[4]

  26. Brugerstak og kernestakeksempel BP1 sp AP:BP1_start() BP1_start(void) { findmin(t3_root); } AP: findmin() afbrydelse AP: findmin() PAL registre: bruger sp: BP1 sp kerne sp: 0x200000 PAL registre: bruger sp: ikke def. kerne sp: 0x200000 kerne sp PAL stakramme $sp = kerne sp $sp = bruger sp kerne sp = $sp AP: ent_int AP: KInterruptH… Datalogi 1F: Multiprogrammering[4]

  27. Processkift i afbrydelsesprocedure • Hvis vi ønsker at skifte proces i en afbrydelsesprocedure skal vi dels: • gemme kørende proces’ tilstand • ændre brugerstakpeger i PAL register • gendanne nye proces’ tilstand • Ændring af bruger sp er nemt: • PAL_rdusp læser bruger stakpeger fra PAL register • PAL_wrusp skriver en ny bruger stakpeger til PAL register • Men processernes tilstande omfatter: • PAL stakramme • Registre gemt af ent_int (afbrydelsesniveau) Datalogi 1F: Multiprogrammering[4]

  28. Skift mellem stakke vedprocesskift under afbrydelse Vi ser på fire eksempler • Skift mellem processer i brugertilstand: • én kernestak • en kernestak pr proces • Processkift med en proces i systemtilstand og en i brugertilstand • Processkift ved indlejrede afbrydelser, f.eks.: • først afbrydelse fra UART (ipl 3) • KInterruptHandler afbrydes af uret (ipl 5) Datalogi 1F: Multiprogrammering[4]

  29. 2 processer i brugertilstand:én kernestak BP2 sp BP1 sp AP:BP2_start() AP:BP1_start() AP: calc() AP: calc() afbrydelse AP: calc() AP: calc() kerne sp PAL stakramme P1 PAL stakramme P2 Registre P2 Registre P1 PAL registre: bruger sp: BP1 sp kerne sp: 0x200000 PAL registre: bruger sp: XXXXX kerne sp: 0x200000 PAL registre: bruger sp: BP2 sp kerne sp: 0x200000 Gem kopi af BP2s kernestak (f.eks. på brugerstakken) Gendan kopi af BP1s kernestak AP: ent_int AP: KInterruptH… AP: KSelectNewP…

  30. 2 processer i brugertilstand:en kernestak per proces BP2 sp BP1 sp PAL registre: bruger sp: BP1 sp kerne sp: 0x200000 PAL registre: bruger sp: BP1 sp kerne sp: 0x220000 PAL registre: bruger sp: BP2 sp kerne sp: 0x200000 PAL registre: bruger sp: XXXXX kerne sp: 0x200000 AP:BP2_start() AP:BP1_start() AP: calc() AP: calc() afbrydelse AP: calc() AP: calc() BP1 kerne sp BP2 kerne sp PAL stakramme P1 PAL stakramme P2 Registre P1 Registre P2 AP: ent_int AP: ent_int AP: KInterruptH… AP: KInterruptH… AP: KSelectNewP… AP: KSelectNewP…

  31. 2 processer: en i brugertilstand ogen i kernetilstand BP2 sp BP1 sp afbrydelse AP:BP2_start() AP:BP1_start() AP: calc() AP: printl() BP1 kerne sp • Skift: • brugerstakpeger • aktiv stakpeger • afbrydelsesniveau BP2 kerne sp PAL stakramme P1 PAL stakramme P2 AP: ent_sys AP: ent_int Registre P1 Registre P2 AP: KWriteChar AP: KInterruptH… AP: KPause AP: KPause AP: KSelectNewP… AP: KSelectNewP…

  32. Indlejrede afbrydelser PAL stakramme P2 Registre P2 kerne sp Er flag for processkift sat og er vi den sidste afbrydelse? AP: ent_int AP: KInterruptH… BP2 sp AP: KPause PAL stakramme P2 AP:BP2_start() AP: KSelectNewP… Registre P2 Så kan vi skifte til en anden proces AP: calc() AP: ent_int afbrydelse AP: calc() afbrydelse AP: KInterruptH… Vi sætter et flag, der fortæller at vi skal foretage et processkift Duer ikke – vi var allerede i gang med at behandle et interrupt AP: KPause AP: KSelectNewP…

  33. Indlejrede afbrydelser • Hvordan ved man at man er det ”eneste” interrupt? • På stakken ligger et statusregister, der fortæller hvad afbrydelsesniveau var inden den aktuelle afbrydelse: • ipl == 0 => ingen forudgående afbrydelser Datalogi 1F: Multiprogrammering[4]

  34. Opsummering • Kerner med afbrydelser: • introduktion af parallelisme i kernen • implementation af udelelighed ved styring af afbrydelsesniveau • Tvungent processkift: • øget parallelisme i kernen (alle processer kan afbrydes) • periodisk processkift • indlejrede afbrydelser Datalogi 1F: Multiprogrammering[4]

  35. K1: Multiprogrammeringskerne med prioriteret skedulering • Udvikling af en multiprogrammeringskerne: • procesafvikling • procesadministration • synkronisering • I/O • der skal kunne afvikle et sæt brugerprogrammer Datalogi 1F: Multiprogrammering[4]

  36. Procesafvikling • Brugerprocesser skal køre i brugertilstand og kernefunktioner afvikles i kernetilstand: • i modsætning til kernerne i kursusbog bind 4 hvor alt foregår i kernetilstand • En konsekvens (og et krav) er at alle kernefunktioner skal aktiveres vha. alpha’ernes systemkaldsmekanisme: • PAL_callsys, PAL_rti • Kernen skal implementere tvungen tidsdeling: • uret afbryder 1024 gange i sekundet • processkift under udførsel af kerneoperationer Datalogi 1F: Multiprogrammering[4]

  37. Procesadministration • start_proc: starter en proces • exit: terminerer en proces • sleep: sætter proces til at vente i X 1/1024 sekunder • yield: frivilligt processkift • Ved kernens start overgives kontrollen til processen INIT(), der starter de resterende brugerprocesser. Datalogi 1F: Multiprogrammering[4]

  38. Skedulering • Prioritetsbaseret skedulering: • 32 prioritetsniveauer: 0 – højest, 31 – lavest • round-robin indenfor hvert prioritetsniveau • ældning af lavprioritetsprocesser for at undgå udsultning • Systemkald: set_priority(unsigned int priority) sætter processens prioritet unsigned int get_priority() returnerer processens aktuelle prioritet Datalogi 1F: Multiprogrammering[4]

  39. Synkronisering • Klassisk tællesemafor: struct KSem { unsigned int value; Queue<Process> queue; } • med operationerne: • KSem *new_sem(int i) • wait_sem(KSem *) • signal_sem(KSem *) • free_sem(KSem *) Datalogi 1F: Multiprogrammering[4]

  40. Prioritetsinvertering • I systemer med prioritetsbaseret skedulering kan der optræde prioritetsinvertering: • en højprioritetsproces venter på en kritisk region, der er låst af en lavprioritetsproces Datalogi 1F: Multiprogrammering[4]

  41. S1 S2 S3 S3 Prioritetsinvertering - eksempel P1 aktiv høj P2 aktiv medium aktiv P3 lav aktiv Datalogi 1F: Multiprogrammering[4]

  42. Prioritetsnedarvning • For at undgå prioritetsinvertering: • arver en proces i en kritisk region prioriteten fra den højest prioriterede proces associeret med den kritiske region • Prioritetsnedarvning er transitiv: • P1 (pri = 0) venter på P2 (pri = 15) • P2 venter på P3 (pri = 31) • P3 skal arve prioritet = 0 • Indlejrede kritiske regioner Datalogi 1F: Multiprogrammering[4]

  43. Kritiske regioner • Kritiske regioner synliggøres overfor kernen ved hjælp af en speciel mutex semafor med operationerne: • KSem *new_mutex() • wait_mutex(KSem *) • signal_mutex(KSem *) • free_mutex(KSem *) • Prioritetsnedarvning kan knyttes til wait_mutex og signal_mutex Datalogi 1F: Multiprogrammering[4]

  44. I/O • readdata: indlæser et antal tegn fra COM og returnerer hurtigst muligt • writedata: udskriver et antal tegn på COM • readpacket: indlæser en pakke fra ETH0 • readline: indlæser en linie fra COM • writeline: udskriver en linie på COM • I/O operationer skal foregå udeleligt Datalogi 1F: Multiprogrammering[4]

  45. Afbrydelser • Kernen skal håndtere afbrydelser fra COM, ETH0 samt uret • Kernen skal kunne håndtere indlejrede afbrydelser • Drivprogramskoden til Ethernet kortet og uret udleveres Datalogi 1F: Multiprogrammering[4]

  46. Sporingsmekanisme • Sporingsmekanisme udviklet af Søren Debois: • en cyklisk hændelsesbuffer: • systemkald • afbrydelser • returnering fra systemkald • brug den fra starten af!! Datalogi 1F: Multiprogrammering[4]

  47. Milepæle • Start med at få brugerprocesser til at køre i brugertilstand: • Start uden afbrydelser • INIT i brugertilstand • Systemkaldsgrænseflade med simpelt kald • Slå afbrydelser til • Udvid systemkald • Dynamisk lagerallokering • Procesoprettelse • Prioriteret skedulering • Tvungent processkift • Tillad afbrydelser fra uret uden processkift • Tillad processkift ved urafbrydelse i brugertilstand • Tillad processkift ved urafbrydelse i begge tilstande Datalogi 1F: Multiprogrammering[4]

  48. Instruktorvagter • Fra på mandag vil der være instruktorvagter alle hverdage • Lørdag den 27. marts er der også instruktorvagt • Kernemaskinen archimedes er reserveret til instruktorvagten under instruktorvagten • Der er ingen øvelser i de næste 3 uger Datalogi 1F: Multiprogrammering[4]

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

More Related