• No results found

Uppgift 1: Schemal¨ aggning(10p)

N/A
N/A
Protected

Academic year: 2021

Share "Uppgift 1: Schemal¨ aggning(10p)"

Copied!
17
0
0

Loading.... (view fulltext now)

Full text

(1)

Tentamen

Datorteknik och realtidssystem, TSEA81

Datum 2020-03-16

Lokal TER4

Tid 14-18

Kurskod TSEA81

Provkod TEN1

Kursnamn Datorteknik och realtidssystem

Institution ISY

Antal uppgifter 5

Antal sidor

(inklusive denna sida)

17

Kursansvarig Anders Nilsson L ¨arare som bes¨oker skriv-

salen

Anders Nilsson Telefon under skrivtiden 013-28 2635 Bes¨oker skrivsalen Cirka 15 och 17

Kursadministrat¨or Eva Zurawski 013-28 6806 Till ˚atna hj ¨alpmedel Inga

Betygsgr ¨anser

Po¨ang Betyg

41-50 5

31-40 4

21-30 3

0-20 U

Viktig information

• Alla svar ska ha en motivation om inget annat anges. Om du svarar med pro- gramkod r¨aknas kommentarer i programkoden som motivation. Svar som ej ¨ar motiverade kan leda till po¨angavdrag.

• Om inget annat anges ska du anta att schemal¨aggningsmetoden som anv¨ands

¨

ar priority based preemptive scheduling.

• Om inget annat anges antas semaforer vara starka.

• Om du ¨ar os¨aker p ˚a det exakta namnet f¨or en viss funktion, skriv en kom- mentar om vad funktionen g¨or s ˚a kommer vi troligtvis att f¨orst ˚a vad du menar.

(Detsamma g¨aller syntaxen f¨or programspr ˚aket C.)

• T¨ank igenom din l¨osning NOGGRANT och anv¨and dig av de l¨osningsprinciper som kursen f¨orevisar. Okonventionella och tvetydiga l¨osningar ger po¨angavdrag.

• Svara ALDRIG med pseudokod, om det inte specifikt efterfr ˚agas. Pseudokod blir l¨att tvetydig och d¨armed inte bed¨omningsbar.

• L¨amna INTE in denna tentamen tillsammans med l¨osningarna. En inl¨amnad tentamen med eventuella anteckningar kommer inte att beaktas som en l¨osning.

• Skriv l¨asbart! Ol¨asbar text kan inte bed¨omas och ger d¨armed inga po¨ang.

Lycka till!

(2)

Uppgift 1: Schemal¨ aggning(10p)

Ett realtidssystem med ett antal processer ska schemal¨aggas p ˚a en dator som enbart har en processor/k¨arna, dvs endast en process ˚at g ˚angen kan exekvera.

F¨oljande krav g¨aller:

• P1 ska arbeta/k¨ora under n tidsenheter i tidsintervallet [i*12, (i+1)*12]

• P2 ska arbeta/k¨ora under 2 tidsenheter i tidsintervallet [i*9, (i+1)*9]

• P3 ska arbeta/k¨ora under 2 tidsenhet i tidsintervallet [i*6, (i+1)*6]

d¨ar i ¨ar ett heltal och i ≥ 0, och n ¨ar ett heltal och n ≥ 0.

Tidr¨akningen startar vid t=0 f¨or alla processer. Du kan anta att uppstart av pro- cesser och processbyte inte tar n ˚agon tid alls. Eventuellt missat arbete under n ˚agot tidsintervall ackumuleras inte till kommande tidsintervall.

(a) (5p) Antag att schemal¨aggningsmetoden Earliest Deadline First (EDF) anv¨ands.

Man vill att P1 ska k¨ora s ˚a mycket som m¨ojligt, dvs ber¨akna st¨orsta m¨ojliga v¨arde p ˚a n s ˚a att specifikationerna uppfylls. Visa sedan vad som h¨ander n¨ar programmet k¨ors genom att rita ett tidsdiagram.

Hur stor blir den faktiska utnyttjandegraden?

