28.02.2025
Trwająca od ponad 20 lat praca nad obsługą czasu rzeczywistego w głównym jądrze Linuksa może wreszcie być „wystarczająco dobra do wszystkich praktycznych celów”.
Trwająca od ponad 20 lat praca nad obsługą czasu rzeczywistego w głównym jądrze Linuksa może wreszcie być „wystarczająco dobra do wszystkich praktycznych celów”.
Ogłoszono, że w następnym jądrze, które zostanie opublikowane, przetwarzanie w czasie rzeczywistym zostanie znacznie ulepszone.
Z zagadnieniem „czasu rzeczywistego” już od chwili, kiedy zacząłem programować w 1969 roku, łączy mnie relacja będąca mieszaniną miłości i nienawiści. W tamtych czasach większość programowania wykonywałem w języku asemblera, często na komputerze bez systemu operacyjnego, wykonując jedno zadanie naraz. Można było napisać program tak, aby stale „odpytywał”, wykrywając jakieś zdarzenie, a gdy to zdarzenie wreszcie nastąpiło, można było się nim natychmiast zająć.
Oczywiście oznaczało to, że cały komputer był poświęcony jednej funkcji, a gdy komputer kosztował 50.000 dol., to zdarzenie, które należało wychwycić, musiało być dość ważne. Nie pomagał fakt, że ówczesny komputer mógł działać z prędkością zaledwie 100.000 instrukcji na sekundę.
Z biegiem czasu komputery zyskały systemy operacyjne, które mogły wykonywać wiele zadań jednocześnie, a niektóre funkcje systemu operacyjnego próbowały rozwiązać kwestie czasu rzeczywistego.
Zawsze starałem się uprościć koncepcję czasu rzeczywistego dla ludzi i dla mnie sprowadza się ona do zdolności komputera do konsekwentnego i niezawodnego wykonywania zadania w wymaganym czasie.
W zależności od konstrukcji systemu operacyjnego istnieje kilka rzeczy, które mogą uniemożliwić efektywne działanie w czasie rzeczywistym.
Większość obecnego sprzętu ma możliwość tworzenia przerwań. Następuje pewne zdarzenie i sprzęt tworzy przerwanie. Dopóki komputer nie będzie w stanie przechwycić wszystkich informacji potrzebnych do obsługi przerwania, dopóty zdolność sprzętu do utworzenia kolejnego przerwania musi być wyłączona, w przeciwnym razie może dojść do utraty części informacji z pierwszego przerwania.
Przy założeniu, że wszystkie informacje ze wszystkich przerwań mogą pojawić się wystarczająco szybko, aby można je było przechwycić i nadać im priorytety, system operacyjny musi następnie określić, które przerwanie lub zadanie jest najważniejsze. Na przykład, czy komputer powinien potraktować przerwę spowodowaną stopieniem się rdzenia elektrowni jądrowej (i w związku z tym opuścić pręty, aby temu zapobiec) lub wyłączyć czajnik, który podgrzewał wodę na herbatę? Większość ludzi powiedziałaby, że priorytetem jest opuszczenie prętów, a po opuszczeniu prętów można wyłączyć czajnik.
Gdyby życie i systemy operacyjne były tak proste, to systemy operacyjne czasu rzeczywistego również mogłyby być proste. Istnieją jednak inne kwestie, które komplikują sprawę.
Większość systemów wielozadaniowych w dzisiejszych czasach używa pamięci wirtualnej stronicowanej na żądanie, a często systemy te mają również koncepcję „wymiany” zasobów, takich jak strony ich programów i struktur kontrolnych, jeśli nie były używane przez długi czas. Jeśli zależy nam na niezawodnej kontroli nad zadaniem w czasie rzeczywistym, warto ograniczyć możliwość wymiany zadania przez system operacyjny lub nawet przechowywania wielu jego stron w pamięci zamiast na dysku, aby zadanie czasu rzeczywistego nie musiało czekać na ponowne przeniesienie instrukcji z dysku do pamięci RAM.
Inną ważną kwestią są obszary kodu, które nie są uważane za otwarte na przerwanie. Te obszary kodu mają blokady, które uniemożliwiają innym wątkom rdzenia procesora wprowadzanie kodu do czasu zakończenia pierwszego wątku. Może to sprawić, że zdarzenie w czasie rzeczywistym będzie oczekiwać dłużej niż to dopuszczalne. Wyeliminowanie tych sekcji kodu lub umożliwienie ich wywłaszczania wymaga dużo czasu i umiejętności, szczególnie w złożonym jądrze, które pozwala na jednoczesne wykonywanie wielu wątków.
To była ta wspaniała część zagadnień technicznych, nad którą pracowano od 2005 roku, więc teraz główne jądro Linuksa może zaspokoić większość potrzeb w czasie rzeczywistym.
Jedną z nielicznych sytuacji, kiedy to dyskutowałem z Linusem na tematy techniczne, była rozmowa telefoniczna z nim pod koniec lat 90. XX w., kiedy błagałem go o więcej „miękkiego czasu rzeczywistego”. Czułem, że znalazłoby się o wiele więcej zastosowań Linuksa dla DEC Alpha, gdyby Linux był w stanie wykorzystać szybkość Alphy, nawet jeśli obsługa w czasie rzeczywistym nie byłaby doskonała. W tamtym czasie w jądrze było wiele miejsc, w których przerwania były wyłączone i mogły pozostać wyłączone przez długi czas, szczególnie w podsystemie we/wy. Nasza rozmowa wyglądała mniej więcej tak:
– Linux działa w czasie rzeczywistym – powiedział Linus. Gram w Quake’a i kiedy potwór chce mnie zastrzelić, naciskam przycisk i zabijam potwora... w czasie rzeczywistym!
– Linus, włóż prawdziwą broń do ręki tego potwora i sprawdź, czy czujesz to samo – odparłem.
– Rozumiem, co masz na myśli – rzekł Linus, a w następnym wydaniu jądra obsługa czasu rzeczywistego nie była idealna, ale znacznie lepsza.
Minęło ponad 20 lat, ale myślę, że wsparcie Linuksa w czasie rzeczywistym może być „wystarczająco dobre do wszystkich praktycznych celów”.
Jon „maddog” Hall jest autorem, wykładowcą, informatykiem i jednym z pionierów Wolnego Oprogramowania. Od 1994 roku, kiedy po raz pierwszy spotkał Linusa Torvaldsa i ułatwił przeniesienie jądra na systemy 64-bitowe, pozostaje orędownikiem Linuksa. Obecnie jest prezesem Linux International®.