Uke 12 - Linux kildekode, nice, fork, effektivitet, Docker

Oppgaver til mandag 17. - fredag 21. mars

  1.  
    #! /bin/bash

    pid=$1

    while [ "true" ] 
    do
    ticks1=$(cut -d' ' -f14 /proc/6231/stat)
    sleep 1
    ticks2=$(cut -d' ' -f14 /proc/6231/stat)
    diff=$(( $ticks2 - $ticks1 ))
    echo $diff
    done

  2. 335 + 27 + 36 = 398 systemkall er definert i denne filen(tellingen starter på 0). entry_64.S inneholder systemkall-rutiner og er skrevet i assembly.
  3. 35 forskjellige språk mm. C er det klart vanligste, fulgt av Assembly, hele 372.000 linjer med Assembly-kode. Totalt 21.200.769 linjer og det tilsvarer 733 Tanenbaum-bøker, en over 36 meter høy stabel. Utviklingskostnadene er anslått til 974 millioner dollar, eller ca 10 milliarder norske kroner.
    ───────────────────────────────────────────────────────────────────────────────
    Language                 Files     Lines   Blanks  Comments     Code Complexity
    ───────────────────────────────────────────────────────────────────────────────
    C                        29456  20279528  2926828   2391103 14961597    2058261
    C Header                 21396   6309144   592587   1038871  4677686      44263
    Device Tree               3520    955998   118300     56011   781687          3
    Plain Text                3002    220788    38289         0   182499          0
    ReStructuredText          2712    560680   133520         0   427160          0
    Makefile                  2608     65850     9995     11134    44721        416
    Assembly                  1291    371881    33138      2226   336517       6206
    YAML                      1252    123646    21699      5723    96224          0
    Shell                      605     96732    16379     11947    68406       5282
    JSON                       332    176173        0         0   176173          0
    gitignore                  264      1345        5       258     1082          0
    Python                     126     38867     2060      2438    34369       1652
    Perl                        59     45820     4963      3819    37038       3162
    SVG                         59     38792       78      1159    37555          0
    BASH                        55      2131      299       292     1540        228
    Extensible Styleshe…        15       300       39         0      261          0
    AWK                         12      1977      213       193     1571          0
    Happy                        9      5804      695         0     5109          0
    LEX                          9      2783      349       304     2130          0
    C++                          8      2273      235        72     1966        312
    LD Script                    8       339       43        33      263          0
    CSV                          6       205        1         0      204          0
    Autoconf                     5       341       24        20      297          5
    Unreal Script                5       716      108       162      446         24
    License                      4       406       79         0      327          0
    Bazel                        2       694      144       138      412          9
    C++ Header                   2       125       11        55       59          2
    HEX                          2      1512        0         0     1512          0
    Module-Definition            2       124       15         0      109          4
    Systemd                      2        92       14         0       78          0
    CSS                          1       137       28        29       80          0
    Gherkin Specificati…         1       252       28        50      174          0
    Ruby                         1        29        4         0       25          1
    Vim Script                   1        42        0         0       42          3
    sed                          1        12        2         5        5          0
    ───────────────────────────────────────────────────────────────────────────────
    Total                    66833  29305538  3900172   3526042 21879324    2119833
    ───────────────────────────────────────────────────────────────────────────────
    Estimated Cost to Develop (organic) $974,161,407
    Estimated Schedule Effort (organic) 187.972279 months
    Estimated People Required (organic) 460.418780
    ───────────────────────────────────────────────────────────────────────────────
    Processed 948707806 bytes, 948.708 megabytes (SI)
    ───────────────────────────────────────────────────────────────────────────────
        
  4. (Oblig)
  5. (Oblig)
  6. Generelt må man ha root-rettigheter for å gi negativ nice-verdi:
    sudo renice -20 22764
    
    hvor 22764 er PID for prosessen man vil gi høyest mulig prioritet. Men dette fungere nå ikke lenger på Linux-VMene; det fungerer på data2500, men der har dere ikke sudo-rettigheter. Se løsningsforslaget. Fra tabellen const int prio_to_weight[40] som er vist nedenfor kan man se at vektforholdet mellom en prosess som har nice-verdi -20 og en som har nice-verdi 19 er 88761 til 15. Så om bare de to kjører vil den første få en andel på 88761/(88761+15) = 0.9998 eller 99.98% og den andre en andel på 0.02%. I praksis er det vanskelig å se annent at den ene får 99.9% og den andre forsvinnende lite. Men om man starter 11 andre regneprosesser (som hver har en vekt på 1024), ser man at hver av dem får en prosent, mens prosessen med -20 får 89%, siden den har en vekt som er 89.000. Dermed har nice -20 prosessen en vekt på 89 av totalt 100, mens hver av de 11 andre har en vekt på en.
  7. Hvis en prosess øker nice-verdien med en, minskes størrelsen på timeslicen(antall ticks) den hadde med 20%. Hvor stor prosentandel totalt prosessen ender opp med avhenger også av hvor mange andre prosesser som bruker CPU. Hvis for eksempel to prosesser kjører med nice-verdi null, får begge 50% CPU-tid. Anta at de har 100 ticks hver. Da har begge opprinnelig 100/(100+100)=0.5 eller 50% CPU-tid hver. Hvis så den ene øker sin nice-verdi til 1, vil den minske antall ticks med 20% til 80 og den får da totalt 80/(100+80)=0.444 eller ca 44%, mens den andre får 56%. Om man øker nice verdien en gang til med en, minser prosessens ticks med ytterligere 20% til 64 og den får da 64/(100 + 64)=0.39 eller 39% og den andre får 61%. Hvis man kjører to CPU-intensive regnejobber på en VM, vil man se akkurat disse tallene med top, om ingen andre prosesser bruker CPU samtidig. Om man øker nice til 10, vil prosessen sittet igjen med 10 ticks og 9% CPU-tid.

    Hvis man starter med tre prosesser og gir den ene nice-verdi en, får den 80/(80 + 100 + 100)=0.28 eller 28% og de to andre får 36% hver. Med nice-verdi to, får den 64/(64 + 100 + 100)=0.24 eller 24% og de to andre 38% hver. Igjen ser man det samme med top og tre regneprosesser.

    Vekten som gis avhengig av nice-verdi hentes av scheduleren fra en tabell. Denne kan sees i /usr/src/linux-source-3.2/kernel/sched.c i arrayet static const int prio_to_weight[40].

    static const int prio_to_weight[40] = {
     /* -20 */     88761,     71755,     56483,     46273,     36291,
     /* -15 */     29154,     23254,     18705,     14949,     11916,
     /* -10 */      9548,      7620,      6100,      4904,      3906,
     /*  -5 */      3121,      2501,      1991,      1586,      1277,
     /*   0 */      1024,       820,       655,       526,       423,
     /*   5 */       335,       272,       215,       172,       137,
     /*  10 */       110,        87,        70,        56,        45,
     /*  15 */        36,        29,        23,        18,        15,
    };
    
    Av tabellen ser vi at nice-verdi -20 har høyeste vekt, 88761, en prosess med nice-verdi 0 har 1024, mens høyeste nice-verdi på 19 gir en vekt på 15.

  8.  
    #include <stdio.h>
    #include <sys/types.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/wait.h>

    int main(){

    int i,id,pid,mypid,ppid;
    id = getpid();
    printf ("Fork demo!\n Jeg er parent-prosess med pid = %d \n",id);
    sleep(2);
    pid = fork();     /* Prosessen lager nå en ny uavhengig prosess
                         I den nye barne-prosessen er $pid = 0
                         I foreldre prosessen er $pid = barnets PID */
    if (pid == 0)
      {
        mypid = getpid();
        ppid  = getppid();
        printf("       Jeg er child (mypid = %d) av parent med pid = %d.\n",mypid,ppid);
        printf("       Here er variabelen pid = %d.\n",pid);
        for (i = 1;i < 10;i++)
          {
            printf("       %d \n",i);
            sleep(1);
          }
        printf("       Child prosess avslutter.\n");
        exit(0);
      } 
    else
      {
        sleep(2);
        printf("Parent %d venter på child %d her...\n",id,pid);
        wait(&pid); 
        printf("Child har avsluttet, Parent avslutter!\n");
      }

    }

     
    #! /usr/bin/perl

    print "\n";
    print "Fork demo! I am the parent (pid =  $$) \n";

    $pid = fork();

    if ($pid == 0)
       {
            $ppid = getppid;
            print "   I am the child (cid = $$) of parent with pid = $ppid.\n";
            sleep 5;

            $pid2 = fork();

            if ($pid2 == 0)
            {
                $ppid = getppid;
                print "       I am the child (cid = $$) of parent with pid = $ppid.\n";
                sleep 5;
                print "       This is the grandchild process exiting.\n";
                exit(0);
            }
            else
            {
                print "   Parent $$ waiting for child $pid2 here...\n";
                wait();
                print "   Grandchild finished, it's parent quitting too !\n";
                exit(0);
            }
      }
    else
      {
        print "Parent $$ waiting for child $pid here...\n";
        wait();
        print "Child finished, Parent quitting too !\n";
      }

  9. Det er fordi at child har blitt foreldreløs og da tildeles init-prosessen med pid = 1 rollen som fosterforelder.
  10. (Oblig)
  11. (Oblig)
  12. sum.bash:     TIMES = 1;
    sum.php:     $TIMES = 8;
    sum.cpp:  int TIMES = 11;
    Sum.java: int TIMES = 19;
    sum.perl:    $TIMES = 60;
    
    Veldig mye mindre forskjell mellom bash og de andre i dette tilfellet. En faktor tusen mindre for C/C++. Overraskende at Perl (og Java) er raskere enn C++, men det er trolig mulig å optimalisere Cpp-koden.
  13. (Oblig)