(b) (5p) Antag att schemal¨aggningsmetoden Rate Monotonic Scheduling (RMS) anv¨ands, samt att n har samma v¨arde som i uppgift (a). Visa vad som h¨ander n¨ar programmet k¨ors genom att rita ett tidsdiagram.

Kommer specifikationerna ovan att uppfyllas? Hur stor blir den faktiska ut- nyttjandegraden?

(3)

Uppgift 2: Teori(10p)

(a) (3p) En kritisk region kan vara relativt odelbar eller absolut odelbar. Vad ¨ar skillnaden? Ge n ˚agot exempel p ˚a var det finns en absolut odelbar kritisk region i ett realtidssystem.

(b) (2p) Beskriv tv ˚a huvudsakliga skillnader mellan en semafor och en mutex.

Beskrivningen f ˚ar inte underf¨orst ˚a n ˚agra egenskaper hos en semafor eller en mutex.

(c) (2p) Ge ett exempel p ˚a n ˚agon del i ett realtidssystem som m ˚aste skrivas i assembler, dvs som inte g ˚ar att skriva i ett h¨ogniv ˚aspr ˚ak som C, samt f¨orklara varf¨or den delen m ˚aste skrivas i assembler?

(d) (2p) Om prioritetsbaserad p ˚atvingad schemal¨aggning anv¨ands och det finns flera processer med samma h¨ogsta prioritet att v¨axla till vid ett processbyte, vilka vanliga metoder skulle schemal¨aggaren kunna anv¨anda d ˚a? Beskriv tv ˚a metoder.

(e) (1p) Om tv ˚a processer k¨or parallellt i var sin k¨arna i samma processor och exakt samtidigt f¨ors¨oker l ˚asa samma mutex, hur best¨ams det d ˚a vilken pro- cess som f ˚ar l ˚asa mutexen?

(4)

Uppgift 3: Barri¨ ar med meddelandehantering(10p)

Ett visst datorsystem inneh ˚aller ett maximalt antal ber¨akningsprocesser, MAX PROC.

Varje ber¨akningsprocess utf¨or ett ber¨akningsarbete och m¨ater sin egen k¨ortid. Nu

¨

onskar man ber¨akna medelv¨ardet av k¨ortiden f¨or ett antal av dessa ber¨aknings- processer, dvs inte n¨odv¨andigtvis alla ber¨akningsprocesser.

F¨oljande krav finns:

• F¨or att ber¨akna medelv¨ardet ska en barri¨ar anv¨andas, till vilken respektive ber¨akningsprocess proc meddelar sin k¨ortid.

• Barri¨arfunktionens header ser ut s ˚asom: void barrier(int limit)

• Antalet ber¨akningsprocesser som samtidigt kan vara i barri¨aren best¨ams av variabeln limit.

• Medelv¨ardet ska ber¨aknas n¨ar gr¨ansen limit har uppn ˚atts.

• Det ber¨aknade medelv¨ardet ska meddelas till anv¨andarinterfaceprocessen ui.

• Det ska vara m¨ojligt att n¨ar som helst, via ett meddelande fr ˚an processen ui, s¨atta ett nytt v¨arde p ˚a limit.

• Om det nya v¨ardet p ˚a limit ¨ar l¨agre ¨an det nuvarande antalet processer i barri¨aren s ˚a ska medelv¨ardet d ˚a ber¨aknas f¨or det antal processer som finns i barri¨aren.

• N¨ar medelv¨ardet ber¨aknats ska processerna i barri¨aren starta en ny omg ˚ang av sitt ber¨akningsarbete.

• Varje process f ˚ar endast bidra med sin k¨ortid en g ˚ang till ett och samma medelv¨arde.

Meddelandefunktionerna finns deklarerade s ˚asom:

/* send message function

msg : pointer to message buffer len : length of message

portid : message queue port id priority : priority of message */

void message_send(char *msg, unsigned int len, unsigned int portid, unsigned int priority)

/* receive message function msg : pointer to message

max_len : maximum length of message received portid : message queue port id */

void message_receive(char *msg, unsigned int max_len, unsigned int portid) Ber¨akningsprocessfunktionens header ser ut s ˚asom:

/* calculation process function with process id as argument */

void proc(int id)

(5)

Barri¨arprocessfunktionens header ser ut s ˚asom:

