Question

I'm trying to understand how the R-V in ADA works:

server (pseudo)code:

task test is
  entry put (num: in integer);
  entry get (num: out integer);
end test;

task body test is
  local_num: integer;
begin
  accept put (num: in integer) do
    local_num := num;
  end put;

  // some next processing of local_num, eg:
  local_num := local_num * 2;

  accept get (num: out integer) do
    num := local_num;
  end get;
end test;

and the client a server are communicating as following:

client (a)    | server (b)
================================
              |   // sleep
(call_entry)  |   // sleep
a.put(num)    |   // sleep
  // sleep    | (accept_entry)
  // sleep    | b.accept put(num)
  // sleep    | local_num := num;
  // sleep    | local_num := local_num * 2;
              |   ???   <--------------------- what is happening after that point?
(call_entry)  |   // sleep
a.get(num)    |   // sleep
  // sleep    | (accept_entry)
  // sleep    | b.accept get(num)
  • Is it correct?
  • Can you describe me how it continues?
  • Who awakes the client to get the result? How the client know, that it can get the result?

update: (correct process?)

client        | server (test)
================================
test.put(num) |   // sleep      ----------> call entry
test.get(A)   | accept put(num) ----------> accept entry PUT (call entry GET to the QUEUE)
  // sleep    | local_num := num;
  // sleep    | local_num := local_num * 2;
test.get(A)   | accept get(A)   ----------> accept entry (removed from the QUEUE)
              |   // sleep
Was it helpful?

Solution

Ada Rendez-Vous are really simple, in fact you have a task test with 2 entries get and put. Once you run the program, the test task is started, so the local_num value is created (with no defined initial value) and the body is executed BUT the first statement is an accept so the task is waiting for an entry call.

procedure ... is

    task test is 
       ...
    end test ;

    task body test is
       ...
    end test ;

    A : Integer ;

begin
    -- 1. The 'test' task is started here, waiting for a call to `put`
    -- 2. You call the 'put' entry, which mean that the current task (the main task) 
    --    is stopped until the end of the entry call.
    test.put(33) ;
    -- 3. Here the entry 'put' is finished, so the 2 tasks are executing
    --    simultaneously
    -- 4. Here we call the 'get' entry, there is a non predictive behaviour: 
    --    We do not know if the instruction local_num := local_num * 2; has
    --    been executed or not, so 2 case:
    --     - The instruction has been executed, so the 'test' task is waiting
    --       and directly accept the 'get' entry, while the main task wait
    --     - The instruction has not been executed, so the main 'task' wait
    --       until there is someone to accept is call
    --    What you're sure is that the entry 'get' won't be executed before
    --    the instruction, and that someone calling 'get' will have to wait
    --    until the 'test' task get to the 'accept get' instruction.
    test.get(A) ;
    -- 5. Here, the 'get' entry is finished, so you're sure that you have ended
    --    the 'test' task

end ... ;

In fact, when you call a entry like test.get, you loose the control until the test.get entry has been fully executed. If there is no task waiting for this entry, you will wait until a task request this entry.

procedure BadTask is

    -- Stupid task that will accept a 'put' entry and then a 'get' (only once)
    task T is
        entry get (A : out Integer);
        entry put (A : in Integer);
    end T ;

    task body T is
        LocalInteger : Integer := 0 ;
    begin
        accept put (A : in Integer) do
            LocalInteger := A ;
        end put ;
        accept get (A : ouInteger) do
            A := LocalInteger ;
        end get ;
    end T ;

    A : Integer ;
begin
    -- Here T is waiting for 'put'
    T.get (A) ; 
    -- You will never get here and your program is blocked because the two tasks
    -- are waiting but no one can't get the control.
end BadTask ;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top