Løsningsforslag til eksamen i INF103

Like dokumenter
Interprosess kommunikasjon. Berkeley Sockets. Hvordan identifiserer jeg hvem jeg vil snakke til? Hva må programmene gjøre?

UNIVERSITETET I OSLO

Løsningsforslag til eksamen i INF103

Løsningsforslag til eksamen i INF103

Dagens program. Operativsystemer Prosesser og systemkall i UNIX Hente prosessens nummer Starte prosesser Vente på prosesser Utføre programmer

IN 147 Program og maskinvare

Del 1 En oversikt over C-programmering

UNIVERSITETET I OSLO

Del 4 Noen spesielle C-elementer

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO

Løsningsforslag til eksamen i INF2270

Programmering i C++ Løsningsforslag Eksamen høsten 2005

Kapittel 1 En oversikt over C-språket

Programmeringsspråket C Del 2. Hans Petter Taugbøl Kragset

Hvordan en prosessor arbeider, del 1

Dagens tema: Datastrukturer

UNIVERSITETET I OSLO

Dagens tema. C-programmering. Nøkkelen til å forstå C-programmering ligger i å forstå hvordan minnet brukes.

Programmeringsspråket C Del 2

Programmeringsspråket C Del 2

Programmeringsspråket C Del 3. Hans Petter Taugbøl Kragset

Programmeringsspråket C Del 2

Løsningsforslag til eksamen i IN 147 og IN 147A

Å løse eksamensoppgaver

TDT4102 Prosedyre og Objektorientert programmering Vår 2015

Oppgave 2: Gå til roten (/) av systemet. Finn minst tre forskjellige måter å gå tilbake til hjemmekatalogen din på.

Oppgave 1 JK-flip-flop (Total vekt 20%)

Dagens tema. Nyttige programmer Programmet make. Flyt-tall Representasjon av flyt-tall. Standarden IEEE 754. Systemkall i Unix

Oversikt. Introduksjon Kildekode Kompilering Hello world Hello world med argumenter. 1 C programmering. 2 Funksjoner. 3 Datatyper. 4 Pekere og arrays

Dagens tema. LC-2 LC-2 er en «ekstrem-risc»; den har 16 instruksjoner og 3 adresseringsmåter.

Del 2 Tabeller, arrays, strenger

UNIVERSITETET I OSLO

INF1000: noen avsluttende ord

Dagens tema INF1070. Info om C. Cs preprosessor. Feilsøking. Dag Langmyhr,Ifi,UiO: Forelesning 31. januar 2005 Ark 1 av 29

Informasjon om C. Dagens tema INF1070 INF1070 INF1070 INF1070. Den viktigste kilden til informasjon om C (utenom en god. C-funksjonene.

Løsningsforslag til eksamen i IN 147(A)

IN 147 Program og maskinvare

Dagens tema C, adresser og pekere

Ark 3 av 26. printf("i adresse %08x ligger b med verdien %d.\n", &b, b); printf("i adresse %08x ligger a med verdien %d.

IN 147 Program og maskinvare

UNIVERSITETET I OSLO

Programmeringsspråket C

IN 147 Program og maskinvare

Dagens tema. Mer om C Enkle datatyper Sammensatte datatyper: Vektorer og matriser Tekster Mengder Strukturer Unioner Ringbuffere

Dagens tema. Kort repetisjon om rutiner. Programmering i C Variable og adresser. Vektorer. Tekster. Preprosessoren. Separat kompilering

UNIVERSITETET I OSLO

Programmeringsspråket C Del 3

Oving 2. Oppgave 1. #include <stdio.h> int main(int argc, char **argv) { char *navn = argv[1]; printf ("Navnet ditt er %s\n", navn); } Oppgave 2

public static <returtype> navn_til_prosedyre(<parameter liste>) { // implementasjon av prosedyren

Generell informasjon

Dagens tema INF2270. Cs preprosessor. Separat kompilering av C funksjoner. C og minnet. Dag Langmyhr,Ifi,UiO: Forelesning 5. februar 2007 Ark 1 av 15

IN 147 Program og maskinvare

TDT4102 Prosedyreog objektorientert programmering Vår 2016

UNIVERSITETET I OSLO

TDT4102 Prosedyreog objektorientert programmering Vår 2016

Programmeringsspråket C Del 3

Løsningsforslag til 2. del av Del - EKSAMEN

TDT4258 Eksamen vår 2013

Dagens tema INF1070. Vektorer (array er) Tekster (string er) Adresser og pekere. Dynamisk allokering

Oppsummering av IN147 siste del Operativsystemer Parallellisering Veien videre

Programmeringsspråket C Del 3

INF1000: noen avsluttende ord

Programmeringsspråket C Del 3

UNIVERSITETET I OSLO

Dagens tema: Parallellstyring

Dagens tema. C-programmering. Nøkkelen til å forstå C-programmering ligger i å forstå hvordan minnet brukes.

Programmeringsspråket C Del 2. Michael Welzl

Løsningsforslag til eksamen i IN 147(A)

public static <returtype> navn_til_prosedyre(<parameter liste>) { // implementasjon av prosedyren

Dagens tema. Rutiner i LC-2 Og her er tilsvarende kode for LC-2: Funksjoner i C Her er det samme programmet i C: Kort repetisjon om rutiner

UNIVERSITETET I OSLO

Cs preprosessor. Dagens tema. Betinget kompilering

Generelt om permanent lagring og filsystemer

Vektorer. Dagens tema. Deklarasjon. Bruk

Dagens tema. Nyttige programmer Programmet make. Hvis én fil endres, hvilke filer må da kompileres på nytt?

Obligatorisk oppgave 1 INF1020 h2005

Intro Rask kode x86-op Optimalisering Inline-kode Konklusjon

En oppsummering (og litt som står igjen)

Innhold. Oppgave 1 Oversettelse (vekt 15%)

løsningsforslag-uke5.txt

Litt om Javas class-filer og byte-kode

Pekere og vektorer. Dagens tema. I C gjelder en litt uventet konvensjon:

Dagens tema. Det siste om C Pekere og vektorer. Pekere til pekere. Vanlige pekerfeil. struct-er og typedef. Lister. Feilsøking

programeksempel Et større En større problemstilling Plan for forelesingen Problemstillingen (en tekstfil) inneholdt ordet "TGA"

Informasjon Prøveeksamen i IN1000 høsten 2018

Innhold uke 4. INF 1000 høsten 2011 Uke 4: 13. september. Deklarasjon av peker og opprettelse av arrayobjektet. Representasjon av array i Java

Løsningsforslag til eksamen 24. november 2015

Oppgave 1 - Linux kommandolinje (%)

Prosesser. Dagens tema. Hva er en prosess? En prosess er et program under utførelse.

IN 147 Program og maskinvare

Et større programeksempel. Hvordan løse et reelt problem med en objektorientert fremgangsmåte

består av 7 sider inklusiv denne forsiden og vedlegg. Kontroller at oppgaven er komplett før du begynner å besvare spørsmålene.

Forelesning 5. Diverse komponenter/større system

Del 3. Pekere RR 2016

UNIVERSITETET I OSLO

Eksamensoppgave i TDT4258 Energieffektive datamaskinsystemer

TDT4102 Prosedyre og Objektorientert programmering Vår 2014

Transkript:

Løsningsforslag til eksamen i INF103 Dag Langmyhr (oppgave 2 og 5) Olav Lysne (oppgave 3 og 6) 15. desember 2001 Sigbjørn Næss (oppgave 1 og 4) 1 Boolsk algebra Sannhetsverditabellen i deloppgave a er vist i tabell 1. a 2 a 1 a 0 F 1 F 2 0 0 0 0 0 0 0 1 1 0 0 1 0 1 0 0 1 1 0 1 1 0 0 1 0 1 0 1 0 1 1 1 0 0 1 1 1 1 0 0 Tabell 1: Sannhetsverditabell for oppgave 1a Ut fra denne tabellen ser man at F 1 = a 2 a 1 a 0 + a 2 a 1a 0 + a 2a 1 a 0 og at F 2 = a 2 a 1a 0 + a 2 a 1 a 0 + a 2 a 1 a 0. Skjemaet er rett frem gitt disse to ligningene. Kall to stykker av kretsen fra oppgave 1a for henholdsvis K 1 og K 2,og utgangene fra de to kretsene K F 1 1, KF 2 1, KF 1 2 og KF 2 2. G vil være 1 når enten K F 1 1 = KF 1 2 = 1 eller K F 2 1 = 1 og a 3 = a 4 = a 5 = 0 eller K F 2 2 = 1 og a 0 = a 1 = a 2 = 0. For å implementere G trenger man dermed to stykker av kretsen fra oppgave a, seks invertere, tre AND-porter og én OR-port, som vist i figur 1 på neste side. (Denne kretsen kan lett forenkles.) 2 Oversettelse Jeg har skrevet funksjonen litt anderledes (men den fungerer likt!) for å gjøre den enklere å oversette. Dette er ingen forutsetning for å få en god karakter; en oversettelse «rett frem» vil bli bedømt som like god. 1 ;;; Rutinenavn: maxa 2 ;;; Synopsis: Finner største element i en vektor. 3 ;;; Signatur i C: short maxa (short a[], short n) 4 ;;; Inn-parametre: R0: adressen til a 5 ;;; R1: n 6 ;;; Ut-parametre: R0: den største verdien 7 ;;; 8 ;;; Teknikk: 1

a 0 a 1 a 2 K 1 F 1 F 2 G a 3 F 1 a 4 a 5 K 2 F 2 Figur 1: Løsning på oppgave 1b 9 ;;; Følgende C-kode er oversatt: 10 ;;; 11 ;;; short maxa (short *a, short n); 12 ;;; { 13 ;;; short max = *a; 14 ;;; 15 ;;; while (--n > 0) { 16 ;;; ++a; 17 ;;; if (max - *a < 0) max = *a; 18 ;;; } 19 ;;; 20 ;;; return max; 21 ;;; } 22 ;;; 23 ;;; Denne versjonen vil alltid gi samme resultat som den som er gitt 24 ;;; i oppgaven, men den egner seg bedre for oversettelse til LC2. 25 ;;; 26 ;;; Registre: R0: a 27 ;;; R1: n 28 ;;; R2: *a 29 ;;; R3: max 30 31 maxa: st R2,saveR2 ; /* Gjem unna R2 32 st R3,saveR3 ; og R3. */ 33 ldr R3,R0,#0 ; max = *a; 34 35 loop: add R1,R1,#-1 ; --n 36 brnz exit ; while ( > 0) { 37 38 add R0,R0,#1 ; ++a; 39 ldr R2,R0,#0 ; t = - *a; 40 not R2,R2 ; /* -*a beregnes som 41 add R2,R2,#1 ; (not *a)+1. */ 42 add R2,R2,R3 ; if (max + t 43 brzp loop ; < 0) { 44 ldr R3,R0,#0 ; max = *a; 45 br loop ; } } 46 2

47 exit: add R0,R3,#0 ; R0 = max; 48 ld R2,saveR2 ; /* Hent tilbake R2 49 ld R3,saveR3 ; og R3. */ 50 ret ; return R0; 51 52 saver2:.fill 0 ; Gjemmested for R2 53 saver3:.fill 0 ; og R3. 3 Socket-programmering Det viktige i deloppgave a er at studentene viser at de har forstått hva som må til for å få den skisserte kommunikasjonsløsningen til å fungere. Det dreier se altså om å få overført de riktige dataene, samt å håndtere det at enkelte deler av det de må overføre har en udefinert lengde. Mitt forslag er følgende: 1. Oppkobling 2. Overføring av to tegn som angir lengde på filnavnet. Her antas det at ingen filnavn er lengre enn 99 tegn langt. 3. Overføring av filnavnet med n tegn, hvor n er lik det antall som ble kommunisert under punkt to. 4. Overføring av 12 tegn som angir tidspunktet for når prislisten skal tas i bruk. 5. Overføring av tre tegn som angir lengden på den første linjen i prislisten. 6. Så lenge det ikke er angitt at den neste linjen inneholder 0 tegn (a) Overføring av en linje i prislisten med det antall tegn som tidligere har blitt kommunisert. (b) Overføring av tre tegn som angir lengden på den neste linjen i prislisten. 7. Nedkobling. Dette lar seg også løse ved å først angi antall tegn på hele filen (inkludert linjeskift), hvorpå det hele overføres samlet altså uten while-løkke. Funksjonene safereadbyte, saferead, safewrite og TCPlyttesocket i deloppgave b er forelest, og det holder derfor at de henviser til forelesningsnotatene for disse. Hoveddelen av denne oppgaven består derfor i programmeringen av main. 1 #include <netinet/in.h> 2 #include <sys/socket.h> 3 #include <netdb.h> 4 #include <stdio.h> 5 #include <string.h> 6 7 8 /* Leser nøyaktig ett byte fra en socketforbindelse */ 9 char safereadbyte(int so) 10 { 11 int bytes; 12 char buf[1]; 13 14 bytes = read(so, buf, 1); 15 if (bytes<0) { 3

16 perror("error in saferead"); 17 if (close(so)) perror("close"); 18 exit(1); 19 } 20 if (bytes<=0) { 21 printf("server: end of file on %d\n",so); 22 if (close(so)) perror("close"); 23 exit(1); 24 } 25 return buf[0]; 26 } 27 28 /* Leser nøyaktig l bytes fra en socketforbindelse */ 29 int saferead(int so, char buf[], int l) 30 { 31 int i; 32 for (i=0; i<l; i++){ 33 buf[i]=safereadbyte(so); 34 } 35 return l; 36 } 37 38 /* Skriver til socket på samme måte som "write", men gir i tillegg 39 en feilmelding dersom det ikke gikk bra */ 40 int safewrite(int so, char buf[], int l) 41 { 42 int i; 43 if (i=write(so, buf, l)==0) 44 { 45 printf("kunne ikke skrive til socket"); 46 exit(1); 47 } 48 return i; 49 } 50 51 /* Oppretter en TCP lyttesocket. Klienter er forventet å opprette 52 forbindelse på det portnummerer som blir sendt med som parameter */ 53 54 55 int TCPlyttesocket(int portnummer) 56 { 57 struct sockaddr_in serveraddr, clientaddr; 58 int clientaddrlen; 59 int request_sock; 60 int i; 61 62 /* Opprett request-socket */ 63 if ((request_sock = socket(af_inet, SOCK_STREAM, IPPROTO_TCP)) < 0) { 64 printf("feil under oppretting av socket\n"); 65 exit(1); 66 } 67 68 /* Opprett adressestruct */ 69 bzero((void *) &serveraddr, sizeof(serveraddr)); 70 serveraddr.sin_family = AF_INET; 71 serveraddr.sin_addr.s_addr = INADDR_ANY; 72 serveraddr.sin_port = htons(portnummer); 73 74 /* Tillat socketen å gjenbruke et portnummer som forrige inkarnasjon 75 av tjeneren fremdeles kan tenkes å legge beslag på */ 76 i = 1; 77 setsockopt(request_sock, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)); 4

78 79 /* bind adressen til socketen */ 80 if (bind(request_sock, (struct sockaddr *)&serveraddr, sizeof serveraddr) < 0) { 81 printf("feil under bind\n"); 82 exit(1); 83 } 84 85 /* aktiver lytting på socketen */ 86 if (listen(request_sock, SOMAXCONN) < 0) { 87 printf("feil under listen\n"); 88 exit(1); 89 } 90 91 return request_sock; 92 } 93 94 95 main(int argc, char *argv[]) 96 { 97 int lyttesocket, datasocket; 98 struct sockaddr_in klientaddr; 99 int klientaddrlen, intlengde; 100 char tidspunkt[12], filnavnlengde[2],filnavn[50],lengde[3], buffer[121]; 101 102 FILE *fil; 103 104 /* Start lytting på et portnummer */ 105 lyttesocket = TCPlyttesocket(2100); 106 107 /* Ta imot oppkobling fra klienten */ 108 klientaddrlen = sizeof(klientaddr); 109 datasocket = accept(lyttesocket,(struct sockaddr *)&klientaddr, &klientaddrlen); 110 if (datasocket < 0) printf("feil under tilkobling av klienten \n"); 111 112 113 /* ta imot filnavnet */ 114 saferead(datasocket, filnavnlengde, 2); 115 saferead(datasocket, filnavn, atoi(filnavnlengde)); 116 117 /* Åpne filen */ 118 filnavn[atoi(filnavnlengde)] = \0 ; 119 fil = fopen(filnavn, "w"); 120 121 /* ta imot tidspunktet filen skal tas i bruk */ 122 saferead(datasocket, tidspunkt, 12); 123 124 /* Så lenge du ikke har mottatt en tom linje - fortsett lesingen */ 125 126 /* les inn lengden på første posten */ 127 saferead(datasocket, lengde, 3); 128 intlengde = atoi(lengde); 129 130 /* Så lenge du ikke har mottatt en tom linje - fortsett lesingen */ 131 while (intlengde!= 0) { 132 saferead(datasocket, buffer, intlengde); 133 buffer[intlengde] = \0 ; 134 fprintf(fil, "%s \n", buffer); 135 136 /* les inn lengden på neste posten */ 137 saferead(datasocket, lengde, 3); 138 intlengde = atoi(lengde); 139 } 5

140 141 /*lukk filen*/ 142 fclose(fil); 143 144 /* lukk lsocketene */ 145 close(lyttesocket); 146 close(datasocket); 147 148 /* Informer systemet om den nye prislisten */ 149 newpricelist(filnavn, tidspunkt); 150 } 4 Flervalgsoppgave Rikige svaralternativ er vist i tabell 2. a b c d e f g h 3 1 4 3 4 4 1 2 Tabell 2: Riktig svar på oppgave 4 Kommentar til 4b Om man ikke har kalkulator, kan man enten regne 2 20 =(2 10 ) 2 = 1024 1024 eller man kan ressonere: 2 10 er omtrent 1000; da er 2 20 omtrent 1 000 000. Siden svaret må være et partall, må det være alternativ 1. 5 Programmet time Det viktigste i denne oppgaven er ikke tidtagingen (hvor koden kan kopieres rett fra oppgaveteksten) men prosesshåndteringen. Siden programmet som skal utføres er oppgitt med fullt filnavn, blir koden ganske enkel: 1 #include <limits.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <time.h> 5 #include <sys/times.h> 6 #include <sys/types.h> 7 #include <unistd.h> 8 #include <sys/wait.h> 9 10 #include "safefork.c" 11 12 extern char **environ; 13 14 int main (int argc, char *argv[]) 15 { 16 int status; 17 time_t start = time(null); 18 struct tms ts; 19 20 if (argc < 1) { 21 printf("usage: time command [param...]\n"); exit(1); 6

22 } 23 24 if (safefork() == 0) { 25 /* Barnet: */ 26 execve(argv[1], &argv[1], environ); 27 perror("time"); exit(0); 28 } 29 30 wait(&status); 31 times(&ts); 32 printf(" real %4ds\n", time(null)-start); 33 printf(" user %4ds\n", (ts.tms_utime+ts.tms_cutime)/clk_tck); 34 printf(" sys %4ds\n", (ts.tms_stime+ts.tms_cstime)/clk_tck); 35 return 0; 36 } 6 Operativsystemer På denne oppgaven er det svært mange svar som vil være fornuftige. Det viktige her er derfor ikke om de har «gjettet riktig», men at den begrunnelsen de gir for sine valg demonstrerer at de har forstått problemområdet. 6a Her finnes det prosesser med harde sanntidskrav. De må slippe til CPU-en med en viss fast frekvens. Det gjør at vi må ha en preemptiv skeduleringsmeknisme. Når vi ser bort fra nedlasting til disk og brukergrensesnittet, er de kravene som stilles av de andre prosesstypene ganske like. Vi foreslår derfor en enkelt round-robin skedulering mellom disse prosessene. For å tilfredsstille de kravene prosessene har om prosentvis andel av CPU-ens tid, må antallet prosesser begrenses. Dette overlates til høynivåskeduleringen. For brukergrensesnittets del foreslår vi her at den inngår i round robinskeduleringen på lik linje med de andre. På den måten blir det enklere å sikre at brukergrensesnittet ikke konsumerer så mye CPU-tid at den ødelegger for en filmavspilling for eksempel. De prosesene som kun driver med nedlasting av data kan (men må ikke) skeduleres for seg med lavest prioritet. Man må i tilfelle sørge for at de ikke opplever «sulting». Det kan for eksempel sikres ved at høynivåskeduleringen ikke slipper til så mange sanntidsprosesser at det ikke blir noe CPU-tid igjen. 6b Ofte er det bare tilgjengelighet av tilstrekkelig internminne som vurderres under høynivåskedulering. I dette tilfellet er det en del sanntidsprosesser som krever tilgang til en viss prosentandel av CPU-ens tid. Derfor er det naturlig her å vurdere CPU-tid ved høynivåskeduleringen, slik at det ikke slippes til flere prosesser enn det faktisk er regnekraft til. 6c Filene som skal håndteres her skal skrives og leses kun sekvensielt. Siden de også er av fast størrelse (en film og et musikkstykke endrer ikke størrelse) peker sekvensiell allokering seg ut. Det gir imidlertid to problemer: 7

Fragmentering. Det kan lett oppstå en situasjon hvor den ledige plassen på disk er delt opp i så mange små stykker at det ikke kan finnes en sekvensiell enhet som er stor nok Under opptak og innlesing av en film/et stykke kan man ofte på forhånd ikke avgjøre hvor stor den er. Følgelig er det vanskelig å vite hvor stort sekvensielt lagringsområde en trenger. Disse problemene kan lettest løses ved periodisk defragmentering og å tillate at en fil kan bestå av flere sammenhengende sekvenser (for eksempel ved pekere, eller indekser). 6d Ettersom vi over har valgt sekvensiell allokering, blir det viktig å finne en metode for håndtering av ledig diskplass som muliggjør enkel gjenfinning av lange sekvenser av ledige blokker. Et «bitmap» med en bit per blokk som angir om den er ledig eller ikke er derfor å foretrekke fremfor Kø/pekerkjede. Ulempen ved dette valget er at vi ikke lenger så lett kan kontrollere at den sist slettede filen ikke er den første som blir overskrevet. Det er likevel rimelig å ofre «angrefrist» på sletting av filer for å effektivisere disklesingen her. 8