/* barrier process function with initial limit as argument */

void barrier(int limit) Huvudprogrammet ser ut s ˚asom:

/* main function */

int main(void) {

int pid;

/* initialize message system */

message_init();

/* start barrier process, and initialize limit to MAX_PROC */

pid = fork();

if (!pid) {

barrier(MAX_PROC) }

/* start calculation processes */

int i;

for (i=0; i<MAX_PROC; i++) { pid = fork();

if (!pid) { proc(i);

} }

/* start user interface process */

ui();

return 0;

}

Din uppgift ¨ar att skriva barrier-funktionen. Du m ˚aste ¨aven sj¨alv definiera hur ett meddelande ska se ut och vilka meddelandetyper och meddelandek¨oer som beh¨ovs f¨or att barrier ska fungera enligt kraven ovan.

Du f ˚ar i din l¨osning anta att ¨ovriga processer s¨ander och tar emot meddelanden p ˚a ett s¨att som passar din barrier-funktion, men kraven ovan m ˚aste f¨orst ˚as fortfarande uppfyllas. Dvs, var noga med att kommentera koden och ber¨atta vad dina meddelandetyper har f¨or betydelse.

Du beh¨over allts ˚a inte bry dig om eller visa hur du t¨anker att ber¨akningsprocessen proceller anv¨andarinterfaceprocessen ui f¨or ¨ovrigt ser ut eller fungerar.

Medelv¨ardet kan ber¨aknas som ett heltal, dvs du beh¨over inte anv¨anda flyttal i l¨osningen.

(6)

Uppgift 4: Await och Cause(10p)

F¨oljande funktioner utg¨or Await och Cause i Simple-OS f¨or att v¨anta p ˚a en h¨andelsevariabel respektive signalera p ˚a en h¨andelsevariabel.

/* Await */

void si_ev_await(si_event *ev) {

int pid;

*** ;

if (! *** ( *** , WAIT_LIST_SIZE)) {

pid = *** ( *** , WAIT_LIST_SIZE);

*** (pid);

} else

{

*** ; }

pid = process_get_pid_running();

*** (pid);

*** ( *** , WAIT_LIST_SIZE, pid);

*** ;

*** ; }

/* Cause */

void si_ev_cause(si_event *ev) {

int done;

int pid;

*** ;

done = *** ( *** , WAIT_LIST_SIZE);

while (!done) {

pid = *** ( *** , WAIT_LIST_SIZE);

*** ( *** , WAIT_LIST_SIZE, pid);

done = *** ( *** , WAIT_LIST_SIZE);

}

*** ; }

(7)

Programkod markerad med *** har dock raderats. Varje f¨orekomst av *** ska ers¨attas med n ˚agon av f¨oljande kodsnuttar:

• wait list remove lowest prio

• wait list remove highest prio

• wait list remove one

• wait list remove all

• wait list is empty

• wait list is full

• wait list insert

• ENABLE INTERRUPTS

• DISABLE INTERRUPTS

• unschedule()

• schedule()

• ready list insert

• ready list remove

• ready list is empty

• ready list is full

• ev->mutex->wait list

• ev->mutex->ready list

• ev->wait list

• ev->ready list

• ev->mutex->counter++

• ev->mutex->counter--

Din uppgift ¨ar att skriva ned de kompletta versionerna av si ev await och si ev cause.

F¨or full po¨ang m ˚aste programkoden ¨aven vara kommenterad!

(8)

Uppgift 5: Semaforer och h¨ andelsevariabler(10p)

Betrakta f¨oljande program:

#include <simple_os.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#define BUFFER_SIZE 1

#define STACK_SIZE 5000

stack_item Producer_Stack[STACK_SIZE];

stack_item Consumer_Stack[STACK_SIZE];

/* data structure for buffer */

typedef struct {

/* the buffer itself */

char buffer_data[BUFFER_SIZE];

/* position for next write */

int in_pos;

/* position for next read */

int out_pos;

/* number of elements in the buffer */

int count;

/* semaphore for protection of the buffer */

si_semaphore mutex;

/* event to indicate that the buffer has changed state, from full to non-full or from empty to non-empty */

si_condvar change;

} buffer_data_type;

