Added upstream version.
[vlp.git] / examp / piszczyt.log
1  
2  program processus4;
3  #include "classes/gui.inc"
4 (* czytelnicy pisarze *)
5     
6    unit elem : class;
7    var ile , nr : integer,qui:pi;
8    (*nr procesu ktory zostawil informacje lub ostatni FreePl w buforze*)
9    end elem;
10  
11    unit ecran : GUI process(node:integer);
12  
13       unit outtext : procedure(x,y:integer, s:string);
14       begin 
15            call GUI_clearArea(x,y,80,16);                   
16            call GUI_writeText(x,y,unpack(s),c_black,c_LightGrey);          
17       end outtext;
18       
19       unit outmessage: procedure(x,y:integer, s: string);
20       begin 
21         call GUI_clearArea(x,y,80,16);     
22         call GUI_writeText(x,y,unpack(s),c_lightgrey,c_red);
23       end outmessage;
24
25       unit circle: procedure(col,x,y,r : integer);   
26       begin
27            call GUI_Ellipse(x,y,r,r,0,360,c_black,col);
28       end circle;
29  
30       unit line : procedure(col,x,y,dlugosc:integer,poziomo:boolean);
31       begin
32            call GUI_move(x,y); (* pozycja linii *)
33            if poziomo
34            then
35               call GUI_LineTo(x+dlugosc,y,col);
36            else (* linia pionowa *)
37               call GUI_LineTo(x, y+dlugosc,col);
38            fi;
39       end line;
40
41       unit Fin: procedure;
42       begin
43          call endRun
44       end fin;
45  
46       unit pisarz: procedure(nr:integer);
47       (*nr jest jednoczesnie numerem kolorem wlasnym i numerem pisarza*)
48       begin
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);
53       end pisarz;
54  
55  
56       unit magazyn : procedure(posX,posY : integer);
57       begin
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");
62       end magazyn;
63    begin
64         call GUI_clear;
65         return;
66         enable magazyn, pisarz;
67         do
68             accept  Fin, line, circle, outtext, outmessage, 
69            GUI_Keypressed, GUI_ClearArea
70         od;
71  
72    end ecran;
73  
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 *)
78  
79    unit tempo : procedure(n:integer);
80    var i : integer;
81    begin
82        for i :=1 to n do i:= i od
83    end tempo;
84  
85  
86    unit wezwij_put : procedure(e:elem);
87    var czekaj : boolean;
88    begin
89          (* najpierw wymazuje z obszaru pisarza *)
90          call ek.outtext((nr-1)*150+20,210,"try to send");
91          for i := 1 to e.ile
92          do
93              call ek.line(7,(nr-1)*150+22,26+i,stala, true);
94              call tempo(50);
95          od;
96          call ek.GUI_clearArea((nr-1)*150+20,210,80,16);
97  
98          call ek.outtext((nr-1)*150+20,210,"waiting");
99          do
100             call M.putt(e.nr, e.qui, e.ile, czekaj);
101             if czekaj 
102             then
103                call ek.outmessage((nr-1)*150+20,210,"stopped"); 
104                stop ;
105                call ek.GUI_clearArea((nr-1)*150+20,210,80,16);
106             else 
107                  call ek.outtext((nr-1)*150+20,210,"sending");
108                  exit 
109             fi;
110          od;
111     end wezwij_put;
112  
113     unit wezwij_get : procedure(inout e:elem);
114        var czekaj : boolean, qui:pi,n,ch:integer ;
115        (*autor chce cos odczytac z magazynu *)
116     begin
117  
118        do
119            n := e.nr; qui := e.qui;
120            call m.gett(n,qui,ch, czekaj);
121            if czekaj then 
122              call ek.outmessage((nr-1)*150+20,210,"stopped"); 
123              stop ;
124              call ek.GUI_clearArea((nr-1)*150+20,210,80,16);
125              (*  magazyn jest zajety; pisarz zostanie wpisany do kolejki oczekujacych*)
126
127            else
128                e:=new elem; e.nr :=n;
129                e.qui:=qui; e.ile :=ch;
130                call ek.outtext((nr-1)*150+20,210,"receiving");
131                for i := 1 to ch
132                do
133                   call ek.line(n,(nr-1)*150+22,26+i,stala,true);
134                   call tempo(100);
135                od;
136                call ek.GUI_clearArea((nr-1)*150+20,210,80,16);
137                
138 (*           otrzymalem wiadomosc od pisarza nr        *)
139                exit
140            fi;
141        od;
142     end wezwij_get;
143  
144     unit fin : procedure;
145     end;
146  
147 var el: elem, r : real;
148 begin
149    call ek.pisarz(nr);
150   
151     
152    return;
153    do
154        r := random*100;
155        (*if r=0 then accept fin; exit fi; *)
156        (* to niezbt dobre rozwiazanie ze wzgl na kolejnosc *)
157        if r<50 then
158             (*  pisarz cos produkuje i chce to wyslac *)
159             el := new elem;
160             el.qui := this pi;
161             el.nr := nr;
162             el.ile := random*170;
163             call ek.outtext((nr-1)*150+20,210,"writing");
164             for i := 1 to el.ile
165             do
166                call ek.line(nr,(nr-1)*150+22,26+i,stala,true);
167                call tempo(100);
168             od;
169             call ek.GUI_clearArea((nr-1)*150+20,210,80,16);
170             call tempo(100);
171             call wezwij_put(el)
172        else
173            (* pisarz zdecydowal sie cos przeczytac  *)
174              el := new elem;
175              el.nr := nr; el.qui := this pi;
176             call ek.outtext((nr-1)*150+20,210,"demanding");
177             call wezwij_get(el);
178             call ek.GUI_clearArea((nr-1)*150+20,210,80,16);
179             call tempo(100);
180             call ek.outtext((nr-1)*150+20,210,"reading");
181             (* czytam przesylke *)
182             for i := el.ile downto 1
183             do
184                call ek.line(7,(nr-1)*150+22,26+i,stala,true);
185                call tempo(50);
186             od;
187             call ek.GUI_clearArea((nr-1)*150+20,210,80,16);
188  
189        fi;
190     od;
191 end pi;
192  
193 unit monitor : elem  process(node,size,max_proc : integer, ek:ecran);
194 const posX = 30,
195          posY = 250;
196
197    unit Belem : class(e:elem,posx:integer);
198    end Belem;
199  
200 var     buffer : arrayof Belem,
201           queue_pour_lire,
202           queue_pour_ecrire : queue,
203           Qpos , x,y: integer,
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 *)
208  
209    unit qEl: class;
210     var  qui : pi, next : qEL;
211    end qEL;
212  
213    unit queue: class(pos:integer);
214    var first, last : qEL;
215  
216       unit into : procedure(p: pi,nr: integer (* nr is the no of pi*));
217       var aux : qEL, c: integer;
218       begin
219  
220            call ek.circle(nr,pos+30,339,12);
221            pos := pos+30;
222            (* rysowanie kolka w odpowiedniej kolejce i odp.kolorem*)
223            nb_proc := nb_proc+1;
224            aux := new qEL;
225            aux .qui :=p;
226            aux . next := none;
227            if first=none then
228                 first := aux; last := aux
229            else
230               last.next := aux;
231               last := aux;
232            fi;
233       end into;
234  
235       unit out : function : pi;
236       begin
237           if first=none then exit else
238              nb_proc := nb_proc -1;
239              call ek.circle(15,pos,339,13);
240              pos :=pos-30;
241              (* wymazanie kolka w odpowiedniej kolejce *)
242              result := first.qui;
243              first := first.next;
244           fi;
245       end out;
246  
247       unit empty : function: boolean;
248       begin
249           result :=  (first=none) ;
250       end empty;
251    end queue;
252  
253    unit tempo : procedure(n:integer);
254    var j : integer;
255    begin
256         for j := 1 to n do j:= j od;
257    end tempo;
258  
259    unit putt : procedure(nr:integer,qui:pi,ch:integer; output czekaj : boolean);
260    var  aux, i : integer,e : elem;
261    begin
262           
263          if (counter< 20 and ilosc_ak+ch<size)
264          then
265                 e := new elem;
266                 e.nr :=nr;
267                 e.ile := ch;
268                 e.qui := qui;              
269                 counter := counter +1;
270                 buffer(counter) := new Belem(e,x);
271     (*         monitor zapisuje przesylke od        *)
272                 for i :=1 to ch do
273                       call ek.line(nr,x+i,posY+7,39,false);
274                       call tempo(50);
275                 od;
276                 x := x+ ch;
277                 ilosc_ak := ilosc_ak+ch;
278                 czekaj := false;
279                 if not queue_pour_lire.empty
280                 then
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);
284                     resume(p);
285                  fi;
286             else
287 (*               nie ma miejsca w buforze dla pisarza      *)
288                  czekaj := true;
289                  call queue_pour_ecrire.into(qui,nr);
290             fi;
291       end putt;
292  
293       unit gett : procedure(inout nr:integer, qui:pi, ch:integer, czekaj:boolean);
294       var i ,j : integer, e:elem , p:pi;
295       begin
296          p := qui;
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;
301                 czekaj := false;
302                 for i := x downto x-ch
303                 do
304                    call ek.line(7,i,posY+7,39,false);
305                    call tempo(100);
306  
307                 od;
308                 x := x-ch;
309                 ilosc_ak := ilosc_ak-ch;
310                 (* w magazynie zwolnilo sie miejsce i ktos moze wpisac *)
311  
312                 if not queue_pour_ecrire.empty
313                 then
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);
317                     resume(p);
318                  fi;
319             else (*jezeli counter=0 tzn. nic nie ma w magazynie *)
320 (*              writeln("M wpisuje pisarza",nr,"do kolejki czytelnikow");*)
321                  czekaj := true;
322                 (* qui := p;*) (* to jest instrukcja niepotrzebna *)
323                  call queue_pour_lire.into(p,nr);
324             fi;
325       end gett;
326  
327 begin  (*   tu sie zaczyna tresc monitora *)
328  
329       array buffer dim(1:20);
330
331      counter := 0;
332      x := 15; ilosc_ak := 0;
333      Qpos := posX;
334      queue_pour_lire := new queue(Qpos);
335      queue_pour_ecrire := new queue(Qpos+300);
336      call ek.magazyn(posX,posY);
337      
338      return;
339      do
340           accept putt, gett;
341            
342           if  ek.GUI_KeyPressed<>0 then call ek.fin fi;
343           if nb_proc = max_proc
344           then
345               call ek.outmessage(470,339,"DEADLOCK! press CR");
346               readln;
347               call ek.fin;
348            fi;
349      od;
350 end monitor;
351  
352  
353  (*  M A I N *)    
354
355 var    
356          M        : monitor, 
357          i, j, nbNodes,ile           : integer,
358          EK      : ecran, EKR    : arrayof ecran, 
359          PROC  : arrayof arrayof pi, p : pi,    
360         TABnodes, NbProc      : arrayof integer;
361  
362 begin  
363  
364      
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);
370    
371      ile := 0;
372      for  i := 1 to NbNodes 
373      do
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);
379       od;
380       
381       array EKR dim (1:NbNodes); 
382       for i := 1 to nbNodes 
383       do
384              if NbProc(i)>0 then  
385                   j := TABnodes(i);
386                   ek := new ecran(j);
387                   EKR(i) := ek;
388                   resume(ek)
389               fi;
390       od;
391      
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!!*) 
394
395      ek := EKR(1); 
396
397      M := new monitor(0,600,ile,ek);
398      resume(M);
399  
400
401      array PROC dim (1: nbNodes);
402      for i := 1 to nbNodes
403      do  
404           array PROC(i) dim (1 : NbProc(i));
405            ek := ekr(i);
406            for j := 1 to NbProc(i)
407            do            
408                 ile := TabNodes(i);
409                P := new pi(ile,j,M,ek);
410                Proc(i,j) := P;      
411            od
412          
413      od;
414         
415        ek := EKR(1); 
416        call  ek.outmessage(400,440,"press CR");
417        readln;
418        call  ek.outtext(400,440," press any key to STOP ");
419  
420         for i :=1 to NbNodes
421         do        
422             for j := 1 to NbProc(i) 
423             do  
424                  p := Proc(i,j);            
425                  resume(p);
426             od
427         od;
428  
429  
430 end processus4;
431 \0\0