Do spisu treści tematu 3
 

3.3.2 Semafory systemowe

Spis treści

 

Wprowadzenie

W jądrze Linuxa znajdują się semafory dostępne tylko dla procedur systemowych (mogą one być wołane jedynie z poziomu jądra). Nie mają one nic wspólnego z semaforami IPC. Semafory jądra są obsługiwane przez funkcje o nieskomplikowanej składni i budowie, a deklaracja tychże semaforów to deklaracja struktury nazwanej semaphore. Oto jej opis (deklaracja w semaphore.h).

Działanie

Jak działa taki semafor?
Rozpocznę opis od podnoszenia semafora (wywołanie funkcji up). Funkcja ta zwiększa count i sprawdz jaką ma ta zmienna wartość (to w asemblerze). Jeśli jest mniejsza lub równa zero, oznacza to, że jakiś proces czekał na semaforze. Wówczas proces zwiększa zmienną waking o jeden (jeden wiecej proces będzie mógł przejść pod semaforem) i "budzi" wszystkie procesy z kolejki procesów czekających (budzenie to tylko zmiana stanu procesu i dowiązań prev_task, next_task w strukturze task_struct, więc wiele budzeń, np. dwa wywołania up po kolei, nic nie psuje). Teraz jeden z nich (ten który najszybciej otrzymał procesor) zmniejsza stan zmiennej waking i przechodzi pod semaforem.
Opuszczenie semafora systemowego (funkcja down lub down_interruptible) polega z kolei na zmniejszeniu wartości count i sprawdzeniu czy jest ona większa lub równa zero (asembler). Jeśli nie to proces wstawia się do kolejki czekających na semaforze (pole wait struktury semaphore). Dalej w pętli próbuje odjąć jeden od zmiennej waking o ile jest ona większa od zera (odjęcie z wyłączonymi przerwaniami sprzętowymi - znów istotna współbieżność). Gdy mu się to uda to wychodzi z pętli, w przeciwnym przypadku wiesza się wywołując funkcję szeregującą schedule. Po powrocie z tej funkcji (inny proces wywołał up lub "nasz" proces otrzymał sygnał) cofa się do początku pętli. Przy obniżaniu semafora za pomocą funkcji down_interruptible możliwe jest jeszcze wyjście z pętli pod warunkiem otrzymania sygnału). Po wyjściu z pętli proces usuwa się z kolejki czekających pod semaforem. 

Funkcje

Funkcje systemowe obsługujące semafory pochodzą z plików: void down_failed(), void up_wakeup() ,void down_failed_interruptible()
Te trzy funkcje służą do wołania z poziomu asemblera funkcji odpowiednio __down, __up,
__down_interruptible.

void __down(semafor systemowy),
void __down_interruptible(semafor systemowy),
void __do_down(semafor systemowy, stan procesu),
Dwie pierwsze funkcje wołają trzecią (z różnym drugim parametrem). Trzecia funkcja wykonuje podstawowe działania przy opuszczaniu semafora systemowego (jest blokująca).

void __up(smafor systemowy)
Funkcja podnosi semafor systemowy (wewnątrz sched.c).

void down(semafor systemowy)
void down_interruptible(semafor systemowy)
Funkcje opuszczające semafor systemowy. Pierwsza zawiesza go na sposób, w którym nie przyjmuje sygnałów, druga pozwala na odebranie sygnału.

void up(semafor systemowy)
Funkcja podnosi semafor systemowy.

give_buzz_lock(int *)
get_buzz_lock(int *)
Te dwie funkcje mają znaczenie tylko dla wieloprocesorowości.


Autor: Bartosz Kruszyński