comp.lang.ada
 help / color / mirror / Atom feed
* Very confused by Ada tasking, can not explain the execution outcome.
@ 2008-08-30  1:54 climber.cui
  2008-08-30  4:17 ` jimmaureenrogers
  2008-08-30  5:12 ` Jeffrey R. Carter
  0 siblings, 2 replies; 8+ messages in thread
From: climber.cui @ 2008-08-30  1:54 UTC (permalink / raw)


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<N and not needs(d) then
       Put_Line("------> acquiring resource,no waiting <------");
       acquire_no_wait;
    end if;

    if next=1 and state=0 and d<N and needs(d) then
       Put_Line("------> 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<N and not needs(d) then
        Put_Line("  >> acquiring resource,no waiting <------");
        acquire_no_wait;
      end if;

      if next=1 and state=0 and d<N and needs(d)  then
        Put_Line("  >> 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;



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2008-08-31 13:37 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-08-30  1:54 Very confused by Ada tasking, can not explain the execution outcome climber.cui
2008-08-30  4:17 ` jimmaureenrogers
2008-08-30  9:34   ` climber.cui
2008-08-30 10:59     ` Damien Carbonne
2008-08-31 13:37       ` Stephen Leake
2008-08-30  5:12 ` Jeffrey R. Carter
2008-08-30  9:42   ` climber.cui
2008-08-30 13:40     ` Georg Bauhaus

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox