Örebro universitet
Institutionen för naturvetenskap och teknik
Thomas Padron-McCarthy (thomas.padron-mccarthy@oru.se)









Tentamen i

Operativsystem för civilingenjörer

torsdag 17 augusti 2023

Gäller som tentamen för:
DT513G Operativsystem för civilingenjörer, provkod A001


Hjälpmedel: Ordbok för översättning.
Poängkrav: Maximal poäng är 30. För godkänt betyg krävs 18 poäng.
Resultat: Meddelas senast 15 arbetsdagar efter tentamensdatum.
Återlämning av tentor: Elektroniskt via webbportalen Studenttjänster.
Examinator och jourhavande: Thomas Padron-McCarthy, telefon 070 - 73 47 013.




LYCKA TILL!

Formelsamling

20 = 1 224 = 16777216
21 = 2 225 = 33554432
22 = 4 226 = 67108864
23 = 8 227 = 134217728
24 = 16 228 = 268435456
25 = 32 229 = 536870912
26 = 64 230 = 1073741824
27 = 128 231 = 2147483648
28 = 256 232 = 4294967296
29 = 512 233 = 8589934592
210 = 1024 234 = 17179869184
211 = 2048 235 = 34359738368
212 = 4096 236 = 68719476736
213 = 8192 237 = 137438953472
214 = 16384 238 = 274877906944
215 = 32768 239 = 549755813888
216 = 65536 240 = 1099511627776
217 = 131072 241 = 2199023255552
218 = 262144 242 = 4398046511104
219 = 524288 243 = 8796093022208
220 = 1048576 244 = 17592186044416
221 = 2097152 245 = 35184372088832
222 = 4194304 246 = 70368744177664
223 = 8388608 247 = 140737488355328

2x * 2y = 2x+y

Uppgift 1 (3 p)

Förklara skillnaderna mellan applikationsprogram, systemprogram och operativsystemkärnan.


Uppgift 2 (3 p)

a) Förklara skillnaderna mellan funktionsanrop och systemanrop.

b) Ett systemanrop är normalt mycket långsammare än ett funktionsanrop. Förklara varför!


Uppgift 3 (5 p)

Här är ett C-program för Linux:

#include <stdio.h>
#include <unistd.h>

int x = 0;

int main(void) {
    int y = 0;
    if (fork() == 0) {
        x = x + 1;
        y = y + 1;
        printf("child: x = %d, y = %d\n", x, y);
    }
    else {
        x = x + 2;
        y = y + 2;
        printf("parent: x = %d, y = %d\n", x, y);
        if (fork() == 0) {
            x = x + 3;
            y = y + 3;
            printf("another child: x = %d, y = %d\n", x, y);
        }
    }
    printf("x = %d, y = %d\n", x, y);
}


a) Vad skrivs ut när programmet körs?

b) Kan det bli olika utskrifter från gång till gång, och vad beror det i så fall på?


Uppgift 4 (6 p)

Här är ett annat C-program för Linux:

#include <stdio.h>
#include <pthread.h>

#define NR_THREADS 1000

volatile int x = 0;

void *thread_body(void *arg) {
    int y = 0;
    x = x + 1;
    y = y + 1;
    return NULL;
}

int main(void) {
    int z = 0;
    x = x + 1;
    z = z + 1;
    printf("Startar! x = %d, z = %d\n", x, z);
    pthread_t threads[NR_THREADS];
    for (int i = 0; i < NR_THREADS; ++i)
        pthread_create(&threads[i], NULL, thread_body, NULL);
    for (int i = 0; i < NR_THREADS; ++i)
        pthread_join(threads[i], NULL);
    printf("Klart! x = %d, z = %d\n", x, z);
}

a) Vad skrivs ut när programmet körs?

b) Kan det bli olika utskrifter från gång till gång, och vad beror det i så fall på?

c) Kan det bli deadlock? Förklara!

d) Min dator har en 8-kärnig processor med hyperthreading, så den kan köra 16 trådar parallellt. Men här kör vi 1000 trådar samtidigt! Hur är det möjligt? Förklara!


Uppgift 5 (5 p)

Här är tre olika C-program för Linux som kopierar filen gamla till filen nya. Vad kan man anta om hur snabba de är på att kopiera en stor fil, jämfört med varandra? Diskutera och förklara!

Programmet cp-1.c:

#include <stdio.h>

int main(void) {
    FILE *gamla = fopen("gamla", "r");
    FILE *nya = fopen("nya", "w");

    int c;
    while ((c = getc(gamla)) != EOF)
        putc(c, nya);

    fclose(gamla);
    fclose(nya);
}

Programmet cp-2.c:

#include <fcntl.h>
#include <unistd.h>

int main(void) {
    int gamla = open("gamla", O_RDONLY);
    int nya = open("nya", O_WRONLY | O_CREAT | O_TRUNC, 0666);

    char data[1];
    int n;
    while((n = read(gamla, data, 1)) > 0)
        write(nya, data, n);
    
    close(gamla);
    close(nya);
}

Programmet cp-3.c:

#include <fcntl.h>
#include <unistd.h>

int main(void) {
    int gamla = open("gamla", O_RDONLY);
    int nya = open("nya", O_WRONLY | O_CREAT | O_TRUNC, 0666);

    char data[1000000];
    int n;
    while((n = read(gamla, data, 1000000)) > 0)
        write(nya, data, n);
    
    close(gamla);
    close(nya);
}


Uppgift 6 (8 p)

Vi har en byteadresserad dator som arbetar med virtuella minnesadresser på 18 bitar och fysiska minnesadresser på 14 bitar. Datorns fysiska minne delas mellan de olika processerna som körs. Av bitarna i adresserna används 10 bitar för offset inom en sida eller frame.

a) Hur stor (i bytes) är den virtuella minnesrymden?

b) Hur stor (i bytes) är den fysiska minnesrymden?

c) Hur stor (i bytes) är en minnessida ("page")?

d) Någon föreslår att i stället ha minnessidor som är exakt 1000 byte stora. Är det ett bra förslag? Förklara!

e) Hur många minnessidor är den virtuella minnesrymden indelad i?

f) Hur många olika ramar ("frames") finns det i det fysiska minnet?

g) Den fysiska minnesrymden är mindre än den virtuella. Hur är det möjligt att en process ändå kan använda hela den virtuella minnesrymden? Förklara!

h) Vi kör flera processer samtidigt. Hur är det möjligt, när det inte ens finns plats för en enda process hela virtuella minnesrymd i det fysiska minnet? Förklara!