temat0152

Lemur zaprasza

Do spisu tresci tematu 1

1.5.2 Sygnaly - struktury i funkcje,

Stan uspienia procesu








Spis tresci


Wprowadzenie

Dzialanie

Typy i struktury danych: wprowadzenie,
sigset_t, _sighandler_t,
sigaction

Pola w strukturze procesu: wprowadzenie,
signal, blocked,
sig, exit_signal

Funkcje wewnetrzne jadra i ich implementacja:wprowadzenie,
send_sig(), force_sig(),
do_signal(), notify_parent()


Funkcje systemowe: wprowadzenie,
kill(), sigsuspend(),
sigprocmask(), sgetmask(),
ssetmask(), sigpending(),
signal(), sigaction(),
sigreturn()
Stan uspienia procesu: wprowadzenie,struktura
wait_queue,wake_up(),
wake_up_interruptible(),
interruptible_sleep_on(),
sleep_on()
Bibliografia





Wprowadzenie

Sygnaly sluza do zawiadamiania procesow o wystapieniu pewnych sytuacji
wyjatkowych. Jedyna cecha sygnalu odebranego przez proces jest jego numer.
Niemozliwe jest stwierdzenie nadawcy sygnalu, liczby wyslanych sygnalow,
ani zadnej dodatkowej informacji na jego temat. Stad nazywanie sygnalow
mechanizmem komunikacji jest lekka przesada. Za to doskonale nadaje sie
on do informowania procesu o sytuacji wyjatkowej (patrz Sygnaly-opis).




Dzialanie

Proces w momencie otrzymania sygnalu moze znajdowac sie w roznych stanach,
przez co roznorodne sa takze jego reakcje na sygnal. Jesli sygnal, ktory
jest wysylany, jest zablokowany, to zdarzenia, ktore wymieniam dalej, sa wstrzymywane
az do wykonania przez proces odblokowania sygnalu. Gdy proces jest w stanie
TASK_INSTERRUPTIBLE jest on budzony z kolejki oczekiwania i jego stan jest
ustawiany na TASK_RUNNING (patrz Procesy-stany).
W przypadku gdy proces znajduje sie w trybie uzytkownika i jest gotowy
do wykonania lub wykonywany TASK_RUNNING (patrz Procesy-stany)
to spodziewane, sekwencyjne wykonywanie procesu jest przerywane i wykonywana
jest akcja zwiazana z tym sygnalem (patrz Sygnaly-spis).
Po zakonczeniu wykonywania akcji zwiazanej z sygnalem proces powraca do
miejsca, w ktorym jego dzialanie zostalo przerwane. Gdy proces jest w stanie
TASK_RUNNING lecz znajduje sie w trybie jadra (wykonuje jakas funkcje systemowa)
to akcja zwiazana z sygnalem jest wykonywana po powrocie z funkcji systemowej
a przed wznowieniem programu. Struktury i funkcje, ktore sa tutaj opisane
realizuja podana specyfikacje.






Typy i struktury danych




Wprowadzenie

Wiekszosc typow i struktur danych zwiazanych z sygnalami jest zdefiniowana
w pliku /asm/signal.h. Sa tam takze
zdefiniowane stale zwiazane z numerami sygnalow (patrz Sygnaly-spis).
Procz tego znajdziemy tam stale zwiazane ze zdefiniowanymi typami i strukturami
danych.




Typ sigset_t

Definicja typu sigset_t z pliku asm/signal.h:


typedef unsigned long sigset_t; /* co najmniej 32 bity */

Typ sigset_t sluzy do trzymania zbioru sygnalow (kazdemu sygnalowi
odpowiada dokladnie jeden bit). Jak widac jest to liczba co najmniej 32-bitowa,
stad stala ilosci sygnalow definiowana jest w nastepujacy sposob:

#define _NSIG 32
#define NSIG _NSIG



Typ __sighandler_t

Typ __sighandler_t jest to typ funkcji obslugi przerwania zdefiniowany
w pliku asm/signal.h nastepujaco:

