Każdy moduł Linuksa musi zawierać funkcje inicjującą i usuwającą moduł:
int init_module( void ) {
if ( ts_installed ) // jakiś moduł już jest zainstalowany
return -1; // sygnalizowany jest błąd
ts_installed = 1;
ts_select = linux_select;
ts_wakeup = linux_wakeup;
return 0;
}
void cleanup_module(void) {
ts_select = NULL;
ts_wakeup = NULL;
ts_on = 0; // Moduł nie implementuje funkcji ts_sched_off,
// więc wystarczy wyzerować flagę.
ts_installed = 0;
}
Zaimplementowana musi być funkcja dla zdarzenia SELECT:
Process linux_select(Process current, int cpu) {
// Numer procesora (cpu) nie jest wykorzystywany,
// gdyż SMP nie jest obsługiwane.
int pri, best_pri = -1000;
Process p, found = NULL;
for_each_ready_process(p) {
pri = p->counter;
if (p==current && pri>0)
pri = pri + 1;
if (pri>best_pri)
best_pri = pri, found = p;
}
if (best_pri==0) { // Postarzanie
for_each_process(p) {
p->counter = (p->counter / 2) + p->priority;
}
return next;
}
Proces budzony może wywłaszczyć proces bieżący, zatem potrzebna jest
funkcja obsługujące zdarzenie WAKEUP:
int linux_wakeup(Process task) {
if (task->counter > current->counter+3)
need_resched = 1;
return 0;
}
Jak widać treść modułu to kilkadziesiąt wierszy, z czego właściwy algorytm
zajmuje około 30, a funkcje administracyjne są niewielkie.
Algorytm wygląda praktycznie identycznie z pseudokodem opisanym w punkcie
2.2. Różnica dotyczy nazwy pola priorytetu statycznego
upri (w Linuksie -- priority) oraz sposobu odwołania się
do elementów struktur (-> w miejsce .).
Zaletą zaproponowanego tu rozwiązania jest jego elastyczność, nakład pracy proporcjonalny do stopnia skomplikowania algorytmu planisty oraz osadzenie w jednym pliku funkcji realizujących jeden algorytm (modularyzacja).
Pełną treść modułu można obejrzeć w pliku ts_linux.c.