3 #include "classes/gui.inc"
4 (* czytelnicy pisarze *)
7 var ile , nr : integer,qui:pi;
8 (*nr procesu ktory zostawil informacje lub ostatni FreePl w buforze*)
11 unit ecran : GUI process(node:integer);
13 unit outtext : procedure(x,y:integer, s:string);
15 call GUI_clearArea(x,y,80,16);
16 call GUI_writeText(x,y,unpack(s),c_black,c_LightGrey);
19 unit outmessage: procedure(x,y:integer, s: string);
21 call GUI_clearArea(x,y,80,16);
22 call GUI_writeText(x,y,unpack(s),c_lightgrey,c_red);
25 unit circle: procedure(col,x,y,r : integer);
27 call GUI_Ellipse(x,y,r,r,0,360,c_black,col);
30 unit line : procedure(col,x,y,dlugosc:integer,poziomo:boolean);
32 call GUI_move(x,y); (* pozycja linii *)
35 call GUI_LineTo(x+dlugosc,y,col);
36 else (* linia pionowa *)
37 call GUI_LineTo(x, y+dlugosc,col);
46 unit pisarz: procedure(nr:integer);
47 (*nr jest jednoczesnie numerem kolorem wlasnym i numerem pisarza*)
49 call GUI_Ellipse((nr-1)*150+20,8,10,10,0,360,c_black,nr);
50 call GUI_WriteText((nr-1)*150+50,5,unpack("Author"),c_black,c_white);
51 call GUI_WriteInt((nr-1)*150+30,5,nr,nr,c_white);
52 call GUI_rect((Nr-1)*150+10,20,(nr-1)*150+ 110,200,c_black,c_lightgrey);
56 unit magazyn : procedure(posX,posY : integer);
58 call GUI_Rect(10,250,600,305, c_Black,c_lightgrey);
59 call outtext(posX,posY-8,"B U F F E R");
60 call outtext(posX,posY+60,"READERS' QUEUE");
61 call outtext(posX+ 300, posY+60,"WRITERS'QUEUE");
66 enable magazyn, pisarz;
68 accept Fin, line, circle, outtext, outmessage,
69 GUI_Keypressed, GUI_ClearArea
74 unit pi : elem process(node,nr : integer, M : monitor,ek:ecran);
75 (* nr jest numerem pisarza *)
76 const stala=76;(* dludosc linii rysowanej przez pisarza *)
77 var posX, posY : integer; (* pozycja pisarza na ekranie *)
79 unit tempo : procedure(n:integer);
82 for i :=1 to n do i:= i od
86 unit wezwij_put : procedure(e:elem);
89 (* najpierw wymazuje z obszaru pisarza *)
90 call ek.outtext((nr-1)*150+20,210,"try to send");
93 call ek.line(7,(nr-1)*150+22,26+i,stala, true);
96 call ek.GUI_clearArea((nr-1)*150+20,210,80,16);
98 call ek.outtext((nr-1)*150+20,210,"waiting");
100 call M.putt(e.nr, e.qui, e.ile, czekaj);
103 call ek.outmessage((nr-1)*150+20,210,"stopped");
105 call ek.GUI_clearArea((nr-1)*150+20,210,80,16);
107 call ek.outtext((nr-1)*150+20,210,"sending");
113 unit wezwij_get : procedure(inout e:elem);
114 var czekaj : boolean, qui:pi,n,ch:integer ;
115 (*autor chce cos odczytac z magazynu *)
119 n := e.nr; qui := e.qui;
120 call m.gett(n,qui,ch, czekaj);
122 call ek.outmessage((nr-1)*150+20,210,"stopped");
124 call ek.GUI_clearArea((nr-1)*150+20,210,80,16);
125 (* magazyn jest zajety; pisarz zostanie wpisany do kolejki oczekujacych*)
128 e:=new elem; e.nr :=n;
129 e.qui:=qui; e.ile :=ch;
130 call ek.outtext((nr-1)*150+20,210,"receiving");
133 call ek.line(n,(nr-1)*150+22,26+i,stala,true);
136 call ek.GUI_clearArea((nr-1)*150+20,210,80,16);
138 (* otrzymalem wiadomosc od pisarza nr *)
144 unit fin : procedure;
147 var el: elem, r : real;
155 (*if r=0 then accept fin; exit fi; *)
156 (* to niezbt dobre rozwiazanie ze wzgl na kolejnosc *)
158 (* pisarz cos produkuje i chce to wyslac *)
162 el.ile := random*170;
163 call ek.outtext((nr-1)*150+20,210,"writing");
166 call ek.line(nr,(nr-1)*150+22,26+i,stala,true);
169 call ek.GUI_clearArea((nr-1)*150+20,210,80,16);
173 (* pisarz zdecydowal sie cos przeczytac *)
175 el.nr := nr; el.qui := this pi;
176 call ek.outtext((nr-1)*150+20,210,"demanding");
178 call ek.GUI_clearArea((nr-1)*150+20,210,80,16);
180 call ek.outtext((nr-1)*150+20,210,"reading");
181 (* czytam przesylke *)
182 for i := el.ile downto 1
184 call ek.line(7,(nr-1)*150+22,26+i,stala,true);
187 call ek.GUI_clearArea((nr-1)*150+20,210,80,16);
193 unit monitor : elem process(node,size,max_proc : integer, ek:ecran);
197 unit Belem : class(e:elem,posx:integer);
200 var buffer : arrayof Belem,
202 queue_pour_ecrire : queue,
204 counter, ilosc_ak, i, nb_proc: integer;
205 (* zmienna counter mowi ile jest elementow w buforze *)
206 (* ilosc_ak = ilosc miejsca w magazynie juz wykorzystana*)
207 (* nb_proc = ilosc procesow stojacuch w obu kolejkach *)
210 var qui : pi, next : qEL;
213 unit queue: class(pos:integer);
214 var first, last : qEL;
216 unit into : procedure(p: pi,nr: integer (* nr is the no of pi*));
217 var aux : qEL, c: integer;
220 call ek.circle(nr,pos+30,339,12);
222 (* rysowanie kolka w odpowiedniej kolejce i odp.kolorem*)
223 nb_proc := nb_proc+1;
228 first := aux; last := aux
235 unit out : function : pi;
237 if first=none then exit else
238 nb_proc := nb_proc -1;
239 call ek.circle(15,pos,339,13);
241 (* wymazanie kolka w odpowiedniej kolejce *)
247 unit empty : function: boolean;
249 result := (first=none) ;
253 unit tempo : procedure(n:integer);
256 for j := 1 to n do j:= j od;
259 unit putt : procedure(nr:integer,qui:pi,ch:integer; output czekaj : boolean);
260 var aux, i : integer,e : elem;
263 if (counter< 20 and ilosc_ak+ch<size)
269 counter := counter +1;
270 buffer(counter) := new Belem(e,x);
271 (* monitor zapisuje przesylke od *)
273 call ek.line(nr,x+i,posY+7,39,false);
277 ilosc_ak := ilosc_ak+ch;
279 if not queue_pour_lire.empty
281 (* monitor budzi pisarza z kolejki czytelnikow *)
282 p := queue_pour_lire.out;
283 call ek.GUI_clearArea((nr-1)*150+20,210,80,16);
287 (* nie ma miejsca w buforze dla pisarza *)
289 call queue_pour_ecrire.into(qui,nr);
293 unit gett : procedure(inout nr:integer, qui:pi, ch:integer, czekaj:boolean);
294 var i ,j : integer, e:elem , p:pi;
297 if counter<> 0 then (* mozna cos zabrac z magazynu *)
298 e := buffer(counter).e;
299 nr := e.nr; qui := e.qui; ch := e.ile;
300 counter := counter - 1;
302 for i := x downto x-ch
304 call ek.line(7,i,posY+7,39,false);
309 ilosc_ak := ilosc_ak-ch;
310 (* w magazynie zwolnilo sie miejsce i ktos moze wpisac *)
312 if not queue_pour_ecrire.empty
314 (* writeln("M budzi pisarza ktory chce pisac ");*)
315 p := queue_pour_ecrire.out;
316 call ek.GUI_clearArea((nr-1)*150+20,210,80,16);
319 else (*jezeli counter=0 tzn. nic nie ma w magazynie *)
320 (* writeln("M wpisuje pisarza",nr,"do kolejki czytelnikow");*)
322 (* qui := p;*) (* to jest instrukcja niepotrzebna *)
323 call queue_pour_lire.into(p,nr);
327 begin (* tu sie zaczyna tresc monitora *)
329 array buffer dim(1:20);
332 x := 15; ilosc_ak := 0;
334 queue_pour_lire := new queue(Qpos);
335 queue_pour_ecrire := new queue(Qpos+300);
336 call ek.magazyn(posX,posY);
342 if ek.GUI_KeyPressed<>0 then call ek.fin fi;
343 if nb_proc = max_proc
345 call ek.outmessage(470,339,"DEADLOCK! press CR");
357 i, j, nbNodes,ile : integer,
358 EK : ecran, EKR : arrayof ecran,
359 PROC : arrayof arrayof pi, p : pi,
360 TABnodes, NbProc : arrayof integer;
365 write("The Number of nodes- processors ?: ");
366 readln(NbNodes); writeln(nbNodes);
367 if nbNodes = 0 then call ENDRun fi;
368 array TABnodes dim (1: NbNodes);
369 array NbProc dim (1: NbNodes);
372 for i := 1 to NbNodes
374 write("Node number ",i, " ? ");
375 readln( TABnodes(i)); writeln;
376 write("Number of Readers/Writers on this node",TABnodes(i)," ? ");
377 readln(NbProc(i)); writeln;
378 ile := ile + NbProc(i);
381 array EKR dim (1:NbNodes);
382 for i := 1 to nbNodes
392 (* ile= ilosc utworzonych procesow typu Readaes/writers na wszystkich razem komputerach polaczonych w siec*)
393 (* zakladam, ze pierwszy z uzytych "node" =0 i ma ilosc procesow >0 - to oczywiscie mozna zmienic!!*)
397 M := new monitor(0,600,ile,ek);
401 array PROC dim (1: nbNodes);
402 for i := 1 to nbNodes
404 array PROC(i) dim (1 : NbProc(i));
406 for j := 1 to NbProc(i)
409 P := new pi(ile,j,M,ek);
416 call ek.outmessage(400,440,"press CR");
418 call ek.outtext(400,440," press any key to STOP ");
422 for j := 1 to NbProc(i)