---
# System prepended metadata

title: SO lista 9+3

---

# SO lista 9+3

## Zadanie 1
![](https://i.imgur.com/stLsi1f.png)

Współdzielone i wyścigi to raczej zrozumiałe pojęcia pzdr.

```cnt``` raczej tu będzie sprawiało problemy, gdyż jest statyczną zmienną i jest inicjalizowana raz a potem zawsze używane w tej funkcji.
```strtab``` też jest współdzielone, ale nie ma tutaj żadnego wyścigu.
```vargp``` nie wydaje się być wyścigiem albo być współdzielone, jest to po prostu argument funkcji thread. Poza tym vargp jest zmienane tylko przed odpaleniem kolejnego wątku
```argc``` jest zmienną lokalną funkcji main, funkcja thread nie ma do niej dostępu więc argc nie jest współdzielone
```argv[0]``` nie czaję tego zbytnio, ale raczej jest współdzielone (?) bo pointer na argv jest przechowywany w strtab?

## Zadanie 2
![](https://i.imgur.com/BUdWdRd.png)

![](https://i.imgur.com/cEa2sR4.png)

Czyli critical section - kawałek kodu w którym albo czytamy albo modyfikujemy dane współdzielone z innym procesem (i też zgaduję wątkiem).

### Rozwiązanie problemu:
![](https://i.imgur.com/iSOvMTD.png)
![](https://i.imgur.com/BuOj1Ff.png)

### Czemu nie możemy używać interrupt disable?
![](https://i.imgur.com/iR9MR3k.png)


### Czemu chcemy jak najmniejsze sekcje krytyczne?
![](https://i.imgur.com/g7bHjGz.png)

Sekcje krytyczne wymuszają działanie jednego wątku w danym momencie - im mniejszy ten czas, tym większe p i tym lepszy speedup.

Fine-grained locking - lockawanie mniejszy paczek danych aby polepszyć wydajność programu. Można z tym przegiąć jeśli przygotowywanie locków zajmuje więcej czasu.

## Zadanie 3

![](https://i.imgur.com/yVcGmLp.png)

Generalnie chcemy uzyskać funkcję atomową do zmiany stanu lock'a aby użyć ją w mechaniźmie lockowania.

### Compare and swap:
![](https://i.imgur.com/EHiCutn.png)

### Spin lock
![](https://i.imgur.com/cwzBCoL.png)

Tutaj wystarczyło by po prostu podmienić testandset na compareandswap i tyle. Całkiem prosty mechanizm, a musi być po prosty żeby był szybki i nie było szansy na przeskakiwanie pomiędzy threadami w czasami zmiany stanu locka.

![](https://i.imgur.com/fDnuAyW.png)

niestety lock ten nie jest fair. 

### Obliczeniówka

Ughhhh. Po pierwsze round-robin to zwykła karuzela, gdzie wybieranie kolejnych wątków następuje po kolei bez żadnych priorytetów. Wynik zależy również od ilości procesorów, gdyż na jednym procesorze oczywiście będzie więcej zmarnowanych cykli procesora. Niezbyt rozumiem tej części zadania sory

~Paweł i Skowi
Spoko my też nie wiemy o chuj tu chodzi, dużo zmiennych jest niepodanych, doszliśmy do tego że możesz mieć, coś takiego, że P - czas wykonywania sekcji krytycznej, R - reszta aż do zakończenia, i są algosy co dają procesowi czas procesora aż do zakończenia procesu więc by kosztowało nas przejście każdego procesu do sekcji krytycznej (P + K)*(n-1) + P vs Robin by to zrobił w P * n

## Zadanie 4

![](https://i.imgur.com/9FJkt4z.png)

![](https://i.imgur.com/4a3DLpv.png)

Generalnie busy-waiting to po prostu takie uga buga robi inf loopa aż coś się zmieni w danych. Jest to gorsze pod tym względem, że czytanie tych danych i sprawdzanie ich zmian może być wolne, meanwhile spinlock może co najwyżej tracić cykle procesora.


### Blokady usypiające

![](https://i.imgur.com/sQP1Bth.png)

prosta struktura kolejki pozwala na usypianie wątków a potem budzenie ich w przyszłości.



### Yield

Tu baaaaardzo zalecam obczajenie [3, 28.13] który super to tłumaczy, ale z grubsza chodzi o to, że jak mamy nasz spinlock, to mamy duże marnowanie cykli procesora. Wymyślili więc takie coś jak funkcja yield(), które sprawi że wątek zstępuje z procesora i pozwala następnemu od razu wejść na jego miejsce. Jest to szybsze niż robienie while'a przez cały kwant czasu naszego wątku, ale dalej pewne problemy pozostają: dalej mamy dużo operacji, bo dla każdego wątku mamy check locka a potem yielda, i dalej może wystąpić sytuacja w które dany wątek nigdy nie wejdzie do locka (wygłodzenie).

### Czemu potrzebny jest setpark

![](https://i.imgur.com/90OFth7.png)

Mamy tutaj race condition. Jeśli wątek A jest tuż przed wywołaniem park() w 22 linijce, i nastąpi przeskok na wątek B który zwolni lock w unlock(), to najpierw wywołany zostanie unpark na wątku A a potem dopiero park(), co doprowadzi do tego, że wątek A będzie spał w wieczność. Dodane zatem setpark(), który mówi, że wątek zostanie uśpiony.

![](https://i.imgur.com/i6t6A4D.png)

Wówczas jeśli było przerwanie w postaci unparka, to wątek A zamiast usnąć na park() po prostu od razu z niego wyjdzie, pomijając etap spania.

## Zadanie 5

![](https://i.imgur.com/uQ3SQdr.png)

### Warunki do zakleszczenia

![](https://i.imgur.com/wSM4xP2.png)

### Jak zapobiec deadlockom

![](https://i.imgur.com/o6LIchT.png)
![](https://i.imgur.com/7e3e0Tv.png)
![](https://i.imgur.com/1KebUbC.png)
![](https://i.imgur.com/KHo6jGc.png)
![](https://i.imgur.com/83rpqFV.png)
![](https://i.imgur.com/wo0u6ok.png)


Co do lockdepa PRZECZYTAJ FRAGMENT CUDNEJ PRACY PODANEJ W PODPOWIEDZI.
There ya go leniwy gnojku dosłownie to przeczytałem nienawidzę ciebie i wszystko co reprezentujesz swoją osoba jpierdolęęęęęęęęęęęęęe
![](https://i.imgur.com/I7jQLFo.png)


## Zadanie 6 i 7 (bardzo podobne)

![](https://i.imgur.com/jMzQA46.png)

W skrócie w 6 mamy problem taki

proces 1 zaczyna dochodzi przed momentem ustawienia turn = id; i przełączamy się na proces 0. Zobaczmy że turn == id (standardowo 0) więc od razu wchodzi do sekcji krytycznej. wracamy do procesu 1 i on robi turn = id więc turn == id i też wchodzi do sekcji krytycznej => gówno nie działa

Za to w 7 trzeba poczytać o tym. Ale peterson dobry ziomo ogarnął by działało. Idea jest taka, że jak np proces 1 jest w sekcji krytycznej to jego blocked = 1 oraz turn == 0 więc nawet jak przełączymy się na proces 0 to nie będzie w stanie iść dalej.

chyba wystarczy przy tablicy na palcach rozważyć przypadki czy coś

## zadanie 8
![](https://i.imgur.com/cTwRGax.png)


rozw z hacka innej osoby mówi
![](https://i.imgur.com/OVmaBqX.png)
ale czemu to ma się psuć? 
idk 

raczej skip albo się wymyśli do 16

## zadanie 9
![](https://i.imgur.com/6NMPBqY.png)
ngl jedno z ciekawszych zadań

a) błąd w 6 linijce czyli dodajemy do pełnej kolejki

Producer daje jedną rzecz
Consumer zjada ją i robimy context switch przed linijką 15 (bo kolejka jest pusta)
Producer zapełnia kolejke i idzie spać w linijce 5
Context switch i budzimy producera
Dodajemy do pełnej kolejki

błąd w 13 linijce jakiś symetryczny

Producer produkuje jedną rzecz i context switch przed 8 linijką
consumer budzi się i je, kolejny obrót while i jak zobaczy że pusta kolejka i pójdzie spać to wracamy do Producera i go budzimy
myk mamy pop na pustej

b) kleszcza możemy złapać tak

zapełniamy kolejke context switch przed 5 linjką 
Consumer dostaje kontrolę i opróżnia wszystko (wakeup nie działa bo producer nie śpi)
widzi że kolejka pusta to idzie spać
context swiitch na producera i on też idzie spać
oba procesy słodko śpią