typedef void (*__sighandler_t)(int);

Zdefiniowane sa takze stale, standardowe wartosci zmiennych tego typu:

#define SIG_DFL ((__sighandler_t)0) /* domyslna obsluga sygnalu */
#define SIG_IGN ((__sighandler_t)1) /* ignorowanie sygnalu */
#define SIG_ERR ((__sighandler_t)-1) /* blad (przy powrocie z funkcji signal) */



Struktura sigaction

Oto dokladna definicja struktury sigaction z pliku asm/signals.h:


/* jedna struktura sigaction dla kazdego sygnalu */
struct sigacion {
_sighandler_t *sa_handler; /* funkcja obslugi sygnalu */
sigset_t sa_mask;
unsigned long sa_flags;
void (*sa_restorer)(void);
};

Dodatkowe wyjasnienia:


sa_handler

Funkcja obslugi sygnalu (patrz typ _sighandler_t).

sa_mask

Jest to maska sygnalow ktore maja byc zablokowane zaraz po wolaniu
funkcji obslugi a przed rozpoczeciem jej wykonywania (patrz flaga SA_NOMASK)


sa_flags

Jest to pole flag decydujacych o sposobie obslugi przerwania. Chwilowo
dostepne sa nastepujace flagi (stale zdefiniowane
w pliku asm/signals.h):

SA_NOCLDSTOP


decyduje czy zawiadamiac rodzica procesu o jego zatrzymaniu (patrz
funkcja notifyparent)


SA_SHIRQ


dla przerwan dzielonych przez PCI i EISA


SA_STACK


nie jest jeszcze zaimplementowane, ale w przyszlosci pozwoli na uzywanie
oddzielnego stosu do funkcji obslugi sygnalu poprzez uzycie pola sa_restorer
(obecnie nieuzywanego) w strukturze sigaction jako wskaznika do
stosu


SA_RESTART


flaga do otrzymania sygnalow restartujacych (w przypadku przerwania
dzialania funkcji systemowej przez sygnal z ustawiona flaga funkcja ta
jest ponawiana)(ta flaga byla kiedys domyslna)


SA_INTERRUPT


uzywana jedynie wewnetrznie przez system (obsluga urzadzen zewenetrznych)
w przypadku handlerow przerwan sprzetowych


SA_NOMASK


po wywolaniu handlera nastepne sygnaly nie sa maskowane (ani ten sygnal
ani maska sa_mask)


SA_ONESHOT


po wywolaniu funkcji obslugi sygnalu lecz przed rozpoczeciem jego wykonywania
pole sa_handler struktury sigaction jest ustawiane na
0 (obsluga domyslna)


SA_PROBE


to samo co SA_ONESHOT


SA_SAMPLE_RANDOM


to samo co SA_RESTART


sa_restorer

Obecnie przestarzale, nieuzywane pole, ale kiedys moze (patrz flaga
SA_STACK).







Pola w strukturze procesu



Wprowadzenie

Struktura procesu zostala dokladnie opisana w proces-struktura
procesu. Jednak wiele pol w strukturze procesu dotyczy sygnalow dlatego
zostana one tutaj wymienione z krotkim opisem. Struktura procesu jest zdefiniowana
w pliku include/linux/shed.h.



Pole signal

Pole to jest zadeklarowane:

unsigned long signal;

Maska sygnalow otrzymanych przez proces, ale jeszcze nie obsluzonych.
Kazdemu sygnalowi odpowiada jeden bit liczby 32-bitowej. Dlatego niemozliwe
jest stwierdzenie ile sygnalow danego rodzaju otrzymal proces. Pole to
pokazuje czy proces otrzymal co najmniej jeden sygnal o danym numerze.
Z opisu wynika ze proces nie zawsze reaguje natychmiast na przyjscie sygnalu.
Ma to miejsce na przyklad gdy dany sygnal jest blokowany (patrz sygnaly-dzialanie).



