# SO - Wielkie rewiżyn
## 1 Podstawy
### Najważniejsze pojęcia
#### składowe SO:
* jądro - Współdzielony program, zarządzający działaniem wszystkich innych programów
* Ważne: kernel nie jest osobnym procesem, a częścią każdego istniejącego procesu
* Jądro ma swoją przestrzeń adresową
* Jądro za zmianę kontekstu
* Jądro działa na każdym procesorze osobno
* Odpowiada za schedulling
* Kernel odpowiada za zabijanie procesów
* Tłumaczy zdarzenia sprzętowe na sygnały
* biblioteki
* Bilbioteki współdzielone są oznaczone jako prywatne
* ładowane przez konsolidator dynamiczny
* Rodzaje ładowania bibliotek
* At run time - w trakcie uruchomienia programu
* At load time - Skompilowanie biblioteki
* Library Interpositioning - Przechwytywanie wywołań funkcji bibliotecznych
* Compile time: When the source code is compiled
* Link time: When the relocatable object files are statically linked to form an executable object file
* Load/run time: When an executable object file is loaded into memory, dynamically linked, and then executed.
* powłoka
* Powłoka to program, który odpala programy w imieniu użytkownika
* Shell jest liderem sesji
* Powłoka jest zaprojektowana do działania wiecznie xD
* Nie powinna gromadzić zasobów
* Pamięci
* Procesów potomnych
* Deskryptorów plików
* Jedno zadanie pierwszoplanowe, reszta drugoplanowe
* programy użytkowe - wszystkie programy z których może korzystać bezpośrednio użytkownik
#### zarządzanie zasobami:
* czas procesora
* Czas jaki procesor poświęci na wykonanie jakiegoś zadania
* Kwant czasu ~1ms
* Iluzja równoległego wykonywania zadań - Prawdziwa równoległość na wielu procesorach
* Po wyczerpaniu czasu przychodzi przerwanie zegarowe, procesor przechodzi w tryb jądra i zrzuca rejestry w odpowiednie miejsce. Wybiera następny proces do uruchomienia i zmienia przestrzeń adresową
* Proces nie jest świadomy tej zmiany
* pamięć wirtualna
* Mapowana na pamięć fizyczną pamięć znajdująca się w przestrzeni adresowej każdego procesu
* Pamięć anonimowa - nie wskazuje na żaden plik, zainicjowana zerami
* Może być przechowywana w formie prywatnej lub współdzielonej
* Prywatna - kopia pamięci stworzona na wyłączność dla danego procesu
* Przy modyfikacji - copy-on-write
* Współdzielona - zmiany są widoczne we wszystkich procesach czytających dany fragment w trybie shared
* Page fault
* Normal page fault -
* Mniejszy pagefault - Kiedy adres znajduje się w tablicy stron, ale nie jest przetłumaczony bezpośrednio przez MMU w TLB
* Większy pagefault - Kiedy wpisu nie ma w tablicy stron i musimy zajrzeć do pamięci
* Segmentation Fault - Accesing non-existing page (SIGSEGV)
* SIGSEGV z SEGV_MAPPER - Strona nie była zmapowana w przestrzeni adresowej procesu
* Protection Exception - Violating permmison (SIGSEGV)
* SIGSEGV z SEGV_ACCERR - Strona nie miała odpowiednich uprawnień
* Fork - Copy on write dla mapowań prywatnych
* Execve - Usuwane wszystkie segmenty należące do starej przestrzeni adresowej


