From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, T_FILL_THIS_FORM_SHORT autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,ebc5bf96039d7210 X-Google-Attributes: gid103376,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII Path: g2news1.google.com!postnews.google.com!b30g2000prf.googlegroups.com!not-for-mail From: "jimmaureenrogers@worldnet.att.net" Newsgroups: comp.lang.ada Subject: Re: Very confused by Ada tasking, can not explain the execution outcome. Date: Fri, 29 Aug 2008 21:17:26 -0700 (PDT) Organization: http://groups.google.com Message-ID: <023de8e6-ce28-4a97-8103-ff855289a795@b30g2000prf.googlegroups.com> References: NNTP-Posting-Host: 75.70.240.233 Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-Trace: posting.google.com 1220069846 1282 127.0.0.1 (30 Aug 2008 04:17:26 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Sat, 30 Aug 2008 04:17:26 +0000 (UTC) Complaints-To: groups-abuse@google.com Injection-Info: b30g2000prf.googlegroups.com; posting-host=75.70.240.233; posting-account=fZH-XgkAAADP-Rf8L8ppyFIdKUfh90k4 User-Agent: G2/1.0 X-HTTP-UserAgent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1,gzip(gfe),gzip(gfe) Xref: g2news1.google.com comp.lang.ada:1831 Date: 2008-08-29T21:17:26-07:00 List-Id: On Aug 29, 7:54=A0pm, climber....@gmail.com wrote: > Hi all, > =A0 I am trying to simulate a concurrent resource allocator with Ada's > task and protected type. > =A0 The idea is simple: there are several resource available (total > number is N=3D8), shared by user_thread. Each user first randomly > generate 4 numbers ranged between 0 and 7, which would represent the > resource needed to access. The resources therefore are implemented by > semaphores, which in turn implemented by protected objects. > =A0 The user_thread is not going to interact with each other by making > entry calls, so no entry is defined in tasks. The task representing > the user_thread simply select a procedure defined in the task body non- > deterministically, until the counter, 'rounds' reached its limit. =A0I > am now only testing a single task for execution. However, the outcome > is very confusing: > =A0 - the last sentence of the task body, which is a put_line statement > is never executed, but the task terminates. > =A0- also, the per task counter 'rounds', was never incremented, it > stays the same as the initial value. The only procedure increment > 'rounds' is procedure 'use_res', but the procedure was never called > during the execution. =A0If you notice the entry condition for the while > loop, 'while rounds<2 loop', how could it get out of the loop if > 'rounds' was never incremented?? =A0why the program still terminates?? > =A0 I am stuck on this issue. Although i am not new to programming, I do > not know Ada very well. Could someone help me out here? The program runs fine with a few modifications to your conditions. Note that I changed the index to a modular type. This eliminates any need to check for out of bounds indexing due to your arithmetic. Modular arithmetic wraps to values within the type definition. Your program contains two unused variables: Rd and Index. You should clean up the unused clutter. Your original version never incremented Rounds because the conditions for Use_Res were never satisfied. with Ada.Text_Io; with Ada.Numerics.Discrete_Random; use Ada.Text_Io; procedure Multi_Res_Alloc_A is N : constant :=3D 8; -- number of resources to share type Res_Index is mod N; type Bool_Array is array (Res_Index) of Boolean; subtype N_Res is Integer range 0..99; package Random_Int is new Ada.Numerics.Discrete_Random (N_Res); use Random_Int; G : Generator; -- ------------------------------------- protected type Semaphore is entry P; entry V; private Value : Boolean :=3D True; end Semaphore; -- ------------------------------------- protected body Semaphore is entry P when Value is begin Value:=3D False; end P; entry V when not Value is begin Value:=3D True; end V; end Semaphore; -- ------------------------------------- R : array (Res_Index) of Semaphore; -- ------------------------------------- task type User_Thread ; task body User_Thread is Rounds : Integer :=3D 0; Next, I : Integer; State : Integer :=3D - 1; D : Res_Index :=3D 0; Needs : Bool_Array :=3D (Others =3D> False); X : Integer :=3D 0; C : Integer :=3D 0; procedure Acquire_No_Wait is begin D:=3DD+1; end Acquire_No_Wait; procedure Acquire_Wait is begin R(D).P; D:=3DD+1; end Acquire_Wait; procedure Use_Res is begin State:=3D1; Put_Line("******* Eating now *******"); while D>0 loop D:=3DD-1; if Needs(D) then R(D).V; end if; end loop; State:=3D-1; Rounds:=3DRounds+1; end Use_Res; procedure Want_Res is begin C:=3D0; State:=3D0; Reset(G); -- start the generator in a unique state in each run while C<4 loop --random x X :=3D Random(G); Needs(Res_Index(X mod N)):=3D True; C:=3DC+1; end loop; end Want_Res; begin Put_Line("-->> Enter task body.."); Reset(G); -- reset the random number generator while Rounds<2 loop Next :=3D Random(G) mod 4; -- number of actions per task =3D 4 Put_Line(" >> next =3D" & Integer'Image(Next) & "; state =3D" & Integer'Image(State)); if Next=3D0 and State=3D0 and not Needs(D) then Put_Line("------> acquiring resource,no waiting <------"); Acquire_No_Wait; end if; if Next=3D1 and State=3D0 and Needs(D) then Put_Line("------> acquire and waiting resource <------"); Acquire_Wait; end if; if Next=3D2 and State=3D0 then Put_Line("------> USING resource <------"); Use_Res; end if; if Next=3D3 and State=3D-1 then Put_Line("------> Want resource(s) <------"); Want_Res; end if; --Put_Line(">> ****** rounds =3D " & INTEGER'Image(rounds) & "*******" ); Next:=3D (Next+1) mod 4; I:=3D0; Put_Line(" >>> next =3D" & Integer'Image(Next) & "; state =3D" & Integer'Image(State)); while (I<3) and (Rounds<2) loop if Next=3D0 and State=3D0 and not Needs(D) then Put_Line(" >> acquiring resource,no waiting <------"); Acquire_No_Wait; end if; if Next=3D1 and State=3D0 and Needs(D) then Put_Line(" >> acquire and waiting resource <------"); Acquire_Wait; end if; if Next=3D2 and State=3D0 then Put_Line(" >> USING resource <------"); Use_Res; end if; if Next=3D3 and State=3D-1 then Put_Line(" >> Want resource(s) <------"); Want_Res; end if; --Put_Line(">> ****** rounds =3D " & INTEGER'Image(rounds) & "*******" ); Next:=3D (Next+1) mod 4; Put_Line(" >>>> next =3D" & Integer'Image(Next) & "; state =3D" & Integer'Image(State)); I:=3DI+1; end loop; Put_Line("..... rounds =3D" & Integer'Image(Rounds) & "...." ); end loop; Put_Line("TASK EXITS :: rounds =3D" & Integer'Image(Rounds) & "...." ); end User_Thread; -- ------------------------------------- U1 : User_Thread; begin null; end Multi_Res_Alloc_A; Jim Rogers