Pole blocked

Pole to jest zadeklarowane:

unsigned long blocked;

Maska sygnalow aktualnie blokowanych przez proces (ich obsluga jest
odwlekana). Zapalony bit odpowiadajacy danemu sygnalowi oznacza ze ow sygnal
jest blokowany. Mozliwe jest blokowanie wszystkich sygnalow procz SIGKILL
i SIGSTOP.



Pole sig

Pole to jest zadeklarowane:

struct signal_struct *sig;

gdzie struktura signal_struct jest zadeklarowana w pliku include/linux/shed.h
nastepujaco:

struct signal_struct {
int count; /* licznik dowiazan do struktury */
struct sigaction action[32]; /* akcje zwiazane z poszczegolnymi sygnalami */
};

Pole sig zawiera informacje o akcjach podejmowanych przez proces
przy otrzymaniu sygnalu. Jak widac w strukturze signal_struct
jest licznik dowiazan do tej struktury-count (handlery sygnalow
moga byc wspoldzielone przez kilka procesow a wlasciwie watkow - patrz
funkcja-clone). Procz tego struktura zawiera tablice, w ktorej pojedynczy
element opisuje akcje zwiazana z sygnalem (patrz struktura-sigaction).




Pole exit_signal

Pole to jest zadeklarowane:

int exit_signal;

Pole to zawiera numer sygnalu, ktory ma byc wyslany do rodzica procesu
w momencie jego smierci (standardowo wynosi SIGCHLD).






Funkcje wewnetrzne jadra i ich implementacja




Wprowadzenie

Istnieja cztery glowne funkcje systemowe zwiazane z obsluga sygnalow,
ktore nie sa dostepne dla zwyklych procesow uzytkownika, ale za to sa uzywane
czesto w roznych miejscach w jadrze systemu.




Funkcja send_sig()

Funkcja ta jest zdefiniowana w /kernel/exit.c.
Sluzy do wyslania sygnalu przez aktualny proces.

DEFINICJA: int send_sig( unsigned long sig, struct task_struct * p, int priv )
WYNIK: 0 w przypadku sukcesu, lub gdy proces docelowy jest zombie lub sygnal 0
-EINVAL gdy p==0 lub sig>32
-EPERM gdy nie ma przywilejow (priv==0) i
to nie jest sygnal SIGCONT lub nie jest z tej samej sesji co p i
p->suid i p->uid sa rozne od current->uid i current->euid
(maja roznych wlascicieli) i
proces wysylajacy nie ma praw zarzadcy systemu



Pierwszym argumentem funkcji jest numer sygnalu, ktory ma byc wyslany
(musi sie zawierac w przedziale 1..32). Argument p jest wskaznikiem do
struktury procesu procesu, do ktorego ma byc wyslany sygnal. Gdy argument
trzeci jest niezerowy wtedy niezaleznie od praw aktualnego procesu (proces
wysylajacy sygnal) nie bedzie mu zabronione wyslanie sygnalu.

Funkcja rozpoczyna swoje dzialanie od sprawdzenia poprawnosci argumentow
i czy aktualny proces (current) moze wyslac sygnal do procesu
p. Z definicji funkcji wynika iz wyslanie sygnalu jest dozwolone
(funkcja nie zwraca -EPERM) gdy jest spelniony jeden z nastepujacych
warunkow:


argument prev jest niezerowy (proces ma przywileje)

wysylany jest sygnal SIGCONT i procesy nadawcy oraz adresata
naleza do tej samej sesji

ktorys z atrybutow uid lub suid procesu adresata
(p) jest rowny ktoremus z atrybutow uid lub euid
procesu nadawcy (w uproszczeniu, gdy procesy maja tego samego wlasciciela)(patrz
procesy-struktura)

proces nadawcy ma przywilej superuser'a.