typedef buffer_data_type* buffer_type;

buffer_type buffer;

/* create buffer: creates a buffer and initialises the created buffer */

buffer_type create_buffer(void) {

/* reference to the created buffer */

buffer_type buffer;

/* allocate memory */

buffer = (buffer_type) malloc(sizeof(buffer_data_type));

(9)

/* start writing at first position */

buffer->in_pos = 0;

/* start reading at first position */

buffer->out_pos = 0;

/* no elements ar stored in the buffer */

buffer->count = 0;

/* initialise semaphore and event variable */

si_sem_init(&buffer->mutex, 1);

si_cv_init(&buffer->change, &buffer->mutex);

return buffer;

}

/* put item: stores an item in buffer */

void put_item(buffer_type buffer, char item) {

/* reserve buffer */

si_sem_wait(&buffer->mutex);

/* check if the buffer is full, and if this is so, wait */

while (buffer->count == BUFFER_SIZE) {

si_cv_wait(&buffer->change);

}

/* store item in buffer */

buffer->buffer_data[buffer->in_pos] = item;

buffer->in_pos++;

if (buffer->in_pos == BUFFER_SIZE) {

buffer->in_pos = 0;

}

buffer->count++;

/* notify other processes that a change has occurred */

si_cv_broadcast(&buffer->change);

/* release buffer */

si_sem_signal(&buffer->mutex);

}

(10)

/* get_item: read an item from the buffer */

char get_item(buffer_type buffer) {

/* item to read from the buffer */

char item;

/* reserve buffer */

si_sem_wait(&buffer->mutex);

/* check if buffer is empty, and if this is so, wait */

while (buffer->count == 0) {

si_cv_wait(&buffer->change);

}

/* read item from buffer */

item = buffer->buffer_data[buffer->out_pos];

buffer->out_pos++;

if (buffer->out_pos == BUFFER_SIZE) {

buffer->out_pos = 0;

}

buffer->count--;

/* notify other processes that a change has occurred */

si_cv_broadcast(&buffer->change);

/* release buffer */

si_sem_signal(&buffer->mutex);

/* return value read */

return item;

}

void producer_task(void) {

char string_to_send[] = "123";

int i;

char item;

while(1) {

for (i=0; i<strlen(string_to_send); i++) {

item = string_to_send[i];

put_item(buffer, item);

printf("P:%c\n",item);

}

si_wait_n_ms(2000);

} }

(11)

void consumer_task(void) {

char item;

while(1) {

item = get_item(buffer);

printf("C:%c\n",item);

} }

/* main */

int main(void) {

/* initialise kernel */

si_kernel_init();

buffer = create_buffer();

/* create tasks */

// High priority:

si_task_create(producer_task, &Producer_Stack[STACK_SIZE-1], 10);

// Low priority:

si_task_create(consumer_task, &Consumer_Stack[STACK_SIZE-1], 20);

/* start the kernel */

si_kernel_start();

/* will never be here */

return 0;

}

(a) (2p) Vad skriver programmet ut fram till dess att producer task v¨antat f¨ardigt i 2000 ms, dvs under f¨orsta varvet i while-loopen? Det r¨acker med ett svar som endast visar sj¨alv utskriften.

(b) (8p) Beskriv varf¨or utskriften blir som den blir i uppgift (a). Var noggrann med att f¨orklara och motivera, g¨arna stegvis. T¨ank p ˚a att beskriva, vad som h¨ander och varf¨or med processerna vid relevanta tillf¨allen, vilka relevanta funktioner som anropas samt bufferns status och inneh ˚all.

(12)

osningsf¨ orslag fr ˚aga 1

F¨oljande notation g¨aller:

# = process running _ = process not running

. = no process running (unused time slot)

| = deadline (met) / = deadline (missed)

1a

F¨or EDF g¨aller att kraven uppfylls om utnyttjandegraden Ue≤ 1, dvs:

n/12 + 2/9 + 2/6 ≤ 1 3n/36 + 8/36 + 12/36 ≤ 1 3n ≤ 16

n ≤ 16/3

Allts ˚a, st¨orsta v¨arde p ˚a n ¨ar 5.

