Wspomnimy jeszcze o liście wszystkich procesów (ang. task_list). Wstawienie do tej listy następuje, gdy dany proces jest tworzony, a usuwanie - gdy proces już się zakończył i uregulował swoje sprawy z ojcem (przekazał mu swój status zakończenia albo został przez niego zignorowany).
Ta lista jest zaimplementowana w standardowy sposób. Pola prev_task
i next_task
ze struktury task_struct
wskazują odpowiednio na poprzedni i następny proces z listy. Nie jest tu używana struktura list.h. Prawdopodobnie dzieje się tak dlatego, że operacji na tej liście dokonuje się stosunkowo rzadko - każdy proces powinien być tylko raz wstawiany i raz usuwany.
Początek listy stanowi proces idle. Jest to logiczne, bo proces ten jest tworzony jako pierwszy i nigdy nie jest usuwany. Stanowi więc idealną atrapę.
Do modyfikacji listy task_list służą makra:
SET_LINKS(p)
Tu dokonuje się wstawienia procesu p
na listę. Co ciekawe, proces jest wstawiany na koniec - tuż przed idle. W tym momencie proces p
staje się najmłodszym synem swego ojca. i młodszym bratem najmłodszego syna swego ojca (jeśli taki istnieje).
REMOVE_LINKS(p)
Tu dokonuje się usunięcia procesu z listy, a także uaktualnienie zależności rodzinnych. Jeśli proces p
jest jedynym synem swojego ojca, to ojciec staje się bezdzietny, jeśli zaś proces p
ma rodzeństwo, to zostaje wyłączony z kolejki dzieci. Wskaźniki rodzinne w procesie p
pozostają bez zmian.
Uwaga: Ponieważ kolejność procesów na liście task_list jest nieistotna, to zdarza się w jądrze Linuksa wykorzystanie powyższych makr do zmiany zależności rodzinnych.
for_each_task(p)
To jest zwykłe makro, zastępujące pętlę przeglądające całą listę procesów.