Nastepnie sprawdzane jest czy sygnal sig to jeden
z sygnalow budzacych (SIGKILL lub SIGCONT). Jesli tak
i proces jest zatrzymany (TASK_STOPPED)(patrz proces-stany)
to proces jest budzony. Procz tego ustawiany jest kod wyjscia procesu na
0 (exit_code) i zerowane sa w polu signal
procesu bity odpowiadajace sygnalom ktore moglyby zatrzymac proces (sa
to: SIGSTOP,SIGTSTP,SIGTTIN,SIGTTOU)(patrz
sygnaly-spis).

Jesli natomiast sygnal sig to jeden z sygnalow,
ktore moglyby spowodowac zatrzymanie procesu (sa to: SIGSTOP,
SIGTSTP, SIGTTIN, SIGTTOU)(patrz sygnaly-spis)
to w polu signal procesu p zerowany jest bit odpowiadajacy
za sygnal budzacy SIGCONT (patrz sygnaly-spis).

Jesli sygnal sig nie jest blokowany ani proces
p nie jest sledzony (tj. gdy sygnal moze byc obsluzony natychmiast)
to: gdy obsluga sygnalu to ignorowanie(SIG_IGN)(patrz typ-sighandler)
i sygnal to SIGCHLD (patrz sygnaly-spis)
nastepuje powrot z funkcji z rezultatem 0. Podobnie jest w przypadku gdy
obsluga sygnalu jest domyslna (SIG_DFL)(patrz typ-sighandler)
a sygnal to jeden z: SIGCONT,SIGCHLD,SIGWINCH,SIGURG.


Nastepnie gdy jeszcze nie zakonczono funkcji w polu signal
procesu docelowego p ustawiany jest bit odpowiadajacy za sygnal
wysylany sig. Dodatkowo gdy proces jest w stanie TASK_INTERRUPTIBLE
(patrz proces-stany) i sygnal nie jest blokowany,
proces p jest budzony. Funkcja zwraca 0.



Funkcja force_sig()

- sluzy do bezwarunkowego wysylania sygnalu.

DEFINICJA: void force_sig( unsigned long sig, struct task_struct *p )
WYNIK: brak

Pierwszym argumentem funkcji jest numer wysylanego sygnalu. p
to wskaznik do struktury procesu procesu docelowego.

Gdy proces docelowy jeszcze istnieje, w polu signal (patrz
proces-struktura) jego struktury jest
ustawiany bit odpowiadajacy za sygnal sig, a w polu blocked
ten sam bit jest zerowany (to zapewni, ze sygnal zostanie obsluzony od razu
po pobraniu procesu do wykonania). Gdy obsluga sygnalu jest ustawiona na
ignorowanie (SIG_IGN) to przestawiana jest na obsluge domyslna
(SIG_DFL)(patrz typ-sighandler).
W przypadku gdy proces p jest w stanie TASK_INTERRUPTIBLE
jest on budzony.




Funkcja do_signal()

- sluzy do obslugi komunikatow ktore przyszly do procesu aktualnego
(current), ale jeszcze nie zostaly obsluzone (ustawione bity na
polu signal-patrz pole-signal).
Funkcja ta jest wolana jedynie w momencie wyjscia z funkcji systemowej
a takze w funkcji systemowej sigsuspend().
Wynika z tego, ze sygnaly sa obslugiwane jedynie w momencie wyjscia z funkcji
systemowej.

DEFINICJA: int do_signal( unsigned long oldmask, struct pt_regs *regs )
WYNIK: 0 w przypadku gdy nie obsluzono zadnego sygnalu
1 gdy obsluzono jeden sygnal

Pierwszym argumentem jest stara maska sygnalow (sprzed wywolania handlera).
Drugi argument to zachowane na stosie wartosci rejestrow procesora sprzed
wywolania funkcji systemowej.

Dzialanie funkcji mozna przedstawic za pomoca nastepujacego pseudoalgorytmu:

