with Text_io; use Text_io; procedure SIEVE is -- C A R Hoare's Prime Number Sieve - using Tasks package IIO is new Text_IO.Integer_io(integer); --need integer output task type PRIMES is entry Get(ID:positive; NUMBER:positive);-- ID identifes which prime entry STOP; end PRIMES; type APRIMES is access PRIMES; ANSWER:string(1..1); P2:PRIMES; package STATUS is -- for output of status reports procedure PUT_PRIME(ID:positive; ITEM:positive); procedure PUT_NUMBER(ID:positive; ITEM:positive); procedure CLEAR(ID:positive); end STATUS; package body STATUS is separate; procedure MAKE_PRIME(N:in out APRIMES) is begin if N=null then N:=new PRIMES; end if; end; procedure DBG(S:string) is begin Put("Debug: "); Put_line(S); end DBG; procedure DBG(N:positive) is begin Put("Debug: "); IIO.Put(N); New_line; end DBG; procedure DBG(S:string; N:positive) is begin Put("Debug: " & S); IIO.Put(N); New_line; end DBG; procedure DBG(S:string; P,N:positive) is begin Put("Debug: " & S); IIO.Put(P);Put(":");IIO.Put(N); New_line; end DBG; task body PRIMES is separate; begin for N in 2..67 loop --DBG("MAIN n= ",N); P2.Get(ID=>1, NUMBER=>N); end loop; DBG("MAIN STOP"); P2.STOP; end SIEVE; ------------------------------------------------- separate(SIEVE) package body STATUS is -- for output of status reports type COMPONENT is ( P, N); S:array(COMPONENT)of STRING(1..79):=(P..N=>(1..79=>' ')); -- Task with ID=I only accesses its own 4 chars on a line procedure PUT_STATUS(WHICH:COMPONENT; ID:positive; ITEM:positive) is begin iio.Put(TO=>S(WHICH)(4*ID-3..4*ID), ITEM=>ITEM); Put_line(S(WHICH)); end PUT_STATUS; procedure PUT_NUMBER(ID:positive; ITEM:positive) is begin PUT_STATUS(N,ID,ITEM); end; procedure PUT_PRIME(ID:positive; ITEM:positive) is begin PUT_STATUS(P,ID,ITEM); end; procedure CLEAR(ID:positive) is begin S(N)(4*ID-3..4*ID):=" "; end CLEAR; end STATUS; -------------------------------------------- separate(SIEVE) task body PRIMES is P:positive; -- This task's PRIME NUMBER. I:positive; -- Prime Number (I). N:positive; DONE:boolean; NEXT:APRIMES; begin --DBG("P"); accept Get(ID:positive; NUMBER:positive) do P:=NUMBER; I:=ID; IIO.Put(I);Put("th Prime is ");IIO.Put(P);New_line; STATUS.PUT_PRIME(I,P); end Get; loop select accept Get(ID:positive; NUMBER:positive) do N:=NUMBER; DONE:=false; STATUS.PUT_NUMBER(I, N); end Get; or accept STOP do DONE:=true; end STOP; end select; --DBG("P",N); exit when DONE; MAKE_PRIME(NEXT); --DBG("P",P,N); delay 0.5*I; STATUS.CLEAR(I); if N mod P /= 0 then NEXT.Get(ID=>I+1, NUMBER=>N); end if; end loop; --DBG("end loop in P",P); NEXT.STOP; --DBG ("end of P",P); end;