System Task


Tuto stranku spravuje: Petr Grygarek
e-mail:petr.grygarek@vsb.cz
Zdrojové kódy:
syst_pub.h - header s definicí symbolických konstant pro zprávy (pro MM a ostatní tasky)
systask.h - header s deklarací veřejných funkcí (pro ostatní tasky, příp. jádro)
systask.c - zdrojový kód
Stav modulu: Schopen kompilace, prakticky hotovo, (snad) funkční
Co se musi upravit:

Popis

System task slouží jako interface mezi MM a kernelem, resp. mezi FS a kernelem. Implementované služby řeší zejména ty části systémových volání, ktere operují nad tabulkou proc[]. MM a FS k této tabulce nemohou přistupovat přímo, jelikož není součástí jejich adresového prostoru. Dále je zde služba pro nejnižší úroveň obsluhy signálů a univerzálně použitelná služba pro kopii bloku paměti mezi adresovými prostory dvou procesů.

System task rozumí následujícím zprávám:


(symbolické konstanty pro pojmenování položek zpráv jsou v syst_pub.h, chybové kódy v errno.h

SYS_COPY

Kopie bloku paměti mezi adresovými prostory procesů. Provádí testy platnosti obou adres a zkoumá, zda blok nepřetéká přes hranice zdrojového ani cílového segmentu.

Parametry zprávy (typ m5):
	SRC_PROC, DST_PROC  	- číslo slotu zdrojového/cilového procesu
	SRC_SEG, DST_SEG	- zdrojový/cílový segment (konstanty D,T z const.h)
	SRC_VIR, DST_VIR	- zdrojova/cilova adresa v rámci příslušného segmentu
	BYTE_CNT 		- velikost přenášeného bloku v bajtech

Návratové kódy (RET_ERROR_CODE):
  	OK
	ESRCH			- neplatný zdrojový nebo cílový proces
	EFAULT			- chyba adresace (mimo rozsah paměťového prostoru) 
        ENOMEM 			- blok přesahuje hranici zdrojového/cílového segmentu

SYS_FORK

Informuje kernel o rozštěpení procesu. Zkopíruje parametry ze slotu rodiče (v proc[]) do slotu dětského procesu, nastaví jeho PID, u nového procesu nastaví spotřebované časy na nulu. Nový proces bude mít nastaven příznak NO_MAP, značící, že mu doposud nebyla přidělena mapa paměti a tedy není zatím schopen běhu.

Parametry zprávy (typ m1):
	PARENT - číslo slotu procesu, který se štepí
 	CHILD  - číslo slotu nově vznikajicího procesu			     
	PID    - PID nového procesu 				     

Návratové kódy (RET_ERROR_CODE):
  	OK			
	ESRCH	- některý proces je neplatný		     

SYS_NEWMAP

Nastaví novou paměťovou mapu procesu (tu konstruuje MM). Podle ní nastaví segmentové registry. Zruší příznak NO_MAP a proces naplánuje.

Parametry zprávy (typ m1):

	PROC  		- proces, kterému se paměťová mapa prideluje 
	MEM_PTR		- pointr na pametovou mapu (v adr. prostoru odesílatele)
			  (ukazuje na pole struktur: mem_map[NR_SEGS])         

Návratové kódy (RET_ERROR_CODE):

  	OK
  	ERSCH		- proces je neplatný
	EFAULT		- neplatná adresa bufferu s mapou paměti     
        ENOMEM 		- buffer s mapou paměti přesahuje segment

SYS_EXEC

Dokončení volání exec(). Nastaví PC na začátek programu a přiřadí zadanou hodnotu do registru SP. U procesu, který exec() provedl, "ručně" zruší příznak RECEIVING a naplánuje jej. To proto, že MM nebude na volání exec() odpovídat - není komu, proces odpověď nečeká, image byla vyměněna.

	
Parametry zprávy (typ m1):
	PROC		- číslo procesu
	NEW_SP		- nová hodnota pro stack pointer

Návratové kódy (RET_ERROR_CODE):
	OK
	ESRCH 		- proces je neplatný

SYS_XIT

Informuje kernel o ukončení procesu. Sečte spotřebované procesorové časy a přičte k časům rodičovského procesu. Proces odplánuje, zruší jej z front čekatelů na odeslání zprávy, uvolní slot v proc[].

Parametry zprávy (typ m1):
	PROC  		- číslo končícího procesu
	PARENT		- číslo rodiče končícího procesu

Návratové kódy (RET_ERROR_CODE):
	OK
	ESRCH		- proces je neplatný

SYS_GETSP

Přečtení hodnoty registru SP zadaného procesu. Používá implementace volání brk().
Parametry zprávy (typ m1):
	PROC 		- čislo procesu

Návratová hodnota:
	RET_SP		- hodnota SP registru

Návratové kódy (RET_ERROR_CODE):
	OK
	ESRCH		- proces je neplatný

SYS_TIMES

Zjišteni časů spotřebovaných zadaným procesem (z proc[]).
Parametry zprávy (typ m1):
	PROC 	     	- číslo procesu
	MEMPTR	     	- adresa bufferu (v D segmentu odesílatele)

Návratová hodnota:
	na *MEMPTR umístěna struktura time_struct (syst_pub.h)
	typedef struct {
		real_time user_time;
		real_time sys_time;
		real_time child_user_time;
		real_time child_sys_time;
	} time_struct;

Návratové kódy (RET_ERROR_CODE):
	OK
	ESRCH		- neplatný proces
        ENOMEM 		- buffer přesahuje segment

SYS_SIG

Zajištění skoku do zadané obslužné rutiny a předání čísla obsluhovaného signálu této rutině jako parametr. Jde v podstatě o nasimulování HW přerušení. Při vstupu do rutiny bude zásobník vypadat takto:
		    flags
		    cs
		    ip
		    signal_nr
Obslužná rutina musí ze zásobníku odstranit parametr-číslo signálu a návrat provést instrukcí IRET.

Parametry zprávy (typ m1):

	PROC          	- číslo procesu, kterému signalizovat
	SIG_NR		- číslo signálu
	HANDLER		- adresa obslužné rutiny (v kódovém segmentu procesu)

Návratové kódy (RET_ERROR_CODE):

	OK
	ESRCH			- neplatný proces
	EINVAL			- neplatné číslo signálu
	ENOMEM			- na zásobník procesu nelze umístit flags,cs,
 				  pc,sig_nr	     			     


Veřejné rutiny

Modul dále obsahuje několik veřejných rutin, použitelných v rámci ostatních tasků, které jsou k systasku přilinkovány:

long umap(int proc_nr, int seg, vir_bytes vir_addr, vir_bytes count);

Mapování adresy z adresového prostoru zadaného procesu na lineární adresu (tj. číslo v rozsahu 0-0xFFFFF). Parametrem je číslo procesu (index do tabulky proc[]), typ segmentu a adresa v rámci tohoto segmentu, výstupem lineární adresa. Funkce může rovněž (volitelně) ověřovat, zda je zadaný blok celý součástí jednoho segmentu některého procesu. V tomto případě se mimo určení virtuální adresy zadává i poslední parametr (count), který určuje velikost bloku. Funkce vrací lineární adresu, jestliže je blok součástí adresového prostoru, jinak chybový kód ENOMEM. Pokud má funkce provést pouze přepočet adresy a přetečení bloku nemá být testováno, použije se hodnota parameru count=0.

/*===========================================================================
				umap
	mapovani adresy z adr. prostoru procesu na linearni
   args:
	int proc_nr		- cislo proscesu v proc[]
	int seg			- segment (T, D)
	vir_bytes vir_addr	- virtualni adresa v ramci segmentu
	vir_bytes count		- pocet kopirovanych bytu (test jestli
				  jsme porad uvnitr segmentu)
				  0=netestovat	
   ret:				
	long      		- spoctena fyzicka (linearni) adresa
				  nebo chybovy kod:
				       ESRCH - proces je neplatny
				       ENOMEM - preteceni segmentu (od count)
 ============================================================================*/

int sys_copy(procnr_t src_proc, Byte src_seg, vir_bytes src_addr, procnr_t dst_proc, Byte dst_seg, vir_bytes dst_addr, Word count);

Funkce pro kopírování mezi různými adresovými prostory. Obdoba zprávy SYS_COPY.

/*===========================================================================*
                              sys_copy
 	 Kopirovani meze virtualnimi adresovymi prostory.
  args:
 	src_proc, dst_proc  	- pozice zdrojoveho/ciloveho procesu v proc[]
	src_seg, dst_seg	- segment (T,D)
 	src_addr, dst_addr	- virtualni adresa v ramci segmentu
	count			- pocet kopirovanych bytu
  ret:
 
        OK
        ESRCH - proces je neplatny
        EFAULT - chybna virtualni adresa
        ENOMEM - blok presahuje (src/dest) segment
 *===========================================================================*/

void cause_sig(int proc_nr, int sig_nr);

Funkce používána ostatními tasky, jestliže potřebují vyvolat zaslání signálu zadanému procesu. Např. CLOCK task takto zasílá SIGALRM, terminálový task kupříkladu SIGINT.

/*===========================================================================*
				cause_sig
		 Zaslani signalu procesu nekterym taskem
   args:
	int proc_nr		- cislo procesu, kteremu se posle signal
	int sig_nr		- cislo zasilaneho signalu

   Vola se, pokud chce task zaslat nejakemu procesu signal. Napr.
   - TTY zasila SIGINT pri stisku DEL,
   - CLOCK zasila SIGALRM pri vyprseni nastaveneho casoveho intervalu.

   Signaly ve skutecnosti obsluhuje MM (zadost o obsluhu zpravou KSIG).
   Tasky tuto zpravu nezasilaji primo, protoze MM nemusi byt prave
   schopen zpravu prijmout. Rutina cause_sig() nastavi bit v bitmape
   aktivovanych signalu - proc[].p_pending a vola inform(), ktery se pokousi
   zpravu MM dorucit. Nepovede-li se to okamzite, ucini se tak pozdeji
   z kernelu, kdyz MM pozada o zpravu a zadna jina zprava pro nej
   nebude k dispozici.
 *===========================================================================*/

void inform(void);

Funkce zajišťující předání signálů vygenerovaných jednotlivými tasky memory manageru k doručení příslušným procesům. Zvnějšku System Tasku ji volá pouze jádro a to tehdy, když memory manager volá receive() a není pro něj žádná zpráva a existují nedoručené signály (sig_procs>0).

void sys_task(void);

Vstupní bod pro inicializaci, hlavní smyčka