{
while (istnieje jeszcze nie obsluzony sygnal nie blokowany)
{
signr=numer takiego sygnalu i bit sygnalu zerowany;
sa=struktura sigaction odpowiadajaca za sygnal signr;
if ( ( proces jest sledzony )&&( signr to nie SIGKILL ) )
{
stan procesu ustalany na TASK_STOPPED , kod wyjscia /*exit_code*/ na signr;
notify_parent(current);
shedule();
if(!(signr=aktualny kod wyjscia procesu /*exit_code*/))
continue;
kod wyjscia procesu /* exit code */ = 0;
if( signr = SIGSTOP )
continue;
if( sygnal signr jest blokowany )
ustawiany jest bit tego sygnalu /*w polu signal procesu*/ , continue;
sa=struktura sigaction odpowiadajaca za sygnal signr;
}
if ( w sa handler jest ustawiony na ignorowanie )
{
  if ( signr to nie SIGCHLD )
continue;
while ( sys_waitpid(-1,NULL,WNOHANG) > 0) ;
/* wszystkie dzieci zombie usuwane */
continue;
}
if ( w sa handler syganalu ustawiony na obsluge domyslna )
{
if ( czy to proces init )
continue;
switch (signr) {
case SIGCONT: case SIGCHLD: case SIGWINCH:
continue;
case SIGTSTP: case SIGTTIN: case SIGTTOU:
if ( grupa procesu jest osierocona /* is_orphaned_pgrp */ )
continue;
case SIGSTOP:
if ( proces jest sledzony )
continue;
stan procesu ustawiany na TASK_STOPPED, kod wyjscia na signr;
if ( czy obsluga sygnalu SIGCHLD u rodzica
ma ustawione zawiadamianie o zatrzymaniu dziecka )
notify_parent();
schedule();
continue;
case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV:
zrzut na dysk obrazu procesu /*CORE DUMP*/;
default:
signal|=bit sygnalu numer ( signr & 0x7f );
w strukturze procesu ustawiona flaga zabicia przez sygnal;
do_exit(signr);
} /* case */
} /* if */
obsluga sygnalu signr handlerem sa z maska oldmask i rejestrami regs;
return 1;
}
return 0;
}




Funkcja notify_parent()

- wolana gdy nalezy poinformowac rodzica jakiegos procesu o jego zatrzymaniu
lub zakonczeniu.

DEFINICJA: void notify_parent( struct task_struct *tsk )
WYNIK: brak


Argumentem funkcji jest struktura procesu, ktory zmienil stan i chce
poinformowac rodzica.

Funkcja rozpoczyna swoje dzialanie od sprawdzania czy rodzicem procesu
jest Init. Jesli tak, to pole exit_signal
procesu tsk jest ustawiane na SIGCHLD.

Po tym do procesu rodzica wysylany jest sygnal exit_signal
(funkcja send_sig z przywilejami
ustawionymi). Nastepnie kolejka czekajacych na smierc tego procesu jest
budzona.






Funkcje systemowe



Wprowadzenie

Funkcje systemowe opisane ponizej wystepuja w zrodlach pod podanymi
nazwami z dodanymi przedrostkami sys_. Wiele z nich korzysta z
funkcji wewnetrznych jadra podanych powyzej.



Funkcja kill()

- sluzy do wysylania sygnalu.

DEFINICJA: int kill( int pid, int sig )
WYNIK: 0 w przypadku sukcesu
-1 gdy nastapil blad; wtedy errno przybiera nastepujace wartosci:
EINVAL bledny parametr (nr sygnalu)
ESRCH nie znaleziony proces do zabicia
EPERM peoces nie posiada praw do wykonania tej funkcji

Drugim argumentem funkcji jest numer sygnalu, ktory ma byc wyslany do
procesu lub grupy procesow opisanych przez pierwszy argument. W zaleznosci
od wartosci argumentu pid zmienia sie adresat:


gdy pid= 0, wysylany jest sygnal do grupy aktualnego procesu

gdy pid=-1, wysylany jest sygnal do wszystkich procesow procz wlasnego
(proby wysylania)