Med EDF schemal¨aggs alltid den process som har kortast tid kvar till deadline. D ˚a fle- ra processer har lika l ˚ang tid kvar och en av dom redan k¨or l ˚ater man den processen forts¨atta f¨or att slippa ett processbyte.

P1_ _ _ _ # # # # # _ _ _|_ _ _ # # # # # _ _ _ _|_ _ # # # # # _ _ _ _ .|

P2_ _ # # _ _ _ _ _|_ _ # # _ _ _ _ _|_ _ _ _ # # _ _ _|_ _ _ _ # # _ _ .|

P3# # _ _ _ _|_ _ _ # # _|_ # # _ _ _|_ _ # # _ _|# # _ _ _ _|_ _ _ # # .|

0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 Alla processer klarar sina deadlines och den faktiska utnyttjandegraden blir 35/36.

Vid tidpunkten t=36 blir samtliga processer samtidigt redo att k¨ora igen, dvs d¨ar b¨orjar f¨orloppet om.

(Kommentar: L¨osningen beh¨over visa hela tidsf¨orloppet (inklusive deadlines) fram till t=36, att k¨orande process forts ¨atter (i f¨orekommande fall), korrekt dra slutsatsen om vilka processer som klarar sina deadlines, att v ¨ardet p ˚a n=5, samt att den faktiska utnyttjandegraden blir 35/36)

1b

MED RMS f ˚ar processerna prioriteter utefter hur ofta de ska k¨oras, dvs ju kortare tidsintervall ju h¨ogre prioritet. Prioriteten bli allts ˚a P3 > P2 > P1. D¨arefter anv¨ands schemal¨aggningsmetoden priority based preemptive scheduling.

P1_ _ _ _ # # _ _ # _ _ #/_ _ # # # # _ _ _ _ # .|_ _ # _ _ # _ _ # # # .|

P2_ _ # # _ _ _ _ _|# # _ _ _ _ _ _ _|_ _ # # _ . _ _ _|# # _ _ _ _ _ _ .|

P3# # _ _ _ _|# # _ _ _ _|# # _ _ _ _|# # _ _ _ .|# # _ _ _ _|# # _ _ _ .|

0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 P1 missar sin deadline vid tidpunkten t=12. P2 och P3 klarar sina deadlines. Den

faktiska utnyttjandegraden blir 34/36 (intervallen t=[23,24],[35,36] blir outnyttjade).

(13)

Vid tidpunkten t=36 blir samtliga processer samtidigt redo att k¨ora igen, dvs d¨ar b¨orjar f¨orloppet om.

(Kommentar: L¨osningen beh¨over visa hela tidsf¨orloppet (inklusive deadlines) fram till t=36, tala om de inb¨ordes prioriteterna f¨or P1, P2 och P3 vid RMS, korrekt dra slutsatsen om vilka processer som klarar sina deadlines (och visa var och vilka som inte g¨or det), visa outnyttjade tidsintervall, samt att den faktiska utnyttjandegraden blir 34/36.)

osningsf¨ orslag fr ˚aga 2

2a

En relativt odelbar kritisk region f ˚ar avbrytas, men ingen annan process f ˚ar anv¨anda gemensam resurs. En absolut odelbar kritisk region f ˚ar inte ens avbrytas (avbrott st¨angs av). Detta f¨orekommer i realtidssystemets k¨arnfunktioner, t ex Wait, Signal, Await, Cause.

2b

En semafor har ett v¨arde ≥ 0, medan en mutex har v¨ardet 0 (l ˚ast) eller 1 (ol ˚ast).

En semafor kan anv¨andas f¨or asymmetrisk/symmetrisk synkronisering, men det g ˚ar inte med en mutex d ˚a den m ˚aste l ˚asas/ol ˚asas inom samma tr ˚ad.

2c

De delar av realtidssystemet som v¨axlar kontext vid ett processbyte m ˚aste g¨oras i assembler d ˚a ett h¨ogniv ˚aspr ˚ak som C saknar m¨ojligheten att g¨ora saker som att spara undan och ˚aterst¨alla CPU:ns kontext p ˚a/fr ˚an processens stack. Specifikt byte av stackpekare, ˚aterst¨allande av CPU:ns registerinneh ˚all samt programr¨aknare.

