Mariusz Rudnicki mariusz.rudnicki@eti.pg.edu.pl PROGRAMOWANIE WSPÓŁBIEŻNE I SYSTEMY CZASU RZECZYWISTEGO CZ.2
Architektura SCR - Procesy Proces program załadowany do pamięci; identyfikowany przez id procesu, zwykle nazywany jako pid; wspólne zasoby procesu: pamięć, włączając kod i dane, otwarte pliki, identyfikatory : id użytkownika, id grupy, timery. Zasoby należące do jednego procesu są chronione przed innymi procesami. 2/52
Architektura SCR - Wątki Wątek wątek jest pojedynczym strumieniem wykonania; wątek posiada pewne atrybuty: priorytet, algorytm kolejkowania, zestaw rejestrów, maska CPU dla SMP, maska sygnałów, i inne. 3/52
Architektura SCR - Procesy i Wątki Wątki są uruchamiane wewnątrz procesów: proces musi posiadać przynajmniej jeden wątek; wątki w procesie współdzielą wszystkie zasoby procesu. 4/52
Architektura SCR - Procesy i Wątki Procesy i wątki: procesy są komponentami składowymi systemu, które: widoczne dla każdego innego procesu; mogą komunikować się z każdym procesem, wątki są szczegółową implementacją danego procesu: ukrytą w jego wnętrzu. 5/52
Architektura SCR Jądro Funkcje jądra: są spoiwem łączącym cały system; programy mają do czynienia z jądrem za pomocą specjalnych procedur bibliotecznych, nazywanych wywołaniami jądra ang. kernel calls, które wykonują kod umieszczony w jądrze; większość podsystemów, włączając aplikacje użytkownika, komunikują się nawzajem używając mechanizmu przekazywania wiadomości, dostarczanego przez jądro za pomocą wywołań jądra. 6/52
Architektura SCR Jądro Jądro jest rdzeniem systemu: Wywołania jądra: często korzystamy z wywołań jądra, np. w trakcie komunikacji IPC lub podczas obsługi przerwań, timerów, wątków itp.; to znaczy, że wykonujemy kod w jądrze podczas wywołania. Co się wydarzy jeżeli wystąpi krytyczne zdarzenie w trakcie wykonywania kernell calls? 7/52
Jądro Wywłaszczanie Wywołania jądra są wywłaszczające: 8/52
Jądro Wywłaszczanie Operacje jądra: 9/52
Jądro Wywłaszczanie Jakie są zalety i wady wywłaszczania? Więcej ustępstw: korzyści: zmniejszone opóźnienie; szybsza odpowiedź na nowe zdarzenia; krótsze opóźnienie reakcji na przerwania, koszty: wydajność wymaga więcej czasu by wznowić przerwane wywołanie jądra; zabiera więcej czasu i zasobów na zachowanie aktualnego stanu i wznowienie wywłaszczonego procesu np. przekazywania wiadomości. 10/52
Jądro Usługi 11/52
Jądro IPC Formy IPC Inter-Process Communication dostarczane przez jądro: Komunikaty - wymiana informacji między procesami. Pulsy - dostarczenie zawiadomienia do procesu. Sygnały - przerwanie procesu i wykonanie innej części kodu lub zakończenie. 12/52
Jądro IPC Komunikaty QNX Neutrino : 13/52
Jądro IPC Pulsy QNX Neutrino używane do powiadamiania o zdarzeniu: coś się zdarzyło. 14/52
Jądro IPC Sygnały zgodne ze specyfikacją POSIX używane np. do przerwania procesu. 15/52
Jądro Wątki Funkcje związane z wątkami obsługa wątków zgodna ze standardem POSIX: dynamiczne tworzenie / usuwanie wątków; oczekiwanie na zakończenie wątku; zmiana atrybutów wątku. 16/52
Jądro synchronizacja wątków Mutex wzajemne wykluczenie wątków Condvar oczekiwanie na zmienną warunkową Semaphore oczekiwanie na licznik RWlock synchronizacja wątków piszących i czytających Join synchronizacja do zakończenia wątku Spinlock oczekiwanie na alokację pamięci Sleepon podobnie do condvars, z dynamiczną alokacją Barrier oczekiwanie na określoną liczbę wątków 17/52
Jądro czas Koncepcja czasu w QNX Neutrino : 18/52
Manager Procesów Zadania Managera Procesów: grupowanie wątków wewnątrz procesów; ochrona pamięci, zarządzanie przestrzenią adresową włączając pamięć wspólną dla IPC; zarządzanie przestrzenią nazw; powołanie i zakończenie procesu: spawn / exec / fork; ładowanie programów wykonawczych ELF; bezczynny wątek, zużywający wolny czas procesora. 19/52
Manager Procesów Komunikacja z managerem procesów: Microkernel procnto Process Manager devb-eide ksh Application process Application process Network Stack User Interface Software Bus phfontfa devc-ser8250 procesy komunikują się z managerem procesów za pomocą IPC 20/52
Struktura rozbudowanego systemu x86 Andrew S. Tanenbaum Systemy operacyjne rysunek 1.12. str. 59. 21/52
Manager Procesów Zarządzanie pamięcią: Wirtualny model adresowania: każdy proces wykonuje się we własnej chronionej wirtualnej przestrzeni adresowej; wskaźniki, z którymi mamy do czynienia zawierają adres wirtualny, nie fizyczny; fizycznie dzielą tą samą przestrzeń adresową. Wątki managera procesów Proces systemowy (procnto) Proces użytkownika #1 Proces użytkownika #2 Proces użytkownika #3 Mikrojądro Adresy wirtualne x86: 3.5G 4G 0 3.5G 0 3.5G 0 3.5G PPC: 0 1G 1G 4G 1G 4G 1G 4G MIPS: 2G 4G 0 2G 0 2G 0 2G SH4: 2G 4G 0 2G 0 2G 0 2G ARM: 2G 4G 0 32M 0 32M 0 32M 22/52
Manager Procesów Zarządzanie pamięcią pamięć współdzielona: Mapowanie wirtualnych adresów do adresów fizycznych: Wirtualna przestrzeń adresowa procesu A np. 0x4000A000 (x86) Dane, Stos, Kod Przestrzeń mapowana Przestrzeń adresowa pamięci fizycznej Współdzielona RAM RAM... np. 0xFC80000 Dane, Stos, Kod Przestrzeń mapowana Wirtualna przestrzeń adresowa procesu B np. 0x40006000 (x86) 23/52
Manager Procesów Zarządzanie przestrzenią nazw: W momencie uruchamiania QNX Neutrino, cała przestrzeń nazw należy do managera procesów w QNX Neutrino to procnto. / /proc Manager procesów Wszystkie zapytania o pliki i urządzenia są przechwytywane przez procnto. 24/52
Manager Procesów Zarządzanie przestrzenią nazw: procnto umożliwia managerom zasobów zaadoptować część przestrzeni nazw: fs-qnx4.so (system plików) / procnto dev devc-con con1 ser1 devc-ser8250 25/52
Windows Embedded CE Kernel structure https://msdn.microsoft.com/en-us/library/aa909237.aspx 26/52
RT Linux Kernel 27/52
PRZERWANIA - INTERRUPTS Struktura przerwań sprzętowych w komputerze osobistym. Andrew S. Tanenbaum Systemy operacyjne rysunek 5.4. str. 359 28/52
Jądro Przerwania Koncepcja przerwań w QNX Neutrino : Obsługa przerwań: Wszystkie przerwania sprzętowe są przekazywane do jądra. Proces: może zarejestrować funkcję, która będzie wywołana przez jądro po wystąpieniu przerwania; żądać powiadomienia o wystąpieniu zdarzenia. 29/52
QNX Neutrino Przerwania Wywołania dla przerwań: id = InterruptAttach (int intr, struct sigevent *(*handler)(void *, int), void *area, int size, unsigned flags); id = InterruptAttachEvent (int intr, struct sigevent *event, unsigned flags); InterruptDetach (int id); InterruptWait (int flags, uint64_t *reserved); InterruptMask (int intr, int id); InterruptUnmask (int intr, int id); InterruptLock (struct intrspin *spinlock); InterruptUnlock (struct intrspin *spinlock); Musimy uzyskać uprawnienia I/O dla tych funkcji. W tym celu wywołujemy ThreadCtl(_NTO_TCTL_IO, 0), poza tym wymagane są uprawnienia root (userid 0). 30/52
QNX Neutrino Przerwania Obsługa przerwań: Przykład sterownika A: z wykorzystaniem funkcji obsługi przerwania ISR. struct sigevent event; const struct sigevent *handler (void *not_used, int id){ } if (check_status_register()) else return (&event); return (NULL); main (){ ThreadCtl (_NTO_TCTL_IO, 0); SIGEV_INTR_INIT (&event); id = InterruptAttach (intnum, handler, NULL, 0,...); while(1){ InterruptWait (0, NULL); // do some or all of the work here } } 31/52
QNX Neutrino Przerwania Obsługa przerwań: Przykład sterownika B: z wykorzystaniem zdarzenia powiązanego z przerwaniem tzw. obsługa w wątku. struct sigevent event; main(){ } ThreadCtl (_NTO_TCTL_IO, 0); SIGEV_INTR_INIT (&event); id = InterruptAttachEvent (intnum, &event,...); for (;;) { } InterruptWait (0, NULL); // do the interrupt work here, at thread priority InterruptUnmask (intnum, id); 32/52
QNX Neutrino Przerwania Do zadań poniższych funkcji należy poinformowanie jądra, która część kodu programu musi być wykonana po wystąpieniu przerwania: 33/52
QNX Neutrino Przerwania Parametr flagi: _NTO_INTR_FLAGS_END Dotyczy kolejności wykonywania procedur obsługi przerwań przypisanych do jednego przerwania. SO QNX6 pozwala na dzielenie przerwań. Oznacza to, że do jednego przerwania przypisanych może być wiele handlerów tworzących łańcuch. Domyślnie nowy handler umieszczany jest na początku łańcuch, co znaczy, że po przyjściu przerwania wykona się jako pierwszy. Kolejność tę można zmienić ustawiając flagę _NTO_INTR_FLAGS_END. Nowy handler dopisany będzie na końcu łańcucha i wykona się jako ostatni. 34/52
QNX Neutrino Przerwania Parametr flagi: _NTO_INTR_FLAGS_PROCESS Gdy flaga ta jest ustawiona, to system kojarzy handler z procesem, a nie z wątkiem. Oznacza to, że handler będzie deinstalowany, gdy kończy się proces, a nie wątek, który zarejestrował ISR. 35/52
QNX Neutrino Przerwania Parametr flagi: _NTO_INTR_FLAGS_TRK_MSK Ma znaczenie, gdy do jednego przerwania dołączonych jest wiele handlerów. Na przykład, gdy zainstalowane są dwa handlery i jeden z nich maskuje przerwanie, to ma ono pozostać zamaskowane tylko dla tego handlera. ZAWSZE musi być ustawiona. 36/52
QNX Neutrino Przerwania Właściwości funkcji obsługi przerwania: Rozmiar stosu, którym dysponuje procedura obsługi przerwania, jest ograniczony. Stąd nie powinna ona zawierać dużych tablic czy innych struktur danych. Bezpiecznie jest przyjąć, że dostępny rozmiar stosu wynosi około 200 bajtów. Procedura obsługi przerwań jest wykonywana asynchronicznie z wątkami należącymi do pewnego procesu i używa wspólnych z nimi danych. Wszystkie zmienne modyfikowane przez handler powinny być poprzedzone słowem kluczowym volatile a ich modyfikacja wewnątrz wątków zabezpieczona przez zablokowanie przerwań. Innym rozwiązaniem jest zastosowanie funkcji realizujących elementarne operacje arytmetyczne i bitowe w niepodzielny sposób. Nazwy tych funkcji zaczynają się od atomic_*. 37/52
QNX Neutrino Przerwania Właściwości funkcji obsługi przerwania: Procedura obsługi przerwania jest wykonywana poza normalnym szeregowaniem, więc powinna być krótka, jak to tylko możliwe. Jeżeli wymagane jest wykonanie czasochłonnych czynności, to powinny być one wykonane w wątku, który zostanie odblokowany przez handlera. Procedura obsługi przerwania nie może wywoływać żadnych funkcji systemowych poza sporadycznymi wyjątkami. 38/52
QNX Neutrino Przerwania Handler vs. event Rozmiar stosu, którym dysponuje procedura obsługi przerwania, jest ograniczony. Stąd nie powinna ona zawierać dużych tablic czy innych struktur danych. Procedura obsługi przerwań jest wykonywana poza normalnym szeregowaniem, więc powinna być tak krótka, jak to tylko możliwe. Jeżeli wymagane jest wykonanie czasochłonnych czynności, to powinny być one wykonane w wątku, który zostanie przez handler odblokowany. 39/52
QNX Neutrino Przerwania Handler vs. event Odblokowany przez zdarzenie wątek ma priorytet i podlega zwykłemu szeregowaniu. Uruchamianie wątków jest łatwiejsze niż handlerów. Większa zwłoka pomiędzy przerwaniem a odblokowaniem wątku. W kodzie procedury obsługi przerwania należy wykonać tylko niezbędne czynności, a następnie powiadomić pewien wątek o wystąpieniu przerwania. Wątek ten wykona resztę pracy. 40/52
RT Linux Przerwania Getting Started with RTLinux.pdf 41/52
RT Linux Przerwania Wirtualny mechanizm przerwań jest kluczowym elementem architektury RT Linuxa. Wszystkie przerwania sprzętowe przechwytywane są przez RT Core. RT Core jednocześnie emuluje kontroler przerwań na potrzeby zwykłego Linuxa, który pracuje tak jakby odbierał przerwania sprzętowe. 42/52
RT Linux Przerwania W RT Linuxie występują dwa rodzaje przerwań: twarde ang. Hard i łagodne ang. Soft. Przerwania twarde są w zasadzie przerwaniami sprzętowymi i posiadają bardzo małe opóźnienia. Przerwanie sprzętowe powoduje uruchomienie handlera RT jeśli jest skojarzony z przerwaniem. Po zakończeniu pracy handlera RT przerwanie zostaje przekazane do Linuxa. W obsłudze przerwań twardych możemy korzystać z ograniczonego zestawu funkcji jądra. 43/52
RT Linux Przerwania W sytuacji, gdy przerwanie nie jest skojarzone z zadaniem krytycznym, to przerwanie takie jest przekazywane do zwykłego Linuxa, pod warunkiem, że żadne zadanie krytyczne nie jest w danej chwili wykonywane. 44/52
RT Linux Przerwania Linux blokuje w niektórych sytuacjach przerwania (np. podczas synchronizacji). RT Linux zapamiętuje taką sytuację. Przychodzące przerwanie oznaczone jest jako oczekujące. Jego zgłoszenie nastąpi natychmiast po odblokowaniu przerwań w Linuxie. Dzieje się tak dzięki zamianie w kodzie jądra Linuxa instrukcji cli, sti i iret odpowiednio na makra S_CLI, S_STI, S_IRET. 45/52
RT Linux Przerwania S_CLI : movl $0, SFIF S_STI : sti pushfl pushl $KERNEL_CS pushl $1f S_IRET 46/52
RT Linux Przerwania S_IRET: push %ds ;zachownie używanych rejestrów na stosie pushl %eax pushl %edx movl $KERNEL_DS,%edx ;Ustawia rejestr segmentu danych na segment jądra mov %dx,%ds cli movl SFREQ,%edx ;sprawdzenie oczekujących przerwań andl SFMASK,%edx bsfl %edx,%eax jz 1f S_CLI ;brak przerwań powrót sti jmp SFIDT (,%eax,4) ;skok do procedury obsługi przerwania 47/52
RT Linux Przerwania 1: movl $1, SFIF popl %edx popl %eax popl %ds iret 48/52
RT Linux Przerwania Łagodne przerwania skojarzone są z Linuxem. Nie zapewniają obsługi w czasie rzeczywistym. W procedurze obsługi tych przerwań można korzystać z funkcji systemowych bez ograniczeń. Reakcja na nie, może być opóźniona o określony czas. Obsługiwane są w czasie braku zadań krytycznych w systemie. 49/52
Windows CE Przerwania Wzajemne powiązania pomiędzy komponentami kernel mode interrupt i wbudowanymi sterownikami urządzeń oraz sprzętem. OAL - OEM Adaptation Layer 50/52
Windows CE Przerwania Przykładowa sekwencja obsługi przerwania: jeżeli moduł Exception handler odbierze przerwanie sprzętowe i jądro wykryje wyjątek wówczas jądro obsłuży przerwanie. W przeciwnym wypadku; moduł jądra wspierający obsługę przerwań powiadamia ISR, aby zablokowała właściwe przerwanie do momentu zakończenia jego obsługi (pozostałe przerwania są odblokowane); moduł obsługi wyjątków wywołuje ISR aby określić sposób obsługi przerwania; 51/52
Windows CE Przerwania Moduł ISH odbiera wartość zwracaną z ISR, która określa co należy zrobić z przerwaniem: SYSINTR_NOP do nothing; SYSINTR_RESCHED jądro przeszeregowuje IST; SYSINTR_XXX, logical interrupt value jądro pobudzone przez ISR budzi wątek IST, który wykonuje swoją pracę. IST tworzy zdarzenie i oczekuje na nie; obudzony IST wykonuje całą pracę wymaganą do obsługi przerwania; jeśli zachodzi taka konieczność IST wywołuje różnego rodzaju funkcje I/O za pomocą, których uzyskuje dostęp do sprzętu w celu wykonania swojej pracy; IST kończy swoją pracę powiadamiając jądro poprzez wywołanie InterruptDone. jądro wywołuje funkcję OAL OEMInterruptDone w celu zakończenia obsługi przerwania. OAL powiadamia sprzęt w celu odblokowania przerwania. 52/52
Windows CE Przerwania Obsługa przerwań podzielona jest na dwie części: Kernel mode interrupt service routine ISR, User mode interrupt service thread IST; Funkcja ISR powinna wykonać minimum pracy niezbędnej do obsługi przerwania: ISR może odczytać dane z urządzenia do bufora w przypadku gdy istnieje ryzyko utraty danych lub nadpisania danych przez kolejne przerwanie; ISR czyści flagi przerwania w urządzeniu; ISR zwraca SYSINTR do jądra systemu; Jądro uruchamia zdarzenie powiązane z przerwaniem, które odblokowuje IST, który odpowiada ISR; Planista szereguje IST. IST kończy obsługę przerwania. 53/52