gdy pid<-1, wysylany jest sygnal do grupy -pid

gdy pid> 0, wysylany jest sygnal do procesu o numerze pid


Niezaleznie od rodzaju parametrow funkcja korzysta z funkcji
jadra send_sig z parametrem perm rownym 0. Stad blad EPERM
wystapi tylko wtedy, gdy wystapilby w przypadku wywolania funkcji send_sig.



Funkcja sigsuspend()

- sluzy do ustawiania maski sygnalow blokowanych i oczekiwania na nadejscie
ktoregos z sygnalow nieblokowanych.

DEFINICJA: int sigsuspend( unsigned long set )
WYNIK: -1 z errno ustawionym na EINTR

Argumentem funkcji jest maska blokowania sygnalow.

Dzialanie funkcji:

{
mask=aktualna maska blokawania sygnalow;
ustaw maske blokowania sygnalow na set;
while (1)
{
ustaw stan procesu na TASK_INTERRUPTIBLE;
schedule();
if ( do_signal(mask,...) )
return -1(EINTR);
}
}



Funkcja sigprocmask()

- sluzy do ustawiania maski blokowania sygnalow.

DEFINICJA: int sigprocmask( int how, sigset_t *set , sigset_t *oset )
WYNIK: 0 w przypadku sukcesu
-1 gdy wystapil blad; ustawia ERRNO na:
EINVAL gdy how mialo wartosc nieznanej opcji;

Pierwszym argumentem funkcji jest numer sposobu ustawiania maski. Moze
przybrac wartosc jednej ze stalych zdefiniowanych w asm/signal.h:

#define SIG_BLOCK 0 /* blokowanie sygnalow */
#define SIG_UNBLOCK 1 /* odblokowywanie sygnalow */
#define SIG_SETMASK 2 /* ustawianie nowej maski */

Argument set jest wskaznikiem na nowa maske blokowania sygnalow.
Gdy wskaznik oset jest niezerowy to jest tam wpisywana stara maska
blokowania syganlow sprzed wywolania tej funkcji.



Funkcja sgetmask()

- pobiera maske blokowania sygnalow.

DEFINICJA: int sig( )
WYNIK: maska blokowania sygnalow



Funkcja ssetmask()

- ustawia maske blokowania sygnalow.

DEFINICJA: int ssetmask( int newmask )
WYNIK: poprzednia maska blokowania sygnalow



Funkcja sigpending()

pobiera zbior wstrzymywanych (przez maske blokowania) sygnalow .

DEFINICJA: int sigpending( sigset_t *set )
WYNIK: 0 w przypadku sukcesu
-1 gdy nastapil blad zapisu pod adres set

Zbior blokowanych sygnalow jest wstawiany pod set.



Funkcja signal()

ustawia nowa procedure obslugi sygnalu.

DEFINICJA: _sighandler_t signal( int signum , _sighandler_t handler )
WYNIK: poprzedni handler obslugi tego sygnalu w przypadku sukcesu
SIG_ERR gdy nastapil blad

Argument signum oznacza numer sygnalu, a handler to
nowa procedura obslugi sygnalu (patrz typ _sighandler_t).



Funkcja sigaction()

ustawia nowa akcje zwiazana z danym sygnalem.

DEFINICJA: int sigaction( int signum , const struct sigaction *action ,
struct sigaction *oldaction)
WYNIK: 0 w przypadku sukcesu
-1 gdy nastapil blad (errno=EINVAL)

Ustawia nowa akcje action zwiazana z sygnalem signum.
Stara akcja zwiazana z tym sygnalem jest wpisywana na oldaction.
Oba parametry sa typu struct sigaction.



Funkcja sigreturn()

jest wywolywana przy powrocie z procedury obslugi handlera sygnalu.


DEFINICJA: int sigreturn( )
WYNIK: brak

Funkcja powinna byc wywolywana przy powrocie z kazdej procedury obslugi
sygnalu.






Stan uspienia procesu