* dostęp do urządzeń wejścia-wyjścia - TODO
* przechowywanie danych
* Typy plików
* Plik
* Katalog
* 
* Reprezentacja listowa → liniowe wyszukiwanie. Dodawanie, usuwanie zmiana nazwy plików potencjalnie wymaga przejrzenia całego katalogu
* Pipe - Jednostronna komunikacja między procesami
* Socket - Dwustronna komunikacja między procesami
* Symlink - Dowiązanie symboliczne
* Zawiera ścieżkę do pliku (katalogu), na który wskazuje
* Jeśli jest wystarczająco krótki - jest przechowywany bezpośrednio w i-nodzie
* W.p.p. jest przechowywany w bloku danych
* Po usunięciu pliku wskazuje na pustą przestrzeń
* Hardlink
* Nazwę przechowuje katalog, więc wiele nazw może odnosić się do jednego pliku
* Hardlink wskazuje bezpośrednio na i-node, a nie na plik
* edytując hardlink, edytujemy dane w i-nodzie
* Żeby usunąć plik trzeba usunąć wszystkie dowiązania twarde
* Urządzenia blokowe/znakowe
* i-węzeł (ang. i-node) Opis zasobu dyskowego.
Oprócz atrybutów zawiera wskaźniki na bloki danych i bloki pośrednie (ang. indirect blocks).
* 
* izolacja i współdzielenie
* ```volatile``` - zmienna nie będzie brana pod uwagę przy optymalizacji. Jej wartość zawsze będzie czytana z dysku
* ```Static```
* Static w ciele funkcji zachowuje wartość pomiędzy wywołaniami
* Static jako zmienna / funkcja globalna jest widoczna tylko w pliku, w którym jest deklarowana
* ```__thread```
* Każdy wątek otrzyma swoją kopie tak oznaczonej zmiennej
* sprawdzanie uprawnień dostępu
* Właściciel - grupa - pozostali
* Uprawnienia dla katalogów
* ```r``` - Czytanie katalogu
* ```w``` - Edycja katalogu
* ```x``` - Przeszukiwanie
* ```SUID``` - Plik jest zawsze wykonywany jako użytkownik, który jest właścielem
* ```SGID``` -
* Na pliku - plik jest wykonywany z uprawnieniami grupy będącej właścicielem
* Na katalogu - Wszystkie utworzone pliki w tym katalogu będą miał GID taki jak katalog
* ```sticky bit``` - Pliki w danym katalogu mogą być edytowane tylko przez użytkowników, będących ich właścicielami
* Uprawnienia są sprawdzane w momencie otwarcia pliku
* Uprawnienia sprawdzamy dla euid/egid
* Wymiana tożsamości
* Euid można przełączyć(setuid) na wartość przechowywaną w suid/ruid
* Tożsamość wymieniamy przy wołaniu execve
* ruid niezmieniony
* euid ustawiany na podstawie pliku
* suid kopiowany z efektywnego
#### szeregowanie zadań:
* zadanie
* algorytm szeregowania,
* polityka i mechanizm - round robin
* system wsadowy,
* wieloprogramowość kooperacyjna vs. wywłaszczanie,
* planista,
* dyspozytor
#### wywołania systemowe:
* separacja przestrzeni użytkownika i jądra
* JEST
* przekazywanie parametrów,
* Zazwyczaj trzeba.w
* kopiowanie pamięci z/do jądra
* 
* Podwójne kopiowanie danych:
* jądro kopiuje dane do bufora FILE,
* użytkownik korzystając z funkcji stdio kopiuje dane do własnej pamięci.
* kod błędu - X?D
* Przekazujemy.
* punkt wywłaszczania
* Zawsze.
### Narzędzia
#### śledzenie wykonania:
* ltrace(1) - A library call tracer
* strace(1) - trace system calls and signals
## 2 Procesy
### Najważniejsze pojęcia
#### atrybuty procesu:
* identyfikator procesu - PID
* grupa procesów - PGID
* rodzic - PPID
* właściciel procesu - UID
* priorytet
#### środowisko procesu:
* argumenty procesu,
* ```execve(char *filename, char *argv[], char *envp[])```
* Loads and runs in the current process:
* Executable file filename
* Can be object file or script file beginning with ```#!interpreter``` (e.g., ```#!/bin/bash```)
* …with argument list argv
* By convention ```argv[0]==filename```
* …and environment variable list envp
* “```name=value```” strings (e.g., ```USER=droh```)
* ```getenv```, ```putenv```, ```printenv```
* system plików proc(5),
* proc - process information pseudo-filesystem
* kod wyjścia - wartosci 0-255, domyślnie 0 (poprawnie) reszta oznacza błąd
* standardowe wejście i wyjście - określone przez deskryptory. Can be changed
* katalog roboczy - katalog w którym działa proces (do zobaczenia poprzez ``pwd``). Może być zmieniony ``cd``
* interpreter - procesor
#### zasoby procesu:
* PCB - A process control block is a data structure used by computer operating systems to store all the information about a process
* przestrzeń adresowa - zakres adresów zmapowanych w pamięci wirtualnej dla danego procesu
* segmenty pamięci - 
* zasoby plikopodobne - zasoby, które przypominają, ale nimi nie są.
* Na przykład
* Pliki w proc
* pseudoterminale
* dyski
* Gniazda sieciowe
* urządzenia zewnętrzne
* dzieci - procesy utworzone przy pomocy ``fork``
* ograniczenia - wyobraźnia
#### kontekst:
* przełączanie procesów
* Proces A wchodzi w tryb jądra
* Zachowujemy kontekst prcoesu A
* Wybieramy proces B
* Odzyskujemy kontekst procesu B
* Wracamy do trybu użytkownika
* Obsługujemy sygnały
* moment wywłaszczenia - otóż kurwa dowolny
* nielokalne skoki
* setjmp - funkcja zapamietuje kontekst programu w jump_buf. Przy pierwszym zawołaniu zwraca 0. Zawołana raz, wychodzi kilka razy
* longjmp - Procedura longjmp jest wołana raz i nigdy nie wraca. Ładuje kontekst z jump_buf
* Przekierowanie sterowania do dowolnej(wzglednie) lokacji w programie
* Wykorzystywane do emulowania wyjątków
* Sigsetjmp/Siglongjmp - by zachować sygnały
#### hierarchia procesów:
* proces init
* Pierwszy proces inicjowany przez jądro
* rodzic,
* Proces, który utworzył inny proces
* dziecko,
* proces utworzony przez inny proces
* zombie,
* Proces, który zakończył swoje działanie, ale nie został obsłużony przez rodzica. Dalej zużywa zasoby (np wpis w tabeli procesów)
* sierota,
* Proces, który utracił rodzica - zostaje potem podłączony pod init
* żniwiarz
* najczęściej rodzic - zabija dzieci, które zakończyły swoje działanie
* grupa,
* Każdy proces należy do dokładnie jednej grupy procesów (PGID == PPID)
* sesja
* Pewna liczba grup procesów podłączonych do tego samego terminala sterującego.
* Leaderem sesji jest najczęściej proces powłoki.
* Żeby zostać liderem sesji należy utworzyć sesję ``setsid`` i ustalić terminal sterujący ``tcsetsid``.
* Jeśli powłoka zostanie odłączona od terminala, to dostanie SIGHUP i zdecyduje co zrobić z procesami, którymi zarządza.
#### stan procesu:
- Stany procesu - Opis tego co się aktualnie dzieje z procesem. Wyróżniamy trzy stany:
- Running - proces albo jest w procesorze, albo czeka na obsłużenie przez procesor, albo jest zablokowany. TEn stan dzieli się jeszcze na:
- Executing
- Ready
- Stopped - proces został zatrzymany i nie zostanie wciągnięty przez procesor dopóki nie zostanie obudzony
- Terminated - Zakończony proces, który jeszcze istnieje w systemie, natomiast już nie może zostać przywrócony
- Blocked - Proces który został zablokowany, wyróżniamy dwa podrodzaje:
- Interruptible - Proces oczekuje na zasoby, np w postaci interackji użytkownka, lub pakietów sieciowych. Taki proces będzie odbeirał sygnały
- Uniterruptible - Proces, który oczekuje na hardware condition, w związku z czym nie będzie obsługiwał sygnałów
#### czas życia procesu:
* czas wykonania w przestrzeni użytkownika i jądra,
* Czas, jaki proces spędził w przestrzeni użytkownika i jądra
* czas przebywania w systemie
* uzytkownik + jadro + zmiana kontekstu
#### zarządzanie procesami:
* klonowanie procesów - fork
* zastępowanie obrazu procesu
* 
* ładowanie pliku wykonywalnego - execve
* 
*
* dziedziczenie zasobów
* kończenie procesów
* Proces otrzymuje sygnał, który zmusza go(a konkretniej jądro) do przejścia w stan terminated
* Wyjście z procedury main, czyli domyślne zakończenie programu
* Wywołanie bezpośrdenio funkcji **exit()** (Która też jest wołana po wyjściu z funkcji main, czyli tak na prawdę dwie możliwości).
* wstrzymywanie i kontynuowanie procesów
* Proces zostaje zatrzymany poprzez sygnał SIGSTOP i SIGSTP
* Wznawiamy proces sygnałem SIGCONT
#### sygnały:
* semantyka wybranych sygnałów
* SIGINT
* Interrupt from keyboard
* Default action - TERM
* SIGCHLD
* Child stopped or terminated
* Default action - IGNR
* SIGKILL
* Kill process
* Default action - TERM
* Cannot be blocked, ignored or caught
* SIGHUP
* Hangup detected on controlling terminal or death of controlling process
* Default action - TERM
* SIGTERM
* Termination signal
* Default action - TERM
* Kill generate this signal by default
* SIGSEGV
* Invalid memory reference
* Default action - CORE
* Can be blocked, ignored or caught, but result is undefined
* SIGSTOP
* Stop process
* Default action - STOP
* Cannot be blocked, ignored or caught
* SIGTSTP
* Stop typed at terminal
* Default action - STOP
* SIGCONT
* Continue if stopped
* Default action - CONT
* Cannot be ignored
* Can be caught
* Can be send by any process in the same session
* bitmapa sygnałów oczekujących i blokowanych
* Utrzymywana w jądrze
* Maska pending - Zapalony bit k oznacza, że sygnał k przyszedł. Po obsłużeniu bit zostaje wyzerowany. W szczególności maska nie zapamiętuje liczby tych samych sygnałów
* Maska blocked - zapalony bit k oznacza, że sygnał k jest blokowany
* moment dostarczania sygnałów - Sygnały obsługujemy po wyjściu z kernel space
* źródła wysyłające sygnał
* Jądro, powody:
* Nieprawidłowa operacja
* Zdarzenie zewnętrzne
* Inny proces wysłał sygnał przy pomocy jądra (O ile kredencjały są zgodne)
* oczekiwanie na sygnały
* Stan snu przerywalnego, w którym proces oczekuje na sygnał z urządzenia zewnętrznego / jądra
#### obsługa i interakcja z sygnałami:
* ignorowanie i przechwytywanie sygnałów
* Ignorowanie - brak reakcji na dostarczony sygnał - informacja o ignorowanych sygnałach w SIG_IGN
* Przechwytywanie - wykonywanie czynności określonych w procedurach obsługi sygnału
* procedura obsługi - Ustalona sekwencja czynności, wykonywana w reakcji na dostarczany sygnał
* domyślna akcja - Signal handler ustala które sygnały zostaną obsłużonwe domyślnie poprzez SIG_DFL
* blokowanie sygnałów
* Opóźnianie obługi sygnału
* Nie wszystkie sygnały można zablokować
* Blokowane sygnały są oznaczane w masce blocked
* procedury wielobieżne
* Procedury, które można bezpiecznie wykonywać w przeplocie z innymi operacjami
* Tylko z takich funkcji należy korzystać wewnątrz signal handlera
* Nie to samo co thread safe!
* zagnieżdżone procedury obsługi
* 
* Sygnał z którym weszliśmy do procedury obsługi sygnałów jest blokowany => Głębokość zagnieżdżenia jest z góry ograniczona przez liczbę sygnałów
#### zadania:
* grupa pierwszoplanowa,
* W grupie pierwszoplanowej może być wykonywane tylko jedno zadanie
* Ma bezpośredni dostęp do terminala
* grupy drugoplanowa
* Procesy wykonywane w tle
* Nie mają dostępu do terminala
* Może być wiele grup drugoplanowych
* terminal sterujący
* Zarządza grupami pierwszo i drugoplanowymi. Moze należeć co najwyżej do jednej sesji. Mogą być sesje bez terminala (wtedy działają w tle, na przykład serwery).
#### tożsamość:
* użytkownik
* Procesy dostają tożsamość użytkownika który je uruchomił
* UID
* grupa
* GID
* grupy dodatkowe
* Lista grup, do których należy użytkownik
* zmiana tożsamości
* Tożsamość może zostać odczytana z załadowanego pliku (execve)
* Euid może sie przełączać między wartościami zapisanymi w ruid i suid
* uruchamianie programów ze zmienioną tożsamością
* Na przykład z sudo
* Uruchamiamy program z uprawnieniami użytkownika uprzywilejowanego
* uwierzytelnianie - mechanizm potwierdzania tożsamości, np. podanie hasła
* autoryzacja - proces sprawdzania, czy proces o danej tożsamości ma dostęp do zasobu.
* kredencjały - W bloku kontrolnym każdego procesu przetrzymwane są **kredencjały**, czyli informacja o tym w jaki sposób identyfikuje się użytkownika.
### Wywołania systemowe, biblioteka libc
#### inicjacja i kończenie:
* exit(3)
* cause normal process termination
* All open stdio(3) streams are flushed and closed
* Files created by tmpfile(3) are removed.
* Exit status transmitted to parent
* atexit(3)
* register a function to be called at normal process termination
* returns the value 0 if successful; otherwise it returns a nonzero value
* abort(3)
* cause abnormal process termination
* unblocks SIGABRT and raise that signal
* If signal SIGABRT is ignored or caught, abort set default handling and send signal again, succesfully terminating process
#### zarządzanie procesami:
* fork(2)
* create a child process
* On success, the PID of the child process is returned in theb parent, and 0 is returned in the child.
* On failure, -1 is returned in the parent, no child process is created, and errno is set to indicate the error.
* execve(2)
* execute program
* execve() executes the program referred to by pathname. This causes the program that is currently being run by the calling process to be replaced with a new program, with newly initialized stack, heap, and (initialized and uninitialized) data segments.
* On success, execve() does not return, on error -1 is returned, and errno is set to indicate the error.
* waitpid(2)
* wait for process to change state
* In the case of a terminated child, performing a wait allows the system to release the resources associated with the child
* If a wait is not performed, then the terminated child remains in a "zombie" state
#### środowisko:
* getenv(3),
* get an environment variable
* The getenv() function searches the environment list to find the environment variable name, and returns a pointer to the corresponding value string.
* The getenv() function returns a pointer to the value in the environment, or NULL if there is no match.
* getcwd(3)
* get current working directory
* On success, these functions return a pointer to a string containing the pathname of the current working directory. In the case of getcwd() and getwd() this is the same value as buf.
* On failure, these functions return NULL, and errno is set to indicate the error. The contents of the array pointed to by buf are undefined on error.
* chdir(2)
* chdir() changes the current working directory of the calling process to the directory specified in path.
* On success, zero is returned. On error, -1 is returned, and errno is set to indicate the error.
#### identyfikatory:
* getpid(2)
* Returns the process ID of the calling process
* getppid(2)
* Returns the process ID of the parent of the calling process
#### grupy procesów:
* setpgid(2)
* Set process group
* Is used to move process from one group to another - both process groups must be part of the same session
* Need to be called both in parent process and child process
* getpgid(2)
* getpgid() returns the process group ID (PGID) of the calling process.
#### sygnały:
* signal(2),
* overview of signals
* sigaction(2),
* examine and change a signal action
* The sigaction() system call is used to change the action taken by a process on receipt of a specific signal.
* Can set SIG_DFL/SIG_IGN
* kill(2),
* Jak sama nazwa wskazuje - wysyła sygnał do procesu **:-)**
* pause(2),
* wait for signal
* pause() causes the calling process (or thread) to sleep until a signal is delivered that either terminates the process or causes the invocation of a signal-catching function.
* pause() returns only when a signal was caught and the signal-catching function returned.
* In this case, pause() returns -1, and errno is set to EINTR.
* sigsuspend(2),
* wait for a signal
* sigsuspend() temporarily replaces the signal mask of the calling thread with the mask given by mask and then suspends the thread until delivery of a signal whose action is to invoke a signal handler or to terminate a process.
* If the signal terminates the process, then sigsuspend() does not return.
* If the signal is caught, then sigsuspend() returns after the signal handler returns, and the signal mask is restored to the state before the call to sigsuspend().
* sigsuspend() always returns -1, with errno set to indicate the error (normally, EINTR).
* setprocmask(2)
* examine and change blocked signals
* The signal mask is the set of signals whose delivery is currently blocked for the caller
#### tożsamość procesu:
* setuid(2)
* Sets the effective user ID of the calling process
* Can be used to drop privileges
* if the calling process is privileged
* the real UID and saved set-user-ID are also set.
* setgid(2),
* Sets the group user ID of the calling process
* getuid(2),
* Gets real user ID
* getgid(2)
* Returns the real group ID of the calling process.
* getegid(2)
* Returns the effective group ID of the calling process.
* getgroups(2),
* returns the supplementary group IDs of the calling process in list
* seteuid(2),
* set effective user or group ID
* Unprivileged processes may only set the effective user ID to the real user ID, the effective user ID or the saved set-user-ID.
* Precisely the same holds for setegid() with "group" instead of "user".
* setreuid(2)
* set real and/or effective user or group ID
* setreuid() sets real and effective user IDs of the calling process.
* Supplying a value of -1 for either the real or effective user ID forces the system to leave that ID unchanged.
* Unprivileged processes may only set the effective user ID to the real user ID, the effective user ID, or the saved set-user-ID.
* Unprivileged users may only set the real user ID to the real user ID or the effective user ID.
* If the real user ID is set (i.e., ruid is not -1) or the effective user ID is set to a value not equal to the previous real user ID, the saved set-user-ID will be set to the new effective user ID.
#### nielokalne skoki:
* longjmp(3)
* Nonlocal jump to a saved stack context
* Restores the environment saved by the last call of setjmp(3)
* setjmp(3),
* Save stack context for nonlocal goto
* Saves the stack context/environment in env for later use by longjmp(3).
* siglongjmp(3)
* Similar to longjmp, restores signal mask saved by sigsetjmp(3)
* sigsetjmp(3)
* Similar to setjmp, saves signal mask for later use by siglongjmp(3)
#### terminal sterujący:
* tcsetpgrp(3)
* Set terminal foreground process group
* isatty(3)
* Test whether a file descriptor refers to a terminal
### Narzędzia
#### zarządzanie:
* top(1) - wyświetla procesy
* The top program provides a dynamic real-time view of a running system.
* ps(1),
* Wyświetla zamrożony, aktualny stan procesów
* kill(1)
* wysyła określony sygnał do procesu
#### tożsamość:
* id(1),
* print real and effective user and group IDs
* getent(1)
* get entries from Name Service Switch libraries
#### zasoby:
* lsof(1)
* list open files
#### czas życia:
* time(1)
* Wyświetla czas procesora dla danego zadania (rzeczywisty, w przestrzeni jądra i w przestrzeni użytkownika)
*
## 3 Pliki i systemy plików
### Najważniejsze pojęcia
#### model pliku:
* sekwencyjny
* W dostępie sekwencyjnym możliwe są następujące operacje: odczyt kolejnego rekordu, dopisanie rekordu na końcu pliku, przesunięcie wskaźnika bieżącej pozycji (bieżącego rekordu) na początek, ewentualnie przesuwanie wskaźnika o podaną liczbę jednostek w przód, czy w tył. Identyfikacja rekordu dla wykonywanej operacji wynika zatem z historii wcześniejszych operacji dostępu.
* swobodny dostęp
* pliki na których można zawołać mmap i seek.
* Umozliwiaja przeprowadzenie diagnostyki (smartctl)
* adresowanie bajtowe - #TODO
* adresowanie rekordami
* Zorganizowanie pliku jako lista rekordów (katalog)
* Read i write nie są dostosowane do takiego adresowania
#### typy plików:
* zwykły
* Plik mający deskryptory
* O swobodnym dostępie
* potok
* Jednokierunkowy zasób plikopodobny
* Ma deskryptory
* gniazdo
* Dwukierunkowy zasób plikopodobny
* Również ma deskryptory
* urządzenie,
* Zasób plikopodobny służący do komunikacji z urządzeniami zewnętrznymi
* Czytany jest w trybie kanonicznym
* Nie posiada trwale zapisanych danych
* katalog
* Węzeł posiadający wskaźniki na pliki i zasoby plikopodobne
* Jedno to abstrakcja jaką tworzy system plików dla użytkownika
#### ścieżka:
* absolutna
* Ścieżka "całościowa" - od katalogu ```/```
* względna i znormalizowana,
* Ścieżka z bieżącego katalogu
* katalog roboczy
* katalog w którym działa proces
* katalog nadrzędny
* Katalog do którego prowadzi symlink ```..```
#### otwarte pliki:
* deskryptor pliku,
* Identyfikator pliku wykorzystywany przez system operacyjny. Po wykonaniu operacji otwarcia pliku, deskryptor pliku może być wykorzystywany wielokrotnie przez wywołanie systemowe w operacjach wejścia/wyjścia. Deskryptor pliku jest zwracany przez funkcje systemowe z rodziny open
* 
* tablica deskryptorów
* Struktura przechowująca wszystkie deskryptory
* struktura pliku w jądrze
* deskryptory
* Nagłówek
* Sekcja na dane
* flagi
* O_RDONLY, O_WRONLY, O_RDWR - Odpowiadają za uprawnienia z jakmi otwieramy plik. Ważne jest to, że uprawnienia są sprawdzane **tylko** w momencie otwierania pliku.
* O_CREAT, O_TRUNC - Flagi do tworzenia plikow. Jezeli plik nie istnieje to mozemy utworzyc plik, lub jezeli istnieje to mozemy przyciac do 0 i potem pisac.
* O_APPEND - Dopisujemy do pliku. Atomowo przenosimy się na koniec pliku, a następnie zapisujemy.
* O_DIRECTORY - Służy do otwierania katalogów. Odmawiamy otwarcia pliku, który nie jest katalogiem.
* kursor,
* W plikach o swobodnym dostępie
* Rozdzielczość 1 bajtu
* Można ustawić przy pomocy lseek
* Przemieszczenie kursora poza koniec pliku skutkuje utworzeniem dziury
* współdzielenie plików
* Po wykonaniu forka dziecko domyślnie współdzieli otwarte pliki z rodzicem (poprzez zachowaną tablicę deskryptorów)
*
* wycieki deskryptorów plików,
* następuje gdy skończymy czytać plik, nie zamykając jego deskryptorów
* przekierowania
* Przepinanie standardowego deskryptora wyjścia na otwarty deskryptor pliku, do którego chcemy przekierować wyjście
#### operacje wej.-wyj.:
* przerywalne i nieprzerywalne
* TODO
* short count,
* Zwrócenie przez read/write mniejszej wartości niż zakładana
* Występuje:
* Kiedy przeczytamy EOF
* Kiedy czytamy z terminala
* Kiedy czytamy z gniazd sieciowych
* tryby działania (nieblokujący, dopisywanie, ...)
#### pliki zwykłe:
* bloki
* Pliki są przechowywane w blokach
* dziury,
* Luki, które zostają między częściami danych pliku (część bloku jest nieużywana)
* skracanie pliku
* Przy pomocy **truncate** możemy zmniejszyć i zwiększyć rozmiar pliku
#### buforowanie:
* problem spójności z pamięcią drugorzędną
* Jądro jest nieświadome istnienia buforów
* Jeżeli proces umrze w trakcie pisania, to zawartość bufora zostaje utracona
* buforowanie w przestrzeni użytkownika (stdio)
* Dla każdego strumienia mamy bufor
* Rodzaje buforowania:
* fully buffered (stdin/stdout do pliku)
* line buffered (stdin/stdout do terminala)
* unbuffered (stderr)
* buforowanie w przestrzeni jądra
* Jądro przechowuje bloki sprowadzone z dysku w stryukturze ``buffer cache``
* Zarządzane w softwarze
* synchronizacja buforów
* Bufory synchronizujemy dzieki wywołaniom systemowym `` patrz niżej ``
* wpływ rozmiaru bufora na wydajność operacji
* Podwójne kopiowanie danych: Najpierw jądro kopiuje dane do bufora strumienia, a później użytkownik kopiuje z bufora jadra do własnej pamięci
#### montowanie:
* punkt montażowy
* Punkty w drzewie katalogów, gdzie zamontowany jest system plików
* Nie jest to wtedy plik, a dowiązanie do miejsca w pamięci, w której znajduje się korzeń systemu plików
* "Dwa drzewa złączone wielkim kijem"
* atrybuty punktów
* superblok, grupy bloków i inne prywatne dane systemu plików
* wskaźnik na tablicę operacji vfsops
* lista v-węzłów należących do instancji tego systemu plików
### Wywołania systemowe, biblioteka libc
#### deskryptory plików:
* open(2)
* open and possibly create a file
* The open() system call opens the file specified by pathname.
* If the specified file does not exist, it may optionally (if O_CREAT is specified in flags) be created by open().
* The argument flags must include one of the following access modes:
* O_RDONLY,
* O_WRONLY,
* O_RDWR.
* The return value of open() is a file descriptor, a small, nonnegative integer that is an index to an entry in the process's table of open file descriptors.
* close(2),
* close a file descriptor
* close() returns zero on success. On error, -1 is returned, and errno is set to indicate the error.
* creat(2),
* equivalent to open(2) with flags equal to O_CREAT|O_WRONLY|O_TRUNC.
* dup(2),
* allocates a new file descriptor that refers to the same open file description as the descriptor ``oldfd``
* The new file descriptor number is guaranteed to be the lowest-numbered file descriptor that was unused in the calling process.
* dup2(2)
* performs the same task as dup(2), but instead of using the lowest-numbered unused file descriptor, it uses the file descriptor number specified in ``newfd``
* fcntl(2)
* manipulate file descriptor
* fcntl() performs one of the operations described below on the open file descriptor fd. The operation is determined by cmd.
#### operacje wejścia-wyjścia:
* read(2)
* read from a file descriptor
* read() attempts to read up to ``count`` bytes from file descriptor ``fd`` into the buffer starting at ``buf``.
* write(2),
* write to a file descriptor
* writes up to ``count`` bytes from the buffer starting at ``buf`` to the file referred to by the file descriptor ``fd``.
* ioctl(2),
* control device
* The ioctl() system call manipulates the underlying device parameters of special files.
* The argument fd must be an open file descriptor.
* The second argument is a device-dependent request code.
* The third argument is an untyped pointer to memory.
* lseek(2),
* reposition read/write file offset
* allows the file offset to be set beyond the end of the file. If data is later written at this point, subsequent reads of the data in the gap (a "hole") return null bytes ('\0') until data is actually written into the gap.
* truncate | ftruncate(2)
* truncate a file to a specified length
* The truncate() and ftruncate() functions cause the regular file named by path or referenced by fd to be truncated to a size of precisely length bytes.
* With ftruncate(), the file must be open for writing;
* With truncate(), the file must be writable.
#### dowiązania symboliczne:
* readlink(2),
* read value of a symbolic link
* symlink(2),
* make a new name for a file
* symlink() creates a symbolic link named linkpath which contains the string target.
* lstat(2)
* return information about a file
* if ``path`` is a symbolic link, then the link itself is stat-ed, not the file that it refers to(only diffrence between **stat**)
#### uprawnienia:
* chown(2),
* Zmienia właściciela pliku / katalogu
* chmod(2),
* Zmienia maskę dostępu do pliku
* Można usuwać / dodawać konkretne uprawnienia dla danej grupy użytkowników (np. ```chown o+x``` dodaje x do części owner)
* Można usuwać dla wszystkich (np. ```chown +w``` dodaje wszystkim w)
* Można ustawiać konkretną maskę (np. ```chown 755``` ustawia maskę na ```-rwxr-xr-x```)
* access(2)
* checks whether the calling process can access the file
* The check is done using the calling process's real UID and GID, rather than the effective IDs as is done when actually attempting an operation on the file.
#### metadane:
* «struct stat»
```c=
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* Inode number */
mode_t st_mode; /* File type and mode */
nlink_t st_nlink; /* Number of hard links */
uid_t st_uid; /* User ID of owner */
gid_t st_gid; /* Group ID of owner */
dev_t st_rdev; /* Device ID (if special file) */
off_t st_size; /* Total size, in bytes */
blksize_t st_blksize; /* Block size for filesystem I/O */
blkcnt_t st_blocks; /* Number of 512B blocks allocated */
/* Since Linux 2.6, the kernel supports nanosecond
precision for the following timestamp fields.
For the details before Linux 2.6, see NOTES. */
struct timespec st_atim; /* Time of last access */
struct timespec st_mtim; /* Time of last modification */
struct timespec st_ctim; /* Time of last status change */
#define st_atime st_atim.tv_sec /* Backward compatibility */
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec
};
```
* stat(2),
* return information about a file
* if ``path`` is a symbolic link, then the file that it refers to is stat-ed
#### buforowanie:
* sync(2)
* Synchronizuje wszystko co jest do synchronizowania w systemie.
* Najczesciej overkill, ale prydatne jak chcemy zamknąć maszyne w trybie ekspresowym
* fsync(2)
* Synchronizuje dane i metadane wybranego pliku.
* Domyślna opcja synchronizacji buforów
* fdatasync(2)
* Synchronizuje dane wybranego pliku.
* Potencjalna utrata danych jeżeli zmienił się rozmiar pliku (informacje o tym trzymamy w metadanych)
* Przydatne gdy mamy gwarancje ze nie będziemy modyfikować metadanych, np bazy danych.
#### katalogi:
* «struct dirent»
```c=
struct dirent {
ino_t d_ino; /* Inode number */
off_t d_off; /* Not an offset; dirent size */
unsigned short d_reclen; /* Length of this record */
unsigned char d_type; /* Type of file; not supported
by all filesystem types */
char d_name[256]; /* Null-terminated filename */
};
```

