Re: Very confused by Ada tasking, can not explain the execution outcome.



On Aug 30, 12:17 am, "jimmaureenrog...@xxxxxxxxxxxxxxxx"
<jimmaureenrog...@xxxxxxxxxxxxxxxx> wrote:
On Aug 29, 7:54 pm, climber....@xxxxxxxxx wrote:



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?

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 := 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 := True;
end Semaphore;
-- -------------------------------------
protected body Semaphore is
entry P when Value is
begin
Value:= False;
end P;

entry V when not Value is
begin
Value:= True;
end V;
end Semaphore;
-- -------------------------------------
R : array (Res_Index) of Semaphore;

-- -------------------------------------
task type User_Thread ;

task body User_Thread is

Rounds : Integer := 0;
Next,
I : Integer;
State : Integer := - 1;
D : Res_Index := 0;
Needs : Bool_Array := (Others => 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(Res_Index(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 not Needs(D) then
Put_Line("------> acquiring resource,no waiting <------");
Acquire_No_Wait;
end if;

if Next=1 and State=0 and Needs(D) then
Put_Line("------> acquire and waiting resource <------");
Acquire_Wait;
end if;

if Next=2 and State=0 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 not Needs(D) then
Put_Line(" >> acquiring resource,no waiting <------");
Acquire_No_Wait;
end if;

if Next=1 and State=0 and Needs(D) then
Put_Line(" >> acquire and waiting resource <------");
Acquire_Wait;
end if;

if Next=2 and State=0 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;

Jim Rogers

Thank you Jim for modifying the program and making it work. I saw how
you modify the guarding conditions for the procedures. In fact, the
conditions are fine by themselves, because i wrote the same program in
Java. However, the modified program is working now. It indeed reminds
me that Ada probably follows the 'strict evaluation' rule when it
comes to the boolean expressions, so in
if Next=1 and State=0 and D<N and Needs(D) then ...
Ada probably would evaluate all the predicates connect by logical
AND, but as soon as D=N is reached, array index for Needs(_) would go
out of bound (because Needs is defined to be array(0..N-1) of
boolean). I am just guessing here.

This would not cause exceptions in Java, because java follows the non-
strict evaluation rule.

tony
.



Relevant Pages

  • Very confused by Ada tasking, can not explain the execution outcome.
    ... I am trying to simulate a concurrent resource allocator with Ada's ... task and protected type. ... entry calls, so no entry is defined in tasks. ... loop, 'while rounds<2 loop', how could it get out of the loop if ...
    (comp.lang.ada)
  • Re: task-safe hash table?
    ... protected type p_type is ... entry awhen p_dummy = 0 is ... 1_000 loop ...
    (comp.lang.ada)
  • Re: [Pcihpd-discuss] Re: ACPI problem with PCI Express Native Hot-plug driver
    ... system has two hot-pluggable PCI Express slots). ... PCI bus 0x0 Resource structure 0. ... Resource Type: Bus Number Range ... pciehp_save_config: In do loop ...
    (Linux-Kernel)
  • RE: Creating a que
    ... and entry count in a collection. ... if eo.Count> 0 then bMoreData = True ... At the beginning of the loop you assume this is the last time through the ... Then you go through each item in the Entries ...
    (microsoft.public.excel.programming)
  • RE: Creating a que
    ... and entry count in a collection. ... if eo.Count> 0 then bMoreData = True ... At the beginning of the loop you assume this is the last time through the ... Then you go through each item in the Entries ...
    (microsoft.public.excel.programming)