Sunteți pe pagina 1din 25

INTRODUCERE

Un executiv de timp real nu difer mult de nucleul unui sistem de operare multitasking, oferind n plus funcii de timp real i trebuind s asigure timpi de rspuns performani. Memoria principal conine la un moment dat mai multe procese care sunt pregtite pentru execuie. Fiecrui program i se acord o cuant de timp pentru utilizarea procesorului. Exist mai muli algoritmi pentru partajarea timpului n care unitatea central este alocat unui anumit proces, n cadrul acestui proiect fiind folosit algoritmul Round-Robin. Randamentul unui astfel de sistem este mai ridicat dect al sistemelor cu prelucrare secvenial. Ele realizeaz o mai bun utilizare a rsurselor i ofer posibilitatea execuiei virtuale a mai multor procese (programe) n acelai timp.

STRUCTURA PROIECTULUI
Clasa RTpr
Clasa de baz n cadrul unui ETR(executiv n timp real) este clasa proces: RTproces. Structura clasei este urmtoarea:
class RTproces { public: AdresaProces p_adr_proces; STARI p_stare; //stare proces char p_nume_proces[9]; //numele procesului int p_dim_stiva; //dimensiunea stivei procesului jmp_buf p_env; //structura pentru salvarea contextului int next; //indica urmtorul proces blocat public: RTproces(); RTproces(info_init_proces, info_init); };

Adresa procesului se afla printr-o construcie de forma:


typedef void (*AdresaProces)() ;

Strile n care poate ajunge un proces sunt urmtoarele:


typedef enum { Activ=1, Pregatit=2, Suspendat=3, Blocat=4, Intarziat=5, Inexistent=6 } STARI;

ACTIV procesul care ruleaz la un moment dat; se va modifica n Planificator(); PREGTIT un proces se afl n aceast stare dac dispune de toate resursele cu excepia UC, fiind un candidat la alocarea acesteia; NTRZIAT procesele ce au solicitat executivului serviciul de ntrziere (delay) pentru un numr specificat de cuante; BLOCAT procesele care au fcut operaia Down asupra unui semafor cu valoarea <=0; listele cu procesele blocate ale semafoarelor, se creeaz prin intermediul cmpului next; SUSPENDAT executivul are toate informaiile despre un proces n aceast stare ,procesul are alocat i stiva, dar nu particip la alocarea resurselor; un proces poate ajunge n aceast stare din oricare alta prin operaia de suspendare (spaiul de stiv nu se elibereaz, sau din aceast stare n PREGTIT prin operaia de pregtire (executat de alt proces)); INEXISTENT - un proces poate ajunge n aceast stare prin funcia de distrugere, semnalnd faptul c i-a terminat execuia (pe care nu o va mai putea relua). Cmpul jmp_buf (predefinit n <setjmp.h>):
typedef struct __jmp_buf { unsigned j_sp;

unsigned j_ss; unsigned j_flag; unsigned j_cs; unsigned j_ip; unsigned j_bp; unsigned j_di; unsigned j_es; unsigned j_si; unsigned j_ds; } jmp_buf[1];

Conine corespunztoare tuturor regitrilor procesorului (cu excepia celor 4 de date), deci va fi utilizat pentru a reine contextul procesului. La iniializarea fiecrui proces aceste cmpuri se iniializeaz cu valorile pe care trebuie s le aib regitrii procesorului la lansarea n execuie a procesului respectiv; cmpurile j_ip i j_cs vor conine adresa de nceput a procesului (ce se furnizeaz n info_init_proces prin intermediul adresei funciei ce implementeaz procesul respectiv, iar j_sp i j_ss adresa vrfului stivei asociate procesului respectiv. Stivele vor fi alocate de executiv, dup crearea obiectelor asociate proceselor i vor avea dimensiunea precizat n info_init_proces, iar valoarea lui j_flag va nsemna posibilitatea sau nu de ntrerupere a procesului (0x200, respectiv 0x0); restul cmpurilor structurii env se iniializeaz cu valorile curente ale regitrilor corespunztori. Modelul de compilare ales va fi small. (SMALL = toate datele se afl ntr-un singur segment standard, codul n alt segment standard, orice instruciune poate fi accesat prin JMP sau CALL de tip NEAR).
RTproces::RTproces(info_init_proces info_init) { next=NEG; strncpy(p_nume_proces,info_init.nume_proces,8); p_nume_proces[8]='\0'; p_dim_stiva=info_init.dim_stiva; p_stare=info_init.stare; p_env->j_ds=_DS; p_env->j_es=_ES; p_env->j_bp=_BP; p_env->j_si=_SI; p_env->j_di=_DI; p_env->j_flag=0x200; p_adr_proces=info_init.adresa_initiala; p_env->j_ip=FP_OFF(p_adr_proces); p_env->j_cs=FP_SEG(p_adr_proces); }

Clasa RTex
Structura clasei executiv este urmtoarea:
class RTexecutiv { public: static RTproces *tabelaProcese[31]; //tabela de procese static int e_nr_procese_null; static int e_nr_procese; //nr. total de procese static int e_proces_activ; //indicele procesului activ static char *e_stiva; //unde ncepe stiva locala alocata proceselor static jmp_buf retEnv; //structura de salvare a contextului pt. procesul //activ curent static Semafor ecran; //resursa comuna public: RTexecutiv(){}; RTexecutiv(int nr_procese, info_init_proces* InitTab); static void interrupt Planificator(...); static void procNULL(); static void Exit(); static void DoIt(); };

Clasa RTexecutiv trebuie s conin tabela proceselor implementat printr-un tablou ce conine pointeri la obiectele proces. Cmpul e_nr_procese conine numrul total de procese. Acest numr se va decrementa pe msur ce procesele sunt terminate. Cmpul e_proces_activ reprezint indicele procesului activ curent. Cmpul e_stiva indic locul de unde ncepe stiva local alocat proceselor.

Constructorul RTexecutiv
Constructorul clasei RTexecutiv trebuie s realizeze urmtoarele operaii: 1. alocarea tabelei de procese i iniializarea acesteia cu informaiile primite prin info_init_proces pentru fiecare proces; se va include aici i procesul null i se va face i pentru acesta iniializarea intrrii corespunztoare n tabela proceselor; 2. calculul dimensiunii stivei totale i alocarea acesteia ;

3. alocarea /eliberarea spaiului rmas liber

(coreleft()-stiva_total=aux) 4. iniializarea stivelor proceselor: j_ss=FP_SEG(stiva); j_sp=FP_OFF(stiva+i*tabela_procese[i].dim_stiva);


RTexecutiv::RTexecutiv(int nr_procese,info_init_proces *InitTab) { int dim_stiva_totala=0; e_nr_procese=nr_procese; e_nr_procese_null=nr_procese+1; //1 for(int i=0;i<e_nr_procese_null-1;i++) { tabelaProcese[i]=new RTproces(InitTab[i]); dim_stiva_totala+=tabelaProcese[i]->p_dim_stiva; } info_init_proces proc_nul={procNULL,"ProcesN",DIM,Activ}; tabelaProcese[e_nr_procese_null-1]=new RTproces(proc_nul); //2 dim_stiva_totala+=tabelaProcese[e_nr_procese_null-1]->p_dim_stiva; //3 char *aux=(char *)malloc(coreleft()-dim_stiva_totala); e_stiva=(char *)malloc(dim_stiva_totala); //4 for(i=0;i<=e_nr_procese_null-1;i++) { tabelaProcese[i]->p_env->j_ss=FP_SEG(e_stiva); tabelaProcese[i]->p_env->j_sp=FP_OFF(e_stiva+(i)*tabelaProcese[i]->p_dim_stiva); } free(aux); e_proces_activ=e_nr_procese_null-1; };

Stivelor procesului trebuie s li se aloce spaiu la sfritul memoriei disponibile (a segmentului de date ce coincide cu cel de stiv n modelul small), prin algoritmul: aloc unui pointer aux spaiul disponibil ce va rmne disponibil dup alocarea stivelor: (de dimensiune = coreleft() - suma_stivelor); aloc unui pointer stiv spaiul necesar tuturor stivelor; iniializeaz stivele, deci cmpurile j_sp, n spaiul alocat stivei; elibereaz spaiul rmas dup alocarea stivelor, deci cel alocat lui aux.

Gestionarea UC (Planificatorul)

Planificatorul realizeaz alocarea UC, pe rnd, proceselor aflate n starea PREGTIT, conform unei discipline prestabilite asigurnd execuia concurent a proceselor. Realocarea presupune : salvarea contextului procesului ACTIV i trecerea n PREGTIT; alegere procesului cruia i se va aloca UC (dintre cele aflate n PREGTIT ) ,acesta devenind ACTIV; lansarea n execuie a noului activ, prin refacerea contextului su.

Realocarea poate avea loc dac: procesului activ i se epuizeaz cuanta de rulare; dup fiecare cuant elementar se genereaz o ntrerupere de ceas ( ntrerupere fizic de nivel 0) ; procesul activ cedeaz UC printr-o cerere explicit; procesul activ solicit un serviciu de autontrziere (delay), pentru un timp specificat trecnd n starea ntrziat, UC trebuind a fi relocat ; procesul activ solicit o resurs nedisponibil prinr-o operaie Down asupra unui semafor , trecnd n starea BLOCAT, iar UC se va reloca.

Planificatorul (Scheduler) este o funcie public a executivului i trebuie s fie nentreruptibil i s salveze contextul (toi regitrii) procesului activ , n stiva proprie acestuia. Prototipul Planificatorului este:
static void interrupt RTexecutiv::Planificator(...);

La apelul ei din codul unui proces ce dorete cedarea UC sau dintr-o alt funcie a executivului , fiind interrupt se introduc n stiv CS i IP. Dup salvarea flag-urilor, IF i TF (Interrupt i Trap Flags) sunt automat pui pe 0, deci funcia este nentreruptibil (apelul ei se face similar cu intrarea hard ntr-o rutin de tratare a unei ntreruperi). nainte de a se trece la execuia codului propriu-zis al funciei, se salveaz n stiv restul regitrilor procesului, deci ntregul su context este salvat pe stiv, posibilitatea refacerii lui necesitnd reinerea vrfului stivei (SS:SP) . Ieirea din funcie se realizeaz cu refacerea automat de pe stiv a regitrilor, apoi cu instruciunea IRET, revenirea la adresa urmtoare apelului Planificatorului i refacerea indicatorilor. Execuia Planificatorului trebuie s realizeze:

slavarea contextului procesului activ (se face automat pe stiv, funcia fiind interrupt); trecerea procesului activ, din starea ACTIV (dac o are) n PREGTIT (s-ar putea ca starea lui s fi devenit anterior BLOCAT sau NTRZIAT, cazuri n care nu se modific); selecia unui proces PREGTIT cruia urmeaz a i se aloca UC; trecerea procesului selectat n ACTIV i completarea informaiilor referitoare la numrul noului proces activ i adresa sa n tabela de procese; refacerea contextului noului proces activ i reluarea sa printr-o instruciune de forma:
if (setjmp(tabelaProcese[vechi_activ]->p_env)) return; else longjmp(tabelaProcese[e_proces_activ]->p_env,1);

Operaiile Planificatorului: se genereaz o ntrerupere de ceas; pune vechiul proces, dac a fost ACTIV, n starea PREGTIT; altfel , starea procesului rmnnd neschimbat; parcurge circular tabela de procese pn la gsirea primului proces PREGTIT, pe care l face noul proces ACTIV; salveaz contextul vechiului proces activ i d controlul noului proces activ (setjmp, longjmp).

Setjmp - salveaz toi regitrii deci i SS, SP ce excepia celor de date, n cmpul env al fostului activ i returneaz 0. Ulterior la un longjmp pereche cu acelai env ca parametru, se reia execuia de la adresa urmtoare lui setjmp, deci return(ce reface regitrii ,apoi IRET).

Algoritmul Round-Robin
Algoritmul carusel simplu (engl.: round-robin) aloc cte o cuant de timp (cuantele pot fi egale sau inegale) pe rnd fiecrui proces pn cnd acesta i termin sarcinile sau trebuie s intre n ateptare. Algoritmul are avantajul c un task care tinde s ocupe procesorul permanent (din greeal), deoarece a intrat ntr-o bucl infinit, nu poate opri
7

celelalte taskuri s avanseze. Este simplu, ceea ce nseamn un timp de execuie sczut. Dezavantajul major este c nu ine cont de urgena de realizare a unor sarcini. Se utilizeaz n sistemele de operare cu divizarea timpului.

Procesul NULL
Acest proces este un proces al executivului, deci un proces sistem; se va crea la iniializarea executivului, pe ultima poziie a tabelei de procese. Codul su va fi un ciclu infinit de apelare a executivului (deci va ceda UC imediat dup primire).
void RTexecutiv::procNULL() { while(1) Planificator(); }

Funcia DoIt
Funcia DoIt este funcia din cadrul executivului care lanseaz primul proces n cadrul executivului de timp real i trateaz ntreruperea de ceas; astfel programul principal const dintr-un apel al funciei DoIt. n cadrul acestei funcii trebuie tratat ntreruperea de ceas. Secvena de mai jos realizeaz acest lucru:
#define CLK 0x08 #define OLD_CLK 0x60 vecheintr=getvect(CLK);// se gsete adresa rutinei standard pentru ntreruperea 08H setvect(OLD_CLK,vecheintr);//se iniializeaz cu aceasta ntrerupere un vector nefolosit setvect(CLK,Planificator);//rutina de tratare va fi Planificatorul

La fiecare ntrerupere de ceas rutina de tratare a ntreruperii va fi Planificatorul().

Funcia Exit
Funcia Exit() din cadrul executivului va pune procesul n starea INEXISTENT i va apela Planificatorul. n aceast funcie se reface adresa
8

rutinei standard de tratare a ntreruperii de ceas printr-un apel setvect numai dac nu mai exist alte procese care nu i-au terminat execuia. Funcia va fi apelat la sfritul fiecrui proces.

Clasa Semafor
Structura clasei Semafor este urmtoarea:
class Semafor { int valoare; int proc_blocate; int prim_proc_bloc; int ultim_proc_bloc; public: Semafor(); void Down();//cand procesul foloseste resursa void Up(); };

Semafoarele sunt folosite pentru ca mai multe procese s poat folosi resurse comune (ex: ecranul, tastatura...).

Membrii clasei Semafor sunt urmtorii: valoare poate lua orice valoare ntreag pozitiv sau negativ; prim_proces_blocat indicele primului proces blocat; ultim_proces_blocat - indicele ultimului proces blocat; proc_blocate - numrul proceselor blocate la semafor.

Cmpul next din cadrul clasei RTproces va indica spre urmtorul proces blocat aflat n lista de ateptare. Dac valoarea lui next este negativ nseamn c nu indic spre alt proces. Toate operaiile asupra unui semafor se exclud mutual. Pentru aceasta ele trebuie s fie nentreruptibile. Practic, un semafor este alctui dintr-o valoare ntreag i o list n care sunt introduse sau din care sunt scoase procesele, care ateapt dup acel semafor. Metodele clasei Semafor sunt: Down procesul folosete resursa; Up procesul elibereaz resursa;

Deoarece operaiile asupra unui semafor trebuie s fie nentreruptibile la nceputul metodelor se vor dezactiva ntreruperile, iar la sfritul acestora se vor activa din nou.
#define DI asm { pushf; cli }//dezactivare ntreruperi #define EI asm { popf } //activare ntreruperi

Down
-

dezactivarea ntreruperilor; decrementeaz valoarea semaforului; dac valoarea semaforului este negativ(semafor blocat) procesul activ care a solicitat resursa devin BLOCAT i va fi introdus n lista proceselor blocate pe ultima poziie (ultim_proces_blocat va avea indicele acestui proces); - incrementeaz numrul proceselor blocate; - activare ntreruperi; - apel Planificator(); dac valoarea semaforului este >=0 procesul obine resursa (se activeaz ntreruperile). dezactivarea ntreruperilor; incrementeaz valoarea semaforului; dac exist procese blocate - primul proces blocat din list devine PREGTIT; - se extrage procesul din coada de ateptare; - decrementeaz numrul proceselor blocate; - activare ntreruperi; - apel Planificator(); dac nu exist procese blocate se activeaz ntreruperile.

UP
-

Clasa Geam
Cu ajutorul clasei Geam se implementeaz o fereastr prin intermediul creia se vor afia rezultatele proceselor. Structura clasei este urmtoare:
class wind{ int xss; int yss; int xdj;

10

int ydj; public: wind(){};

deschenar(int,int,int,int,int);//deseneaza conturul ferestrei scriere(char *,int);//scrie in fereastra initdesstare();//initializeaza fereastra de stare des_stare(int,int,int);//arata starea procesului }; xss,yss,xdj,ydj reprezint coordonatele ferestrei;

GEAM.H
#ifndef _geam_h #define _geam_h #include<iostream.h> #include<conio.h> #include<stdio.h> #include<bios.h> // //extern int a[5][4]; class wind{ int xss,yss,xdj,ydj,linie; public: wind(); ~wind(); deschenar(int, int ,int ,int,int); scriere(char *,int); initdesstare(); des_stare(int ,int,int); }; #endif

GEAM.CPP
#include "geam.h" #includesema.h static int a[4][4]; Semafor sem; wind::wind() {
11

linie=0; } wind::deschenar(int x1,int y1,int x2,int y2,int nrproc) { gotoxy(x1,y1); printf(""); gotoxy(x1,y2); printf(""); gotoxy(x2,y1); printf(""); gotoxy(x2,y2); printf(""); gotoxy(x1+1,y1); for(int i=x1;i<x2-1;i++) printf(""); gotoxy(x1+1,y2); for(i=x1;i<x2-1;i++) printf(""); for(i=1;i<y2-y1;i++) { gotoxy(x1,y1+i); printf(""); } for(i=1;i<y2-y1;i++) { gotoxy(x2,y1+i); printf(""); } gotoxy(x1+1,y1); printf("PROCESUL %d\r\n",nrproc); a[nrproc][0]=x1; a[nrproc][1]=y1; a[nrproc][2]=x2; a[nrproc][3]=y2; } wind::scriere(char *cuv,int nrproc) {
12

sem.Down(); gotoxy(a[nrproc][0]+1,a[nrproc][1]+1+linie); printf(cuv); sem.Up(); linie++; if (linie==a[nrproc][3]-a[nrproc][1]-1) linie=0; } wind::initdesstare() { for(int i=0;i<4;i++) { gotoxy(a[4][0]+1,a[4][1]+2+i*2); printf("proc %d:",i); } } wind::des_stare(int val_maxim,int val_curenta,int nr_proc) { { gotoxy(26+8+(val_curenta*20)/ (val_maxim),10+nr_proc*2); printf("%c",219); } } wind::~wind() { }

RTPR.H
#ifndef _rtpr_h #define _rtpr_h #include <setjmp.h> #define MAX 100 #define NEG -10 typedef void (*AdresaProces)() ;

13

typedef enum { Activ=1, Pregatit=2, Suspendat=3, Blocat=4, Intarziat=5, Inexistent=6 } STARI; typedef struct { AdresaProces adresa_initiala; char nume_proces[9]; int dim_stiva; STARI stare; } info_init_proces; class RTproces { public: AdresaProces p_adr_proces; STARI p_stare; char p_nume_proces[9]; int p_dim_stiva; jmp_buf p_env; int next; //indica urmatorul proces blocat public: RTproces(); RTproces(info_init_proces info_init); }; #endif//_rtproces_h

RTPR.CPP
#include "rtpr.h" #include <string.h> #include <dos.h>

14

RTproces::RTproces() { next=NEG; }; RTproces::RTproces(info_init_proces info_init) { next=NEG; strncpy(p_nume_proces,info_init.nume_proces,8); p_nume_proces[8]='\0'; p_dim_stiva=info_init.dim_stiva; p_stare=info_init.stare; p_env->j_ds=_DS; p_env->j_es=_ES; p_env->j_bp=_BP; p_env->j_si=_SI; p_env->j_di=_DI; p_env->j_flag=0x200; p_adr_proces=info_init.adresa_initiala; p_env->j_ip=FP_OFF(p_adr_proces); p_env->j_cs=FP_SEG(p_adr_proces); }

SEMA.H
#ifndef _sema_h #define _sema_h #define DI asm { pushf; cli } #define EI asm { popf } #define NEG -10 class Semafor { int valoare; int proc_blocate; int prim_proc_bloc; int ultim_proc_bloc; public: Semafor(); void Down();//cand procesul foloseste resursa void Up();

15

}; #endif//_semafor_h

SEMA.CPP
#include "sema.h" #include "rtex.h" extern int e_proces_activ; extern RTproces* tabelaProcese[]; Semafor::Semafor() { valoare=1; proc_blocate=0; prim_proc_bloc=ultim_proc_bloc=NEG; } void Semafor::Down() { DI; if ((--valoare)<0) { RTexecutiv::tabelaProcese[RTexecutiv::e_proces_activ]>p_stare=Blocat; if (prim_proc_bloc==NEG) prim_proc_bloc=ultim_proc_bloc=RTexecutiv::e_proces_activ; else { RTexecutiv::tabelaProcese[ultim_proc_bloc]>next=RTexecutiv::e_proces_activ; ultim_proc_bloc=RTexecutiv::e_proces_activ; } proc_blocate++; EI; RTexecutiv::Planificator(); } else EI; } void Semafor::Up()

16

{ DI; ++valoare; if (proc_blocate) { RTexecutiv::tabelaProcese[prim_proc_bloc]->p_stare=Pregatit; //extragere din coada de asteptare if (RTexecutiv::tabelaProcese[prim_proc_bloc]->next==NEG) { prim_proc_bloc=ultim_proc_bloc=NEG; } else { int aux=prim_proc_bloc; prim_proc_bloc=RTexecutiv::tabelaProcese[prim_proc_bloc]>next; RTexecutiv::tabelaProcese[aux]->next=NEG; } proc_blocate--; EI; RTexecutiv::Planificator(); } else EI; }

RTEX.H
#ifndef _rtex_h #define _rtex_h #include "rtpr.h" #include "sema.h" #define CLK 0x08 //intrerupere de ceas standard #define OLD_CLK 0x60 //intrerupere neutilizata #ifdef __cplusplus #define __CPPARGS ... #else #define __CPPARGS #endif

17

void proc0(); void proc1(); void proc2(); void proc3(); void proc4(); class RTexecutiv { public: static RTproces *tabelaProcese[31]; static int e_nr_procese_null; static int e_nr_procese; static int e_proces_activ; static char *e_stiva; //unde incepe stiva locala alocata proceselor static char *e_stiva_cur; //pointer asociat stivei programului activ static jmp_buf retEnv;//structura de salvare a contextului pt. procesul //activ curent static Semafor ecran; public: RTexecutiv(){}; RTexecutiv(int nr_proces,info_init_proces* InitTab); static void interrupt Planificator(...); static void procNULL(); static void Exit(); static void DoIt(); static RTproces* GetActive() { return tabelaProcese[e_proces_activ]; }; }; #endif //_rtexecut_h

RTEX.CPP
#include "rtex.h" #include <iostream.h> #include <alloc.h> #include <dos.h>
18

#include <string.h> #include <stdio.h> #include <stdlib.h> #define DIM 2000 extern RTexecutiv a; extern int tabc[2][30]; extern int lx,ly; extern nr_procese; int RTexecutiv::e_nr_procese_null; int RTexecutiv::e_proces_activ; RTproces* RTexecutiv::tabelaProcese[31]; int RTexecutiv::e_nr_procese; char* RTexecutiv::e_stiva; char* RTexecutiv::e_stiva_cur; jmp_buf RTexecutiv::retEnv; Semafor RTexecutiv::ecran; static void interrupt (*vecheintr)(...); RTexecutiv::RTexecutiv(int nr_procese,info_init_proces *InitTab) { int dim_stiva_totala=0; e_nr_procese=nr_procese; e_nr_procese_null=nr_procese+1; for(int i=0;i<e_nr_procese_null-1;i++) { tabelaProcese[i]=new RTproces(InitTab[i]); dim_stiva_totala+=tabelaProcese[i]->p_dim_stiva; } info_init_proces proc_nul={procNULL,"ProcesN",DIM,Activ}; tabelaProcese[e_nr_procese_null-1]=new RTproces(proc_nul); dim_stiva_totala+=tabelaProcese[e_nr_procese_null-1]->p_dim_stiva; char *aux=(char *)malloc(coreleft()-dim_stiva_totala); e_stiva=(char *)malloc(dim_stiva_totala); for(i=0;i<=e_nr_procese_null-1;i++)
19

{ tabelaProcese[i]->p_env->j_ss=FP_SEG(e_stiva); tabelaProcese[i]->p_env->j_sp=FP_OFF(e_stiva+(i)*tabelaProcese[i]>p_dim_stiva); } free(aux); e_proces_activ=e_nr_procese_null-1; }; void RTexecutiv::procNULL() { while(1) Planificator(); } void interrupt RTexecutiv::Planificator(...) { static int i; geninterrupt(OLD_CLK); int sw; sw=0; int vechi_activ=e_proces_activ; i=e_proces_activ; if (tabelaProcese[vechi_activ]->p_stare==Activ) tabelaProcese[vechi_activ]->p_stare=Pregatit; tabelaProcese[e_nr_procese_null-1]->p_stare=Activ; do{ if (i==e_nr_procese_null-1) i=-1; i++; if (tabelaProcese[i]->p_stare==Pregatit) { tabelaProcese[e_nr_procese_null-1]->p_stare=Pregatit; tabelaProcese[i]->p_stare=Activ; e_proces_activ=i; sw=1; } } while ((sw==0)); if (setjmp(tabelaProcese[vechi_activ]->p_env)!=0) return;
20

else longjmp(tabelaProcese[e_proces_activ]->p_env,1); } void RTexecutiv::DoIt() { vecheintr=getvect(CLK);// se gaseste adresa rutinei standard pentru //intreruperea 08H setvect(OLD_CLK,vecheintr);//se initializeaza cu aceasta intrerupere //un vector nefolosit setvect(CLK,Planificator); procNULL(); } void RTexecutiv::Exit() { e_nr_procese--; tabelaProcese[e_proces_activ]->p_stare=Inexistent; tabelaProcese[e_nr_procese_null-1]->p_stare=Activ; e_proces_activ=e_nr_procese_null-1; if (e_nr_procese==0) { setvect(CLK,vecheintr); sleep(5); exit(1); } else Planificator(); }

MAIN.CPP
#include <iostream.h> #include <values.h> #include "rtpr.h" #include "rtex.h"
21

#include "geam.h" #include <conio.h> #include <dos.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define DIM 2000 info_init_proces tab[5]={ {proc0,"Proces0",DIM,Pregatit}, {proc1,"Proces1",DIM,Pregatit}, {proc2,"Proces2",DIM,Pregatit}, {proc3,"Proces3",DIM,Pregatit}, {proc4,"Proces4",DIM,Pregatit}, }; int nr_procese=4; wind ferestre[5]; int stare[4][2]; #define INTR 0x09 #ifdef __cplusplus #define __CPPARGS ... #else #define __CPPARGS #endif void interrupt ( *oldhandler)(/*__CPPARGS*/...); static int count=0; char ch; static int sw=0; void interrupt handler(/*__CPPARGS*/...) { sw++; oldhandler(); } void proc0() { char *q;
22

int val; stare[0][0]=100; for(stare[0][1]=0;stare[0][1]<stare[0][0];stare[0][1]++) {val=2*stare[0][1]; itoa(val,q,10); ferestre[0].scriere(q,0); delay(100); ferestre[0].des_stare(stare[0][0],stare[0][1],0); } ferestre[0].scriere("TERMINAT !",0); RTexecutiv::Exit(); }; void proc1() { char *q;//,*q0="nr. ",*q1=" este p.p.",*q2=" nu este p.p."; int val; stare[1][0]=100; for( stare[1][1]=0;stare[1][1]<stare[1][0];stare[1][1]++) { val=3*stare[1][1]+25; itoa(val,q,10); //strcat(q0,q); //if (stare[1][1]==((stare[1][1]/2)*2)) strcat(q0,q1); //else strcat(q0,q2); ferestre[1].scriere(q,1); delay(100); ferestre[1].des_stare(stare[1][0],stare[1][1],1); } ferestre[1].scriere("terminat !!",1); RTexecutiv::Exit(); }; void proc2() { char *q; int val; stare[2][0]=100; for(stare[2][1]=0;stare[2][1]<stare[2][0];stare[2][1]++) {
23

val=990-2*stare[2][1]; itoa(val,q,10); ferestre[2].scriere(q,2); delay(100); ferestre[2].des_stare(stare[2][0],stare[2][1],2); } ferestre[2].scriere("terminat !!!",2); RTexecutiv::Exit(); }; void proc3() { char *q; int val; stare[3][0]=100; for(stare[3][1]=0;stare[3][1]<stare[3][0];stare[3][1]++) { val=1.7*stare[3][1]; itoa(val,q,10); ferestre[3].scriere(q,3); delay(100); ferestre[3].des_stare(stare[3][0],stare[3][1],3); } ferestre[3].scriere("terminat !!!!",3); RTexecutiv::Exit(); }; void proc4() { do{ //for(int i=0;i<4;i++) { ferestre[4].des_stare(stare[0][0],stare[0][1],0); //delay(10); } }while((stare[0][0]!=stare[0][1])&&(stare[0][0]!=stare[0][1])&&(stare[0] [0]!=stare[0][1])&&(stare[0][0]!=stare[0][1])); RTexecutiv::Exit(); };

24

void main() { clrscr(); wind ferestre[4]; ferestre[0].deschenar(1,1,25,7,0); ferestre[1].deschenar(55,1,79,7,1); ferestre[2].deschenar(1,19,25,25,2); ferestre[3].deschenar(55,19,79,25,3); ferestre[4].deschenar(26,8,54,18,4); ferestre[4].initdesstare(); RTexecutiv a(nr_procese,&tab[0]); RTexecutiv::DoIt(); }

25

S-ar putea să vă placă și