* readdir(2)
* read a directory
* The readdir() function returns a pointer to a dirent structure
representing the next directory entry in the directory stream
pointed to by dirp. It returns NULL on reaching the end of the
directory stream or if an error occurred.
* rename(2),
* renames a file, moving it between directories if required
* Nie możemy przenosić w ten sposób plików między instancjami systemów plików
* unlink(2)
* deletes a name from the file system
* If that name was the last link to a file and no processes have the file open the file is deleted and the space it was using is made available for reuse.
* If the name referred to a symbolic link the link is removed.
* If the name referred to a socket, fifo or device the name for it is removed but processes which have the object open may continue to use it.
### Narzędzia
#### katalogi:
* mkdir(1)
* Tworzy katalog
* rmdir(1)
* Usuwa pusty katalog
* ls(1)
* Wypisuje zawartość katalogu w formie listy
* domyślnie przyjmuje pwd jako ścieżkę
#### metadane:
* stat(1)
* Display file or file system status.
## 4 Komunikacja międzyprocesowa
### Najważniejsze pojęcia
#### model komunikacji:
* lokalna vs. zdalna,
* Gniazda domeny uniksowej - lokalne
* Gniazda sieiowe - zdalne
* strumieniowa vs. datagramowa,
* Strumieniowy
* Wysyłamy ciąg bajtów bez żadnej struktury
* Używany przez TCP/IP
* Datagramowy
* Wysyłamy datagramy, czyli określone porcje danych
* Używany przez UDP/IP
* jedno- vs. dwukierunkowa
* Potoki vs Gniazda
#### potoki:
* łączenie procesów
* połączenie standardowego wyjścia jednego procesu ze standardowym wejściem drugiego.
* atomowe operacje wej.-wyj.
* Gwarancja atomowego odczytu/zapisu
#### gniazda domeny uniksowej:
* przesyłanie otwartych plików,
* TODO
* przesyłanie tożsamości
* TODO
#### gniazda sieciowe:
* adres IP
* Identyfikator danego urządzenia w sieci
* Adresy IP są nadawane globalnie i lokalnie
* W lokalnej sieci, każde urządzenie ma własny adres IP
* W sieci globalnej urządzenia identyfikują się adresem IP routera
* 
* port
* Służy do rozróżnienia procesu na maszynie
* porty ulotne (ang. ephemeral),
* zwykłe, każdy proces może przypisać dany port gniazdu.
* Wybierane przez procesy użytkownika świadomie(rzadko) lub przydzielane automatycznie przez jądro(zazwyczaj)
* Well known ports
* Porty <1024
* Dla serwerów
* główne różnice między TCP i UDP
* UDP
* Rozszerzenie protokołu komunikacji
* Umożliwia komunikację między konkretnymi procesami
* Unreliable
* TCP
* Rozszerzenie protkołu UDP
* Reliable
* Niedostarczony pakiet zostanie wysłany ponownie
* Urządzenie przywróci oryginalną kolejność
* Działa jak dwukierunkowe potoki
#### komunikacja połączeniowa
* JEST
#### komunikacja bezpołączeniowa:
* datagramy
* podstawowa jednostka przekazu powiązana z siecią komutacyjną pakietów.
* Datagramy zwykle są zbudowane z sekcji nagłówka i ładunku.
### Wywołania systemowe, biblioteka libc
#### tworzenie:
* pipe(2),
* create pipe
* ```int pipe(int pipefd[2]);```
* The array pipefd is used to return two file descriptors referring to the ends of the pipe.
* ```pipefd[0]``` refers to the read end of the pipe.
* ```pipefd[1]``` refers to the write end of the pipe.
* Data written to the write end of the pipe is buffered by the kernel until it is read from the read end of the pipe.
* ```pipe()``` creates a pipe, a unidirectional data channel that can be used for interprocess communication.
* On success, zero is returned.
* On error, -1 is returned, errno is set to indicate the error, and pipefd is left unchanged.
* socketpair(2)
* create a pair of connected sockets
* The ```socketpair()``` call creates an unnamed pair of connected sockets in the specified domain, of the specified type, and using the optionally specified protocol.
* The file descriptors used in referencing the new sockets are returned in ```sv[0]``` and ```sv[1]```. The two sockets are indistinguishable.
* socket(2)
* creates an endpoint for communication and returns a file descriptor that refers to that endpoint.
#### gniazda sieciowe:
* «struct sockaddr»,
```c=
struct sockaddr {
uint16_t sa_family; /* Protocol family */
char sa_data[14]; /* Address data. */
};
struct sockaddr_in {
uint16_t sin_family; /* Protocol family (always AF_INET) */
uint16_t sin_port; /* Port num in network byte order */
struct in_addr sin_addr; /* IP addr in network byte order */
unsigned char sin_zero[8]; /* Pad to sizeof(struct sockaddr) */
};
```
* bind(2),
* bind a name to a socket
* assigns the address specified by ``addr`` to the socket referred to by the file descriptor ``sockfd``
* listen(2),
* listen for connections on a socket
* marks the socket referred to by ``sockfd`` as a passive socket, that is, as a socket that will be used to accept incoming connection requests using accept(2).
* accept(2),
* accept a connection on a socket
* extracts the first connection request on the queue of pending connections for the listening socket, ``sockfd``, creates a new connected socket, and returns a new file descriptor referring to that socket
* connect(2)
* initiate a connection on a socket
* connects the socket referred to by the file descriptor ``sockfd`` to the address specified by ``addr``.
#### właściwości gniazd:
* setsockopt(2)
* set options on sockets
#### operacje wej.-wyj.:
* recv(2),
* receive a message from a socket
* The only difference between recv() and read(2) is the presence of flags. With a zero flags argument, recv() is generally equivalent to read(2)
* send(2),
* send a message on a socket
* The only difference between send() and write(2) is the presence of flags.
* With a zero flags argument, send() is equivalent to write(2).
* recvfrom(2),
* The recvfrom() function shall receive a message from a connection-mode or connectionless-mode socket. It is normally used with connectionless-mode sockets because it permits the application to retrieve the source address of received data.
* The recvfrom() function takes the following arguments:
* **socket** - Specifies the socket file descriptor.
* **buffer** - Points to the buffer where the message should be stored.
* **length** - Specifies the length in bytes of the buffer pointed to by the buffer argument.
* flags - Specifies the type of message reception. Values of this argument are formed by logically OR'ing zero or more of the following values:
* **address** - A null pointer, or points to a sockaddr structure in which the sending address is to be stored.
* **address_len** - Either a null pointer, if address is a null pointer, or a pointer to a socklen_t object which on input specifies the length of the supplied sockaddr structure, and on output specifies the length of the stored address.
* sendto(2),
* send a message on a socket
* the address of the target is given by ``dest_addr`` with ``addrlen`` specifying its size
* sendmsg(2),
* send a message on a socket using a message structure
* ssize_t sendmsg(int socket, const struct msghdr *message, int flags);
* recvmsg(2)
* receive a message from a socket
```c=
struct msghdr {
void *msg_name; /* Optional address */
socklen_t msg_namelen; /* Size of address */
struct iovec *msg_iov; /* Scatter/gather array */
size_t msg_iovlen; /* # elements in msg_iov */
void *msg_control; /* Ancillary data, see below */
size_t msg_controllen; /* Ancillary data buffer len */
int msg_flags; /* Flags on received message */
};
```
#### rozwiązywanie nazw:
* getaddrinfo(3)
* network address and service translation
* The addrinfo structure used by getaddrinfo() contains the following fields:
```c=
struct addrinfo {
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
socklen_t ai_addrlen;
struct sockaddr *ai_addr;
char *ai_canonname;
struct addrinfo *ai_next;
};
```
* getnameinfo(3)
* converts a socket address to a corresponding host and service, in a protocol-independent manner.
### Narzędzia
#### gniazda:
* netstat(8)
* Print network connections, routing tables, interface statistics, masquerade connections, and multicast memberships
## 5 Pamięć
### Najważniejsze pojęcia
#### przestrzeń adresowa:
* lista odwzorowań
* vm_area_struct - lista wszystkich segmentow pamieci wirtualnej (ktore sa odwzorowane w przestrzen adresowa procesu).
* 
* obsługa błędu strony
* Normalny page fault:
* Mały
* ściągnij stronę z tablicy stron
* Duży
* ściągnij stronę z pamięci
* Segmentation fault
* SIGSEGV z SIG_MAPPER
* Protection Exception
* SIGSEGV z SIG_ACCER
* kopiowanie przy zapisie,
* 
*
* niejawne współdzielenie pamięci
*
* przestrzeń wymiany - pamięć dyskowa z której jądro korzysta kiedy zabraknie mu pamięci fizycznej.
#### fragmentacja:
* wewnętrzna
* Alokując pamięć, alokujemy zawsze cały blok. Fragmentacja wewnętrzna to zjawisko niewykorzystywania pełnej pojemności bloku (zapisywania danych o mniejszym rozmiarze niż rozmiar bloku), przez co zostawiamy nieużywane luki w blokach, tracąc dostępne bajty.
* Występuje wtedy gdy przechowujemy dane potrzebne do alokatora (np. boundary tags, header)
* Wystepuje gdy pozostały offset jest niewystarczajacy by stworzyc samodzielny wolny blok
* zewnętrzna
* Występuje kiedy w pamięci znajduje się wystarczająco miejsca by spełnić żądanie alokacji, ale nie ma żadnego wystarczająco dużego wolnego bloku
#### boundary tags:
* tworzenie,
* 
* W stópce przechowujemy kopie informacji z nagłówka, dzięki czemu możemy przechodzić listę wolnych bloków w obu kierunkach
* operacje złączania i podziału bloków
* Domyślnie złączamy bloki gorliwie, w momencie zawołania free, jeżeli sąsiadujący blok również jest wolny (do sprawdzenia bloku poprzedniego używamy boundary tags)
* Podział bloku domyślnie wykonujemy przy alokowaniu pamięci, jeżeli pozostały rozmiar bloku jest wystarczająco duży by istnieć samoistnie
#### zarządzanie wolnymi blokami:
* niejawna lista,
* Umiarkowanie prosta
* Koszt liniowy w najgorszym przypadku
* Free jest stałe
* Nawet ze złączaniem
* Zużycie pamięci zależne od polityki wyszukiwania bloków
* Nie jest używane w praktyce (chcemy przyspieszyć)
* Koncept podziału bloków, złączania bloków i boundary tagów jest **wspólny** dla pozostałych alokatorów
* lista dwukierunkowa
* Lista, w której w każym bloku przechowujemy informację o zajętości poprzedniego i następnego bloku
* kubełki
* Dzielimy listę bloków na kubełki.
* W każdym kubełku umieszczamy bloki o wielkości od $2^k$ do $2^{k + 1} - 1$
* bitmapa
* Tablica bitów informująca o tym, które bloki są zajęte
* Jeśli $i$-ty bit jest zapalony - $i$-ty blok jest zajęty
#### polityki przydziału:
* first-fit,
* Przechodzimy liste wolnych bloków i wybieramy pierwszy blok spełniający wymagania
* Pesymistyczny czas działania: O(n)
* Na początku listy powstanie duzo malych blokow ktore sa nieuzywane i sa zbyt male by spelnic żądania
* best-fit,
* Szukamy zawsze najmniejszego bloku, do którego jesteśmy w stanie zmieścić dane
* Wolniejszy niż first-fit, ale znacznie lepiej wykorzystuje pamięć
* next-fit,
* First-fit, tylko rozpoczyna poszukiwania od miejsca w którym skończył poprzednio
* Troche szybszy od first-fit, natomiast większa fragmentacja
* lista posortowana względem adresów
*
#### błędy odwołania do pamięci
### Wywołania systemowe, biblioteka libc
#### biblioteczny algorytm:
* malloc(3)
* allocate dynamic memory
* The malloc() function allocates size bytes and returns a pointer to the allocated memory.
* realloc(3),
* The realloc() function changes the size of the memory block pointed to by ptr to size bytes.
* free(3)
* free dynamic memory
* The free() function frees the memory space pointed to by ptr, which must have been returned by a previous call to
* malloc(),
* calloc(),
* realloc().
* Otherwise, or if free(ptr) has already been called before, undefined behavior occurs.
* If ptr is NULL, no operation is performed.
#### odwzorowania:
* mmap(2),
* creates a new mapping in the virtual address space of the calling process.
* mprotect(2),
* changes the access protections for the calling process's memory pages containing any part of the address range in the interval [addr, addr+len-1].
* munmap(2)
* unmap files or devices into memory
* ```int munmap(void *addr, size_t length);```
* madvise(2),
* give advice or directions to the kernel about the address range beginning at address ``addr`` and with size ``length`` bytes.
* In most cases, the goal of such advice is to improve system or application performance.
* msync(2)
* synchronize a file with a memory map
* ```int msync(void *addr, size_t length, int flags);```
* msync() flushes changes made to the in-core copy of a file that was mapped into memory using mmap(2) back to the filesystem.
* Without use of this call, there is no guarantee that changes are written back before munmap(2) is called.
* To be more precise, the part of the file that corresponds to the memory area starting at addr and having length length is updated.
#### rozmiar programu:
* sbrk(2)
* change data segment size
* increments the program's data space by ``increment`` bytes.
* Calling sbrk(2) with an increment of 0 can be used to find the current location of the program break.
### Narzędzia
#### przestrzeń adresowa:
* pmap(1)
* reports the memory map of a process or processes.
## 6 Współbieżność i synchronizacja
### Najważniejsze pojęcia
#### wykonywanie zadań:
* szeregowe,
* Wykonujemy czynności jedna po drugiej
* współbieżne
* Mówimy że dwa procesy są współbieżne, jeżeli ich wykonanie przeplata się w czasie
* równoległe
* Mówimy że dwa procesy są równoległe, jeżeli wykonują się w tym samym czasie
* Na jednym procesorze możemy uzyskać złudzenie rónoległości, poprzez dzielenie czasu procesora na kwanty czasu
* Prawdziwa równoległość do uzyskania na wielu procesorach
#### organizacja oprogramowania współbieżnego:
* pętla zdarzeń i maszyny stanów,
* TODO
* pule wątków
* TODO
#### zasoby prywatne wątku:
* stos,
* kontekst,
* Ciąg instrukcji
* problemy z izolacją
#### usterki programów współbieżnych:
* sytuacja wyścigu,
* wynik działania programów nie zależy tylko od logiki programów, ale również od decyzji scheduler, tego jakie były przeploty
* zagłodzenie,
* Zdarzenia zewnętrzne lub decyzje schedulera które przyczyniają się do tego że niektóre zadania nie mogą postępować do przodu, mimo że jedyna rzecz która je ogranicza to brak przydzielonego czasu procesora.
* uwięzienie,
* Sytuacja, kiedy żaden proces z czekających nie ma wyższego priorytetu, więć nie może sięgnąć pierwszy po zasoby
* zakleszczenie
* Procesy oczekują wzajemnie na zwolnienie zasobów
#### zakleszczenia:
* graf przydziału zasobów,
* metody zapobiegania zakleszczeniom
* Circular wait
* dodajemy warunek numerowania blokad, tak aby występowały one w jakiejś ustalonej kolejności
* Hold-and-wait
* Gwarantownie wykonywania wszystkich blokad po sobie, atomowo
* No Preemption
* Bierzemy blokady tylko jak są dostępne
* Jezeli nie mozemy uzyskac blokady, to zwalniamy tą którą posiadamy
* Może zachodzić livelock
* Mutual Exclusion
#### sekcja krytyczna:
* blokady wirujące,
* Spinlock - Wątek w pętli próbuje wejść do sekcji krytycznej
* Problem - Aktywne czekanie
* Używa się w jądrze, po stronie użytkownika raczej nie
* muteksy zwykłe i rekurencyjne
* Semafory bianrne zapamiętujące kto założył blokade
* Ta checha pozwala rozwiązać problem **odwrócenia priorytetów**
* Muteksów rekurencyjnych raczej się nie używa
#### zmienne warunkowe:
* semantyka operacji wait
```=
def pthread_cond_wait(condvar c, mutex m):
atomic:
m.unlock()
c.pushThread(self)
block
m.lock()
```
* signal i broadcast
* signal - wybudza dokładnie jeden oczekujący wątek
* broadcast - wybudza wszystkie oczekujące wątki
#### złożone środki synchronizacji:
* semafory zliczające,
* Rozwiazuja problem Producenta-Konsumenta
* blokady współdzielone,
* Reader-write lock
* Rozwiazuja problem Czytelnikow-Pisarzy
* Synchronizacja dostępu do strkuktury danych, w jednej chwili #R $\geq 0$ wątków może czytać, albo #W $\leq 1$ może modyfikować
* bariery synchronizacyjne
* Obliczenia postępują w fazach
* Wszystkie podzadania muszą się zakończyć zanim przejdziemy do następnej fazy.
### Wywołania systemowe, biblioteka libc
#### oczekiwanie na zdarzenia:
* select(2)
* allows a program to monitor multiple file descriptors, waiting until one or more of the file descriptors become "ready"
* A file descriptor is considered ready if it is possible to perform a corresponding I/O operation without blocking.
* TODO
* poll(2)
* wait for some event on a file descriptor
* poll() performs a similar task to select(2):
* It waits for one of a set of file descriptors to become ready to perform I/O.
* TODO
#### zarządzanie wątkami:
* pthread_create(3),
* create a new thread
* ```int pthread_create(pthread_t *restrict thread, const pthread_attr_t *restrict attr, void *(*start_routine)(void *), void *restrict arg);```
* The pthread_create() function starts a new thread in the calling process.
* pthread_join(3),
* join with a terminated thread
* waits for the thread specified by ``thread`` to terminate. If that thread has already terminated, then pthread_join() returns immediately.
* The thread specified by ``thread`` must be joinable.
* pthread_exit(3)
* terminates the calling thread and returns a value via ``retval`` that (if the thread is joinable) is available to another thread in the same process that calls pthread_join(3).
#### właściwości wątków:
* pthread_detach(3)
* detach a thread
* ```int pthread_detach(pthread_t thread);```
* The pthread_detach() function marks the thread identified by thread as detached.
* When a detached thread terminates, its resources are automatically released back to the system without the need for another thread to join with the terminated thread.
#### muteks:
* pthread_mutex_init(3),
* initialize the mutex referenced by ``mutex`` with attributes specified by ``attr``.
* Upon successful initialization, the state of the mutex becomes initialized and unlocked.
* pthread_mutex_lock(3)
* lock and unlock a mutex
* If the mutex is already locked, the calling thread shall block until the mutex becomes available
*
#### zmienna warunkowa:
* pthread_cond_init(3),
* initialize the condition variable referenced by ``cond`` with attributes referenced by ``attr``
* pthread_cond_signal(3),
* The pthread_cond_signal() function shall unblock at least one of the threads that are blocked on the specified condition variable cond (if any threads are blocked on cond).
#### semafory:
* sem_open(3),
* initialize and open a named semaphore
* ```sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value);```
* ```sem_open()``` creates a new POSIX semaphore or opens an existing semaphore.
* sem_wait(3),
* decrements (locks) the semaphore pointed to by ``sem``.
* If the semaphore's value is greater than zero, then the decrement proceeds, and the function returns, immediately.
* If the semaphore currently has the value zero, then the call blocks until either it becomes possible to perform the decrement, or a signal handler interrupts the call.
* sem_post(3)
* unlock a semaphore
* ``` int sem_post(sem_t *sem);```
* ```sem_post()``` increments (unlocks) the semaphore pointed to by ```sem```.
* If the semaphore's value consequently becomes greater than zero, then another process or thread blocked in a ```sem_wait``` call will be woken up and proceed to lock the semaphore.
## RANDOM