2d

Tidskvanta : Den process som varit k¨orklar l¨angst tid f ˚ar k¨ora (s k Round-Robin scheduling)

K¨oordning : Den process som ligger f¨or i ready-listan f ˚ar k¨ora (FIFO: First in First Out)

2e

Det avg¨ors i CPU:ns h ˚ardvara, via speciella atomiska assemblerinstruktioner, t ex TAS (Test And Set) eller CAS (Compare And Swap).

(14)

osningsf¨ orslag fr ˚aga 3:

Eftersom antalet processer i barri¨aren kan vara f¨arre ¨an det maximala antalet pro- cesser i systemet (MAX PROC) s ˚a m ˚aste vi h ˚alla reda p ˚a vilka processer som tr¨att in i barri¨aren, f¨or att senare sl¨appa just dessa processer fr ˚an barri¨aren till en ny ber¨akningsomg ˚ang.

Skulle ett nytt v¨arde p ˚a limit vara mindre ¨an count (antalet processer i barri¨aren), eller om count uppn ˚att v¨ardet p ˚a limit s ˚a ¨ar det dags att ber¨akna medelv¨ardet och skicka resultatet till ui(), samt d¨arefter start en ny ber¨akningsomg ˚ang f¨or all processer i barri¨aren.

Problemet med att nya processer kommer in i barri¨aren samtidigt som barri¨aren redan ¨ar full eller d ˚a limit ¨andras l¨oser sig automatiskt med meddelandehantering eftersom inkommande meddelanden k¨oas och barri¨aren hanterar ett meddelande i taget.

#define NO_PID -1

#define PORT_BARRIER 0

#define PORT_UI 1

#define PORT_PROC 10 typedef enum {

ENTER, // message from proc() to barrier() when proc entering barrier

CALC, // message from barrier() to proc() when proc should start new calculation AVG, // message from barrier() to ui() with average run time data

LIMIT // message from ui() to barrier() with new limit value } message_type;

struct message {

message_type type; // message type

int pid; // process id

int data; // runtime, limit or average data };

void barrier(int limit) {

struct message *m; // message pointer char buf[4096]; // message buffer

int count = 0; // number of proc’s in barrier int sum = 0; // sum of runtimes

int pids[MAX_PROC]; // to keep track of pids in barrier int i;

/* initialize pids to NO_PID */

for (i=0; i<MAX_PROC; i++) { pids[i] = NO_PID;

}

while (1)

(15)

{

/* wait for message */

message_receive(buf, 4096, PORT_BARRIER);

m = (struct message *) buf;

switch (m->type) {

case LIMIT: // message from ui() with new limit limit = m->data;

break;

case ENTER: // message from proc() entering barrier pids[count] = m->pid;

sum = sum + m->data;

count++;

break;

default:

break;

}

if (count >= limit) {

/* send average value to ui() /*

m->type = AVG;

m->data = sum / count;

message_send((char *) m, sizeof(*m), PORT_UI, 0);

/* reset total sum */

sum = 0;

/* release all processes from barrier */

while (count > 0) {

count--;

m->type = CALC;

if (pids[count] != NO_PID) {

message_send((char *) m, sizeof(*m), PORT_PROC+pids[count], 0);

pids[count] = NO_PID;

} } } } }

osningsf¨ orslag fr ˚aga 4:

/* Await */

void si_ev_await(si_event *ev)

(16)

int pid;

/* atomic section begins */

DISABLE_INTERRUPTS;

/* among processes waiting for the mutex, make the one with highest prio ready to run */

if (!wait_list_is_empty(ev->mutex->wait_list, WAIT_LIST_SIZE)) {

pid = wait_list_remove_highest_prio(ev->mutex->wait_list, WAIT_LIST_SIZE);

ready_list_insert(pid);

} else

{

/* no processes are waiting, so unlock the mutex */

ev->mutex->counter++;

}

/* now wait on the condition variable, so remove ourself from readylist and insert into event waiting list */

pid = process_get_pid_running();

ready_list_remove(pid);

wait_list_insert(ev->wait_list, WAIT_LIST_SIZE, pid);

/* find new process to run */

schedule();

/* atomic section ends */

ENABLE_INTERRUPTS;

}

