Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ada TASKING_ERROR

Assume the following situation: There is a box, which is used to store coins People take money from the box People put money into the box i have take task entry as Add, Subtract, Read and Write. below is my code .now i am confused how to call entry add ,subtract and read to achieve above requirement please help

with Ada.Text_IO,ada.integer_text_io;
use ada.text_io,ada.integer_text_io;

procedure protected_imp is
   task type box(initial_value:integer;min_value:integer;max_value:integer) is
      entry add(number:integer); 
      entry subtract(number:integer);
      entry read;
   end box;
   task body box is 
      x:integer:=initial_value; --shared variable
   begin
      loop                  --why raised TASKING_ERROR when loop is removed?
         select
            when x<max_value=>
               accept add(number:integer)do
                  x:=x+number;
               end add;
         or  
            when x>min_value=>
               accept subtract(number:integer) do
                  x:=x-number;
               end subtract;
         or
            accept read do
               put("coins");
               put_line(integer'image(x));
            end read;
         or
            delay(5.0);
            put("no request received for 5 seconds");
         end select;
      end loop;
   end box;
   go:box(1,0,10);
begin ----- how to call? and why  i am getting "no request received for 5 seconds " even i have activate go .add(1) ?
   for i in 1..5 loop
      go.add(1);
   end loop;
   go.read;
end protected_imp;
like image 261
pravu pp Avatar asked Nov 01 '22 10:11

pravu pp


1 Answers

Here, your program produces the output

$ ./protected_imp 
coins 6
no request received for 5 secondsno request received for 5 secondsno request received for 5 seconds^C

(I stopped it at that point).

“coins 6” is exactly the output it should give; you’ve added 1 to the starting value (1) 5 times.

The reason you get Tasking_Error if you remove the loop is that then the task executes the select statement once; after it accepts the go.add call it exits the select and drops out of the bottom of the task, so that the next go.add call has nowhere to go because there is no task any more.

The sequence of events is

task arrives at select; all the alternatives are closed
main calls go.add (1)'
task accepts the entry, increments x, exits the select, and goes round the loop again to wait at the select
main calls go.add (1)
task accepts the entry, increments x, exits the select, and goes round the loop again to wait at the select
main calls go.add (1)
task accepts the entry, increments x, exits the select, and goes round the loop again to wait at the select
main calls go.add (1)
task accepts the entry, increments x, exits the select, and goes round the loop again to wait at the select
main calls go.add (1)
task accepts the entry, increments x, exits the select, and goes round the loop again to wait at the select
main calls go.read
task accepts the entry, prints out “coins 6”, and goes round the loop again to wait at the select
main finishes and waits until the task terminates, which it doesn’t, because
after 5 seconds, the select’s delay alternative opens, so the task takes it, prints the message (it should really use Put_Line) and goes round the loop again to wait at the select
after 5 seconds, the select’s delay alternative opens, so the task takes it, prints the message and goes round the loop again to wait at the select
...
like image 119
Simon Wright Avatar answered Nov 11 '22 06:11

Simon Wright