Może jeszcze kilka pytań:
Beck i in. podają następujący kod na str. 61 "wywołania systemowe":
PSEUDO_CODE system_call(int sys_call_num, sys_call_args) {
/*...*/
I teraz przed poniższym fragmentem komentarz autorów:
[quote]Rzeczywiste zadanie wywołania systemowego jest w tym miejscu zakończone. Jednak zanim będzie można kontynuować wykonywanie procesu, trzeba jeszcze uporać się z pewnymi zadaniami administracyjnymi. W rzeczywistości poniższy kod wykonywany jest nie tylko po każdym wywołaniu systemowym, ale również po każdym "wolnym" przerwaniu i z tego powodu zawiera pewne instrukcje, które mają znaczenie tylko dla procedur obsługi przerwań. [/quote]
Wcześniej zastanawiałem się jak to możliwe, iż po wolnym przerwaniu jest wykonywana część kodu funkcji system_call, ale zacząłem się domyślać (nie wiem czy słusznie), iż musi być to realizowane przez skok goto. Jednak nasuwa się mi pytanie: dlaczego w takim razie ret_from_sys_call jest umieszczone w funkcji system_call? Czy nie lepiej umieścić tę część kodu w całkiem innej funkcji i nadać jej jakąś nazwę, która lepiej oddawałaby jej przeznaczenie?
[quote]Ponieważ całkiem prawdopodobne jest zagnieżdżenie jednej procedury obsługi przerwania w drugiej, zmienna intr_count zarządza głębokością zagnieżdżeń procedur obsługi przerwań. Jeśli nie ma ona wartości zero, oznacza to, że została przerwana kolejna procedura obsługi przerwań i funkcja ret_from_sys_call natychmiast zwraca sterowanie.[/quote]
ret_from_sys_call:
if (intr_count) goto exit_now;
if (bh_mask & bh_active) {
handle_bottom_half:
++intr_count;
sti();
do_bottom_half();
--intr_count;
}
sti();[/code]
Czy tutaj ++intr_count, --intr_count jest równoważne intr_count=1, intr_count=0? Jeżeli nie, to jestem nieco zmieszany - przecież przed chwilą sprawdzaliśmy, czy intr_count nie jest równe zero! Jeżeli istotnie może się zdarzyć taka sytuacja, że inkrementacja intr_count może dać wartość różną od jedynki, to widzę tutaj tylko jedną możliwość - mianowicie musiało dojść do przełączenia zadań przez scheduler. W związku z tym pytanie: czy powyższy kod jest wywoływany w sposób atomowy? Jeżeli tak nie jest, to IMO przetwarzanie powyższego kodu może się zakończyć fatalnie - tzn. po inkrementacji intr_count (ale jeszcze przed sti()) scheduler może przekazać procesorowi do wykonywania inne zadanie, to zadanie spowoduje zwiększenie intr_count, tuż po tej instrukcji scheduler przełączy się znowu na powyższy kod i w efekcie otrzymamy błędne wartości intr_count.
Dalej, mamy tu instrukcję sti(), ale nie do końca rozumiem celowości jej zamieszczenia tutaj - powoduje ona odblokowanie przerwań, ale z jakiego powodu przerwania wcześniej miałyby być zablokowane? Wyżej nigdzie nie ma instrukcji cli() (w kodzie w /*...*/ też nie).
Ponadto, na samym początku mamy instrukcję: if (bh_mask & bh_active) - czyli w masce możemy wyłączyć wykonywanie niektórych dolnych połówek (po prostu ustawiając odpowiednie bity na zera). Jaki jest konkretny, uchwytny przykład sytuacji, w której ma to zastosowanie?
[quote]Od tego momentu przerwania są na ogół odblokowywane.[/quote]
Jak to na ogół? Chyba sti() wymusza odblokowanie przerwań, nie widzę wyżej jakiego powodu do używania trybu warunkowego.
[quote]Jeśli do bieżącego procesu zostały wysłane sygnały i nie zablokował on ich odbierania, są teraz przetwarzane. (...) [/quote]
```c
if (current->signal & ~current->blocked) {