Zmiany stanów procesów
Aleksander Zalewski
Listopad 2001
1 Algorytm sleep_on
Funkcje:
- void interruptible_sleep_on(wait_queue_head_t *q)
- long interruptible_sleep_on_timeout(wait_queue_head_t *q, long time-out)
- void sleep_on(wait_queue_head_t *q)
- long sleep_on_timeout(wait_queue_head_t *q, long timeout)
Algorytm:
- zmiana stanu procesu na:
- TASK_INTERRUPTIBLE dla funkcji interruptible_ lub
- TASK_UNINTERRUPTIBLE dla pozostałych dwóch funkcji
- zapamiętanie flag i blokada kolejki q
- dodanie bieżącego procesu do kolejki q
- odblokowanie kolejki q
- przeszeregowanie
- funkcja schedule() lub
- funkcja schedule_timeout()
- blokada kolejki q
- usunięcie z kolejki q
- odblokowanie kolejki q i odczytujemy flagi
2 Algorytm wake_up
W pliku sched.h mamy zdefiniowanych 10 makr. Tak naprawdę są to jednak
wywołania funkcji __wake_up_common z różnymi parametrami, tj.
- wskaźnik na kolejkę procesów oczekujących
- tryb - które procesy mamy obudzić:
- wszystkie, które zasnęły na kolejce czyli TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE
- tylko te TASK_INTERRUPTIBLE
- nr - liczba procesów, które obudzimy (0 - wszystkie )
- synchronus - odpowiada za to czy zostanie wywołane przeszeregowanie
Występuje jeszcze etap pośredni pomiędzy makrami a funkcją __wake_up_common
są to funkcje __wake_up i __wake_up_sync.
Różnią się one dokładnie jednym znakiem!!! A mianowicie wartością parametru
synchronus.
- Zablokowanie dostępu do kolejki procesów oczekujących i zapisanie flag
- wywołanie funkcji __wake_up_common z przekazanymi parametrami
- odwrotnie do punktu 1, odblokowujemy kolejkę i odczytujemy flagi
Wersja z _sync jako wartość parametru synchronus przekazuje 1 a bez 0. Wartość
tą interpretuje się następująco:
- 1 - przeszeregowywujemy tylko w systemie wieloprocesorowym, jeśli mamy taką możliwość
- 0 - zawsze
Algorytm:
W pętli, dla kolejnych procesów z kolejki,
sprawdzamy czy proces został uśpiony w odpowiednim trybie jeśli tak to
próbujemy go obudzić.
Przerwanie wykonywania pętli możliwe jest z dwóch powodów:
- przeszliśmy już całą kolejkę
- zaszły na raz 3 warunki:
- obudziliśmy proces
- miał on ustawioną flagę EXCLUSIVE
- obudziliśmy co najmniej nr procesów
Niestety komentarz dotyczący tej funkcji jest zupełnie inny.
3 Algorytm wake_up_process
Budzenie pojedynczego procesu.
- zablokowanie kolejki procesów gotowych i zapisanie flag
- zmiana stanu procesu na TASK_RUNNING
- jeśli proces jest w kolejce procesów gotowych to skaczemy do punktu 6
- dodajemy proces do kolejki procesów gotowych
- jeśli jest wykonywany proces idle to następuje przeszeregowanie (funkcja: reschedule_idle)
- odwrotnie do punktu 1, odblokowujemy kolejkę procesów gotowych i odczytujemy flagi
4 Uwagi i komentarze
Blokowanie kolejek odbywa się na semaforach.
Zapisanie flag oznacza zapis rejestru flagowego procesora.
Jedno z makr (do wake_up) nie przekazuje jednego parametru. (również w wersji 2.4.13)