tomiQrsd
tomiQrsd

Reputation: 119

Access two entries of one task at the same time by different tasks

I need to acces two different entries of one task by two different tasks. Looks like my knowledge about Ada is not enough to perform this, i also spent a lot of time searching for solution but with no effects. I tried using protected type as a manager but it didn't work. I would like my accessing tasks to increment the counter by 1 in each entry and then perform some more work in the first entry after counter reaches 2. My approach to this is something like that

  task mainTask is
      entry first(n : in Integer);
      entry second(n : in Integer);
  end mainTask;
  task body mainTask is
      counter : Integer := 0;
  begin
  loop
     accept first(n : in Integer) do
        loop
           counter := counter + 1;
           Put_Line("First one working");
           --loop and wait until counter is 2
           --perform rest of the code
           delay 1.0;
        end loop;
     end first;
     accept second(n : in Integer) do
        loop
           counter := counter + 1;
           Put_Line("Second one working");
           delay 1.0;
        end loop;
     end second;
  end loop;
end mainTask;

task firstTask;
task body firstTask is
begin
   mainTask.first(0);
end firstTask;

task secondTask;
task body secondTask is
begin
   mainTask.second(0);
end secondTask;

After running the firstTask is accesing the first entry and enters the infinite loop and the second one can't acces the second entry. I get it why it happens, but i can't think of something that might work. Maybe there is something like accept first(..) AND accept second(..). Thank you in advance!

Upvotes: 0

Views: 168

Answers (2)

Simon Wright
Simon Wright

Reputation: 25501

If you really want "a machine (task) that require two workers (workers is an array of tasks) tho push two different buttons at the same time so the machine will be able to do something”, as in your reply to my comment, you could consider being explicit about this in your code; something like

task body Main is
begin
   loop
      select
         accept First_Button_Pressed;
         select
            accept Second_Button_Pressed;
            Put_Line ("second pressed while first pressed");
         or
            accept First_Button_Released;
            Put_Line ("first released");
         or
            terminate;
         end select;
      or
         accept Second_Button_Pressed;
         select
            accept First_Button_Pressed;
            Put_Line ("first pressed while second pressed");
         or
            accept Second_Button_Released;
            Put_Line ("second released");
         or
            terminate;
         end select;
      or
         accept First_Button_Released;
         Put_Line ("first released");
      or
         accept Second_Button_Released;
         Put_Line ("second released");
      or
         terminate;
      end select;
   end loop;
end Main;

but clearly this isn’t going to be easy to maintain if you have to extend your code to handle a larger number of buttons!

Upvotes: 1

Dale Stanbrough
Dale Stanbrough

Reputation: 433

You need to have a select statement - that will allow any of the possibly open choices (first, second) to be chosen by a calling task. At the moment you have two infinite loops, so I'd be surprised if the 2nd accept ever happens.

so...

task multiple_entry is
    entry increment;
    entry decrement;
end multiple_entry;

task body multiple_entry is
    i : integer;
begin
    select
        accept increment;
        i := i + 1;
    or
        accept decrement do
            i := i - 1;
        end decrement
    or
        terminate;
    end select;
end;

is how it should be structured.

Upvotes: 0

Related Questions