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









Tentamen i

Operativsystem för civilingenjörer

onsdag 8 januari 2025

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 34. För godkänt betyg krävs 20 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!

Tabeller och formler

20 = 1 224 = 16777216 248 = 281474976710656
21 = 2 225 = 33554432 249 = 562949953421312
22 = 4 226 = 67108864 250 = 1125899906842624
23 = 8 227 = 134217728 251 = 2251799813685248
24 = 16 228 = 268435456 252 = 4503599627370496
25 = 32 229 = 536870912 253 = 9007199254740992
26 = 64 230 = 1073741824 254 = 18014398509481984
27 = 128 231 = 2147483648 255 = 36028797018963968
28 = 256 232 = 4294967296 256 = 72057594037927936
29 = 512 233 = 8589934592 257 = 144115188075855872
210 = 1024 234 = 17179869184 258 = 288230376151711744
211 = 2048 235 = 34359738368 259 = 576460752303423488
212 = 4096 236 = 68719476736 260 = 1152921504606846976
213 = 8192 237 = 137438953472 261 = 2305843009213693952
214 = 16384 238 = 274877906944 262 = 4611686018427387904
215 = 32768 239 = 549755813888 263 = 9223372036854775808
216 = 65536 240 = 1099511627776 264 = 18446744073709551616
217 = 131072 241 = 2199023255552 265 = 36893488147419103232
218 = 262144 242 = 4398046511104 266 = 73786976294838206464
219 = 524288 243 = 8796093022208 267 = 147573952589676412928
220 = 1048576 244 = 17592186044416 268 = 295147905179352825856
221 = 2097152 245 = 35184372088832 269 = 590295810358705651712
222 = 4194304 246 = 70368744177664 270 = 1180591620717411303424
223 = 8388608 247 = 140737488355328 271 = 2361183241434822606848

2x * 2y = 2x+y
2x / 2y = 2x-y

Uppgift 1 (5 p)

Här är ett C-program för Linux, där funktionen do_stuff saknas:

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

#define NR_STUFFS 10

volatile long long int data = 0;
pthread_mutex_t lock;

int main(void) {
    pthread_mutex_init(&lock, NULL);
    pthread_t threads[NR_STUFFS];
    for (int i = 0; i < NR_STUFFS; ++i)
        pthread_create(&threads[i], NULL, do_stuff, (void*)i);
    for (int i = 0; i < NR_STUFFS; ++i)
        pthread_join(threads[i], NULL);
    printf("The value of data is %lld.\n", data);
}

Beskriv vad om händer när programmet körs för var och en av de följande versionerna av do_stuff, och vilka skillnaderna mellan de olika programkörningarna blir, särskilt med avseende på utskrifter och körtid.

a)

void *do_stuff(void *arg) {
    for (int i = 0; i < 1000000; ++i) {
        pthread_mutex_lock(&lock);
        ++data;
        pthread_mutex_unlock(&lock);
    }
    return NULL;
}

b)

void *do_stuff(void *arg) {
    pthread_mutex_lock(&lock);
    for (int i = 0; i < 1000000; ++i) {
        ++data;
    }
    pthread_mutex_unlock(&lock);
    return NULL;
}

c)

void *do_stuff(void *arg) {
    for (int i = 0; i < 1000000; ++i) {
        ++data;
    }
    return NULL;
}

Uppgift 2 (5 p)

Vi fortsätter med programmet från uppgiften ovan, och använder a-versionen av do_stuff. Nu byter vi i stället ut main-funktionen. Beskriv vad om händer när programmet körs för var och en av de följande versionerna av main, och vilka skillnaderna mellan de olika programkörningarna blir, särskilt med avseende på utskrifter och körtid.

a)

int main(void) {
    pthread_mutex_init(&lock, NULL);
    pthread_t threads[NR_STUFFS];
    for (int i = 0; i < NR_STUFFS; ++i) {
        pthread_create(&threads[i], NULL, do_stuff, (void*)i);
        pthread_join(threads[i], NULL);
    }
    printf("The value of data is %lld.\n", data);
}

b)

int main(void) {
    pthread_mutex_init(&lock, NULL);
    for (int i = 0; i < NR_STUFFS; ++i) {
        do_stuff((void*)i);
    }
    printf("The value of data is %lld.\n", data);
}

c)

int main(void) {
    pthread_mutex_init(&lock, NULL);
    for (int i = 0; i < NR_STUFFS; ++i) {
        if (fork() == 0) {
            do_stuff((void*)i);
            exit(0);
        }
        else {
            int waitstatus;
            wait(&waitstatus);
        }
    }
    printf("The value of data is %lld.\n", data);
}

Uppgift 3 (7 p)

Vi har en byteadresserad dator som arbetar med virtuellt minne. Virtuella adresser består av 50 bitar och fysiska adresser består av 40 bitar. Sidstorleken ("page size") är 1024 byte.

a) Vi har satt i så mycket primärminne i datorn att hela den fysiska adressrymden kan utnyttjas. Hur mycket primärminne har datorn?

b) Hur många olika ramar ("frames") är det fysiska minnet indelat i?

c) Hur stor är den virtuella adressrymden?

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

e) Både virtuella minnessidor ("pages") och fysiska ramar ("frames") numreras med början på noll. Vi tittar i sidtabellen ("page table") för en process, och ser att den virtuella adressen 1 motsvaras av den fysiska adressen 2049. Kan man, baserat på detta, säga något om vilken fysisk adress som den virtuella adressen 2000 motsvaras av? Förklara!

f) Kan man, under samma förutsättningar, säga något om vilken fysisk adress som den virtuella adressen 1000 motsvaras av? Förklara!

Uppgift 4 (5 p)

a) Vad menas i operativsystemsammanhang med schedulering ("schemaläggning")?

b) För schemaläggningen används flera olika köer. Vilka köer är det, och vad har man varje kö till?

c) Var finns dessa köer?

Uppgift 5 (6 p)

a) Vad menas med spinlock och busy-wait (även kallat spinning)?

b) Ge exempel på när det kan vara lämpligt för operativsystemkärnan att använda dessa.

c) Under vilka omständigheter bör operativsystemkärnan absolut inte använda dessa?

d) Varför är det normalt inte lämpligt att använda dem i vanliga program?

Uppgift 6 (3 p)

a) Vad är ett systemanrop, och hur skiljer de sig från vanliga funktionsanrop?

b) Brukar systemanrop vara snabbare eller långsamare än vanliga funktionsanrop? Vad beror skillnaden på?

Uppgift 7 (3 p)

Operativsystemkärnan kan ha flera olika buffertar (på engelska "buffer") där den lagrar data. Ge exempel på vad dessa buffertar används till, och förklara varför man har valt att ha dem.