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=-0.9 required=5.0 tests=BAYES_00,FORGED_GMAIL_RCVD, FREEMAIL_FROM autolearn=no autolearn_force=no version=3.4.4 X-Google-Thread: 103376,ebc5bf96039d7210,start X-Google-Attributes: gid103376,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news2.google.com!postnews.google.com!73g2000hsx.googlegroups.com!not-for-mail From: climber.cui@gmail.com Newsgroups: comp.lang.ada Subject: Very confused by Ada tasking, can not explain the execution outcome. Date: Fri, 29 Aug 2008 18:54:53 -0700 (PDT) Organization: http://groups.google.com Message-ID: NNTP-Posting-Host: 72.39.186.157 Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Trace: posting.google.com 1220061293 11209 127.0.0.1 (30 Aug 2008 01:54:53 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Sat, 30 Aug 2008 01:54:53 +0000 (UTC) Complaints-To: groups-abuse@google.com Injection-Info: 73g2000hsx.googlegroups.com; posting-host=72.39.186.157; posting-account=fnsQjAoAAACsmgRb2dWjnstJ3nliOcz6 User-Agent: G2/1.0 X-HTTP-UserAgent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.14) Gecko/20080410 SUSE/2.0.0.14-0.2.3 Firefox/2.0.0.14,gzip(gfe),gzip(gfe) Xref: g2news2.google.com comp.lang.ada:7558 Date: 2008-08-29T18:54:53-07:00 List-Id: Hi all, I am trying to simulate a concurrent resource allocator with Ada's task and protected type. The idea is simple: there are several resource available (total number is N=8), 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. 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. I am now only testing a single task for execution. However, the outcome is very confusing: - the last sentence of the task body, which is a put_line statement is never executed, but the task terminates. - 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. If 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?? why the program still terminates?? 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? Thanks a lot. The entire program (runnable) would be attached at the end of the message. tony -------------------------------------------------------- -------------------------------------------------- with Ada.Text_IO; with Ada.Numerics.Discrete_Random; use Ada.Text_IO; procedure multi_res_alloc_a is N: constant := 8; -- number of resources to share RD:constant := 2; -- number of rounds type BOOL_ARRAY is array(0..N-1) 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: INTEGER := 1; end Semaphore; -- ------------------------------------- protected body Semaphore is entry P when value>0 is begin value:= value-1; end P; entry V when value=0 is begin value:= value+1; end V; end Semaphore; -- ------------------------------------- r: array(0..N-1) of Semaphore; -- ------------------------------------- task type User_thread ; task body User_thread is rounds: INTEGER :=0 ; next, i, index : INTEGER; state: INTEGER :=-1 ; d : INTEGER :=0; needs: BOOL_ARRAY := (0..N-1 => FALSE); x: INTEGER :=0; c: INTEGER :=0; procedure acquire_no_wait is begin d:=d+1; end acquire_no_wait; procedure acquire_wait is begin r(d).P; d:=d+1; end acquire_wait; procedure use_res is begin state:=1; Put_Line("******* Eating now *******"); while d>0 loop d:=d-1; if needs(d) then r(d).V; end if; end loop; state:=-1; rounds:=rounds+1; end use_res; procedure want_res is begin c:=0; state:=0; Reset(G); -- start the generator in a unique state in each run while c<4 loop --random x x := Random(G); needs(x mod N):= TRUE; c:=c+1; end loop; end want_res; begin Put_Line("-->> Enter task body.."); Reset(G); -- reset the random number generator while rounds<2 loop next := Random(G) mod 4; -- number of actions per task = 4 Put_Line(" >> next =" & INTEGER'Image(next) & "; state =" & INTEGER'Image(state)); if next=0 and state=0 and d acquiring resource,no waiting <------"); acquire_no_wait; end if; if next=1 and state=0 and d acquire and waiting resource <------"); acquire_wait; end if; if next=2 and state=0 and d>N-1 then Put_Line("------> USING resource <------"); use_res; end if; if next=3 and state=-1 then Put_Line("------> Want resource(s) <------"); want_res; end if; --Put_Line(">> ****** rounds = " & INTEGER'Image(rounds) & "*******" ); next:= (next+1) mod 4; i:=0; Put_Line(" >>> next =" & INTEGER'Image(next) & "; state =" & INTEGER'Image(state)); while (i<3) and (rounds<2) loop if next=0 and state=0 and d> acquiring resource,no waiting <------"); acquire_no_wait; end if; if next=1 and state=0 and d> acquire and waiting resource <------"); acquire_wait; end if; if next=2 and state=0 and d>N-1 then Put_Line(" >> USING resource <------"); use_res; end if; if next=3 and state=-1 then Put_Line(" >> Want resource(s) <------"); want_res; end if; --Put_Line(">> ****** rounds = " & INTEGER'Image(rounds) & "*******" ); next:= (next+1) mod 4; Put_Line(" >>>> next =" & INTEGER'Image(next) & "; state =" & INTEGER'Image(state)); i:=i+1; end loop; Put_Line("..... rounds =" & INTEGER'Image(rounds) & "...." ); end loop; Put_Line("TASK EXITS :: rounds =" & INTEGER'Image(rounds) & "...." ); end User_thread; -- ------------------------------------- u1: User_thread; begin null; end multi_res_alloc_a;