/* Cause */

void si_ev_cause(si_event *ev) {

int done;

int pid;

/* atomic section begins */

DISABLE_INTERRUPTS;

/* move all processes waiting on the condition variable to instead wait on the mutex */

done = wait_list_is_empty(ev->wait_list, WAIT_LIST_SIZE);

while (!done) {

pid = wait_list_remove_one(ev->wait_list, WAIT_LIST_SIZE);

wait_list_insert(ev->mutex->wait_list, WAIT_LIST_SIZE, pid);

done = wait_list_is_empty(ev->wait_list, WAIT_LIST_SIZE);

}

/* atomic section ends */

ENABLE_INTERRUPTS;

}

(17)

osningsf¨ orslag fr ˚aga 5:

5a

Programmet skriver ut f¨oljande under f¨orsta varvet i while-loopen f¨or producer task:

P:1 P:2 C:1 P:3 C:2 C:3 5b

Vi kallar producer task f¨or P, och consumer task f¨or C.

1. P (h¨ogst prio) anropar put item med ’1’ (buffern ledig och tom), l¨agger in ’1’ i buffern, si cv broadcast orsakar inget, si sem signal l ˚ater P (h¨ogst prio) forts¨atta.

2. P skriver ut ’P:1’

3. P anropar put item med ’2’ (buffern ledig och full), P flyttas till v¨antelistan f¨or h¨andelsevariabeln change, C blir k¨orande.

4. C anropar get item (buffern ledig och full), l¨aser ’1’, si cv broadcast flyttar P fr ˚an v¨antelistan f¨or change till v¨antelistan f¨or semaforen mutex, si sem signal flyttar P fr ˚an v¨antelistan f¨or semaforen till readylistan och P (h¨ogst prio) blir k¨orande.

5. P forts¨atter i put item (buffern ledig och tom), skriver in ’2’ i buffern. si cv broadcast orsakar inget, si sem signal l ˚ater P (h¨ogst prio) forts¨atta.

6. P skriver ut ’P:2’

7. P anropar put item med ’3’ (buffern ledig och full), P flyttas till v¨antelistan f¨or h¨andelsevariabeln change, C blir k¨orande.

8. C returnerar fr ˚an get item med ’1’.

9. C skriver ut ’C:1’

10. C anropar get item (buffern ledig och full), l¨aser ’2’, si cv broadcast flyttar P fr ˚an v¨antelistan f¨or change till v¨antelistan f¨or semaforen mutex, si sem signal flyttar P fr ˚an v¨antelistan f¨or semaforen till readylistan och P (h¨ogst prio) blir k¨orande.

11. P forts¨atter i put item (buffern ledig och tom), skriver in ’3’ i buffern, si cv broadcast orsakar inget, si sem signal l ˚ater P (h¨ogst prio) forts¨atta.

12. P skriver ut ’P:3’, P st¨aller sig och v¨antar 2000 ms, C blir k¨orande 13. C returnerar fr ˚an get item med ’2’.

14. C skriver ut ’C:2’

15. C anropar get item (buffern ledig och full), l¨aser ’3’, si cv broadcast orsa- kar inget, si sem signal l ˚ater C forts¨atta (endast C ¨ar redo).

16. C skriver ut ’C:3’, anropar get item och blir v¨antande p ˚a h¨andelsevariabeln (buffern tom).

References

Related documents

Som hemarbete ges sedan figurens utskärning

[r]

[r]

[r]

Men sagan fann hon inte annat än i luften den första natten, ty när hon hade gått några steg blev hon rädd att gå mot folk, ty där folk var fanns sex som kunde snappa upp

Antalet glassar som s¨aljs i en liten kiosk en viss sommardag ¨ar Poissonf¨ordelat med ett v¨antev¨arde m som beror p˚a v¨adret.. Ber¨akna sannolikheten att man inte f˚ar s˚alt

(b) Antalet olycksfall under en m˚ anad vid en industri antas vara P oisson(λ)−f¨ ordelad.. Ber¨ akna ML-estimatet

[r]