4 (* czytelnicy pisarze *)
\r
6 var ile , nr : integer,qui:pi;
\r
7 (*nr procesu ktory zostawil informacje lub ostatni FreePl w buforze*)
\r
10 unit ecran :IIUWGRAPH process(node:integer);
\r
12 unit outtext : procedure(x,y:integer, s:string);
\r
13 var A: arrayof char, i: integer;
\r
16 call color(14); (* yellow *)
\r
18 for i := lower(A) to upper(A) do
\r
19 (* call HASCII(0); *)
\r
20 call HASCII(ord(A(i)));
\r
24 unit outmessage: procedure(x,y:integer, s: string);
\r
25 var A: arrayof char, i: integer;
\r
28 call color(12); (* rouge clair *)
\r
30 for i := lower(A) to upper(A) do
\r
31 call HASCII(ord(A(i)))
\r
35 unit circle: procedure(col,x,y,r : integer);
\r
39 call rectangle(x,y,r,r);
\r
40 for i := 1 to r-1 do
\r
41 call line(col,x,y+i,r,true)
\r
45 unit line : procedure(col,x,y,dlugosc:integer,poziomo:boolean);
\r
48 call move(x,y); (* pozycja linii *)
\r
51 call draw(x+dlugosc,y);
\r
52 else (* linia pionowa *)
\r
53 call draw(x, y+dlugosc);
\r
60 call GrOFF; call endRun
\r
63 unit pisarz: procedure(nr:integer);
\r
66 call circle(2*nr+1,(nr-1)*150+20,8,10);
\r
67 (* call rectangle((nr-1)*150+20,10,10,10);*)
\r
68 call rectangle((Nr-1)*150+10,20,80,200);
\r
71 unit rectangle:procedure(x,y,dl,wys:integer);
\r
76 call draw(x+dl,y+wys);
\r
81 unit magazyn : procedure;
\r
84 call rectangle(10,250,600,50);
\r
89 enable magazyn,pisarz;
\r
91 accept Fin, line, circle, outtext, outmessage
\r
96 unit pi : elem process(node,nr : integer, M : monitor,ek:ecran);
\r
97 (* nr jest numerem pisarza *)
\r
98 const stala=62;(* dludosc linii rysowanej przez pisarza *)
\r
99 var posX, posY:integer; (* pozycja pisarza na ekranie *)
\r
101 unit tempo : procedure(n:integer);
\r
104 for i :=1 to n do i:=i od
\r
108 unit wezwij_put : procedure(e:elem);
\r
109 var czekaj : boolean;
\r
111 (* najpierw wymazuje z obszaru pisarza *)
\r
112 call ek.outtext((nr-1)*150+20,200,"sends ");
\r
113 for i := 1 to e.ile
\r
115 call ek.line(0,(nr-1)*150+22,32+i,stala, true);
\r
118 call ek.outtext((nr-1)*150+20,200,"waiting ");
\r
120 call M.putt(e.nr, e.qui, e.ile, czekaj);
\r
123 call ek.outmessage((nr-1)*150+20,180,"stopped");
\r
131 unit wezwij_get : procedure(inout e:elem);
\r
132 var czekaj : boolean, qui:pi,n,ch:integer ;
\r
136 n := e.nr; qui := e.qui;
\r
137 call m.gett(n,qui,ch, czekaj);
\r
139 call ek.outmessage((nr-1)*150+20,180,"stopped");
\r
142 e:=new elem; e.nr :=n;
\r
143 e.qui:=qui; e.ile :=ch;
\r
144 call ek.outtext((nr-1)*150+20,200,"receives");
\r
147 call ek.line(2*n+1,(nr-1)*150+22,32+i,stala,true);
\r
150 call ek.outtext((nr-1)*150+20,200, " ");
\r
151 (* otrzymalem wiadomosc od pisarza nr *)
\r
157 unit fin : procedure;
\r
160 var el: elem, r : real;
\r
162 call ek.pisarz(nr);
\r
163 call ek.outtext((nr-1)*150+36,8,"Actor");
\r
167 if r=0 then accept fin; exit fi;
\r
168 (* to niezbt dobre rozwiazanie ze wzgl na kolejnosc *)
\r
170 (* pisarz cos produkuje i chce to wyslac *)
\r
174 el.ile := random*175;
\r
175 call ek.outtext((nr-1)*150+20,200,"writes ");
\r
176 for i := 1 to el.ile
\r
178 call ek.line(2*nr+1,(nr-1)*150+22,26+i,stala,true);
\r
181 call ek.outtext((nr-1)*150+20,200," ");
\r
183 call wezwij_put(el)
\r
185 (* pisarz zdecydowal sie cos przeczytac *)
\r
187 el.nr := nr; el.qui := this pi;
\r
188 call ek.outtext((nr-1)*150+20,200,"demands ");
\r
189 call wezwij_get(el);
\r
190 call ek.outtext((nr-1)*150+20,200," ");
\r
192 call ek.outtext((nr-1)*150+20,200,"reads ");
\r
193 (* czytam przesylke *)
\r
194 for i := el.ile downto 1
\r
196 call ek.line(0,(nr-1)*150+22,26+i,stala,true);
\r
199 call ek.outtext((nr-1)*150+20,200," ");
\r
205 unit monitor : elem process(node,size,max_proc : integer, ek:ecran);
\r
208 unit Belem : class(e:elem,posx:integer);
\r
211 var buffer : arrayof Belem,
\r
213 queue_pour_ecrire: queue,
\r
215 counter, ilosc_ak, i,x, nb_proc: integer;
\r
216 (* zmienna counter mowi ile jest elementow w buforze *)
\r
217 (* ilosc_ak = ilosc miejsca w magazynie juz wykorzystana*)
\r
218 (* nb_proc = ilosc procesow stojacuch w obu kolejkach *)
\r
221 var qui : pi, next : qEL;
\r
224 unit queue: class(pos:integer);
\r
225 var first, last : qEL;
\r
227 unit into : procedure(p: pi,nr: integer (* nr is the no of pi*));
\r
228 var aux : qEL, c:integer;
\r
231 call ek.circle(2*nr+1,pos+30,339,10);
\r
233 (* rysowanie kolka w odpowiedniej kolejce i odp.kolorem*)
\r
234 nb_proc := nb_proc+1;
\r
237 aux . next := none;
\r
239 first := aux; last := aux
\r
246 unit out : function : pi;
\r
248 if first=none then exit else
\r
249 nb_proc := nb_proc -1;
\r
250 call ek.circle(0,pos,339,10);
\r
252 (* wymazanie kolka w odpowiedniej kolejce *)
\r
253 result := first.qui;
\r
254 first := first.next;
\r
258 unit empty : function: boolean;
\r
260 result := (first=none) ;
\r
264 unit tempo : procedure(n:integer);
\r
267 for j := 1 to n do x:=x od;
\r
270 unit putt : procedure(n:integer,qui:pi,ch:integer; output czekaj : boolean);
\r
271 var aux, i : integer,e : elem;
\r
274 if (counter< 20 and ilosc_ak+ch<size)
\r
280 counter := counter +1;
\r
281 buffer(counter) := new Belem(e,x);
\r
283 (* monitor zapisuje przesylke od *)
\r
285 call ek.line(2*n+1,x+i,posY+7,39,false);
\r
289 ilosc_ak := ilosc_ak+ch;
\r
291 if not queue_pour_lire.empty
\r
293 (* monitor budzi pisarza z kolejki czytelnikow *)
\r
294 p := queue_pour_lire.out;
\r
295 call ek.outtext((nr-1)*150,180," ");
\r
299 (* nie ma miejsca w buforze dla pisarza *)
\r
301 call queue_pour_ecrire.into(qui,n);
\r
306 unit gett:procedure(inout nr:integer, qui:pi, ch:integer, czekaj:boolean);
\r
307 var i ,j : integer, e:elem , p:pi;
\r
310 if counter<> 0 then (* mozna cos zabrac z magazynu *)
\r
311 e := buffer(counter).e;
\r
312 nr := e.nr; qui := e.qui; ch := e.ile;
\r
313 counter := counter - 1;
\r
315 for i := x downto x-ch
\r
317 call ek.line(0,i,posY+7,39,false);
\r
322 ilosc_ak := ilosc_ak-ch;
\r
323 (* w magazynie zwolnilo sie miejsce i ktos moze wpisac *)
\r
325 if not queue_pour_ecrire.empty
\r
327 (* writeln("M budzi pisarza ktory chce pisac ");*)
\r
328 p := queue_pour_ecrire.out;
\r
329 call ek.outtext((nr-1)*150,180," ");
\r
332 else (*jezeli counter=0 tzn. nic nie ma w magazynie *)
\r
333 (* writeln("M wpisuje pisarza",nr,"do kolejki czytelnikow");*)
\r
335 qui := p;(* to jest instrukcja niepotrzebna *)
\r
336 call queue_pour_lire.into(p,nr);
\r
340 begin (* tu sie zaczyna tresc monitora *)
\r
342 array buffer dim(1:20);
\r
345 x := 12; ilosc_ak := 0;
\r
347 queue_pour_lire := new queue(Qpos);
\r
348 queue_pour_ecrire := new queue(Qpos+300);
\r
350 call ek.outtext(posX,posY-6,"BUFFER");
\r
351 call ek.outtext(posX,posY+60,"READERS' QUEUE");
\r
352 call ek.outtext(posX+ 300, posY+60,"WRITERS'QUEUE");
\r
356 if nb_proc = max_proc
\r
358 call ek.outmessage(470,339,"DEADLOCK! press CR");
\r
368 var PROC : arrayof pi,p,P1,P2,P3 : pi,
\r
371 i, NbProc : integer;
\r
375 write("NbProc : ");
\r
377 array Proc dim(1:NbProc);
\r
379 ek := new ecran(0);
\r
381 M := new monitor(0,550,NbProc,ek);
\r
383 for i := 1 to NbProc
\r
385 P := new pi(0,i,M,ek);
\r
390 call ek.outmessage(550,320,"press CR");
\r
392 call ek.outtext(550,320," ");
\r
394 for i :=1 to NbProc
\r