Wprowadzenie

Biorac pod uwage definicje stanu uspienia z ksiazki Bacha (patrz Bibliografia)
najblizszy temu opisowi wydaje sie stan TASK_INTERRUPTIBLE (patrz proces-stany).
Jest to taki stan zatrzymania procesu, ktory moze byc przerwany przez sygnal.
Procesy przebywajace w tym stanie sa w wiekszosci przypadkow zatrzymane
na strukturze kolejki oczekiwania (struct wait_queue).
Do usypiania i budzenia calych kolejek oczekiwania sluza funkcje opisane
ponizej.




Struktura wait_queue

Definicja typu sigset_t z pliku linux/wait.h:


struct wait_queue {
struct task_struct * task;
struct wait_queue * next;
};

Na pojedynczej strukturze tego typu sa wstrzymywane wszystkie procesy,
ktore maja byc obudzone w przypadku wystapienia zdarzenia z pewnej grupy
zdarzen.



Funkcja wake_up()

Funkcja wake_up jest zaimplementowana w pliku linux/kernel/sched.c.

DEFINICJA: void wake_up( struct wait_queue **q )
WYNIK: brak

Funkcja budzi wszystkie procesy znajdujace sie na kolejce oczekiwania
a bedace w stanie TASK_INTERRUPTIBLE lub TASK_UNINTERRUPTIBLE. Budzenie
procesu polega na ustawieniu stanu procesu na TASK_RUNNING i wlozeniu go
do kolejki procesow gotowych. O usuniecie z kolejki oczekiwania zadba sam
proces obudzony.



Funkcja wake_up_interruptible()

Funkcja wake_up_interruptible jest zaimplementowana w pliku linux/kernel/sched.c.

DEFINICJA: void wake_up_interruptible( struct wait_queue **q )
WYNIK: brak

Funkcja budzi wszystkie procesy znajdujace sie na kolejce oczekiwania
a bedace w stanie TASK_INTERRUPTIBLE. Budzenie procesu polega na ustawieniu
stanu procesu na TASK_RUNNING i wlozeniu go do kolejki procesow gotowych.
O usuniecie z kolejki oczekiwania zadba sam proces obudzony (czyli jak
wyzej).



Funkcja interruptible_sleep_on()

Funkcja interruptible_sleep_on jest zaimplementowana w pliku linux/kernel/sched.c.

DEFINICJA: void interruptible_sleep_on( struct wait_queue **q )
WYNIK: brak

Funkcja usypia proces aktualny na kolejce q ustawiajac jego
stan na TASK_INTERRUPTIBLE.

Funkcja rozpoczyna dzialanie od dodania procesu aktualnego do kolejki
q i ustawieniu stanu procesu na TASK_INTERRUPTIBLE. Nastepnie
wywolywana jest funkcja schedule() zmiany procesu aktualnego. Po obudzeniu
procesu jest on usuwany z kolejki q.



Funkcja sleep_on()

Funkcja sleep_on jest zaimplementowana w pliku linux/kernel/sched.c.

DEFINICJA: void sleep_on( struct wait_queue **q )
WYNIK: brak

Funkcja usypia proces aktualny na kolejce q ustawiajac jego
stan na TASK_UNINTERRUPTIBLE (patrz wyzej).




Bibliografia


Pliki zrodlowe Linuxa 2.0.20:


include/asm/signal.h (definicje
stalych i typow)

include/linux/wait.h (definicje stalych
i typow)

kernel/signal.c (implementacja)


linux/arch/i386/kernel/signal.c
(implementacja)

linux/kernel/exit.c (implementacja)

linux/kernel/sched.c (implementacja)


W. Richard Stevens: Programowanie zastosowan sieciowych w systemie
UNIX

Maurice J. Bach: Budowa systemu operacyjnego UNIX




Autor: Rafal Bledzinski
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • teen-mushing.xlx.pl
  • Wątki
    Powered by wordpress | Theme: simpletex | © Lemur zaprasza