8

I am a newbie in Ada programming language and I am working on concurrent programming, but I am having a problem with one implementation. This might be very dummy question. The code is:

type status is array(1..6) of boolean; --boolean values for each track
track_available :status:=(others=>true); --true if track is available
protected track_handler is

entry track_req(n:in track_part_type); --n is track number
entry track_rel(n:in track_part_type); --n is track number

end track_handler;


protected body track_handler is
--implement entries
entry track_req(n: in track_part_type) when track_available(n) is --here where the error occurs
    begin
        req(n);
    end track_req;

entry track_rel(n: in track_part_type) when track_available(n) is
    begin
        rel(n);
    end track_rel;
end track_handler;

    procedure req(nr : track_part_type) is
    begin
        --null;
        track_available(nr):=false;
    end req;

    procedure rel(nr : track_part_type) is
    begin
        --null;
        track_available(nr):=true;
    end rel;

Here I get a compilation error for "when track_available(n)" statement saying that "n is undefined". I think variable n is out of scope, but I also need to check if the n'th index of the array is true or false. How can I overcome this problem?

Thank you.

Shark8
  • 4,095
  • 1
  • 17
  • 31
Ahmet Keskin
  • 1,025
  • 1
  • 15
  • 25
  • **Great** question BTW! It has been years since someone asked me a question that chased me back into Cohen's Ada as a Second Language – T.E.D. Jan 31 '11 at 16:06
  • Real-time systems @ Chalmers? :D – André Laszlo Feb 23 '11 at 23:22
  • @André Laszlo: Yes, I did not have any time to write an example code. So I posted it actual one :) – Ahmet Keskin Mar 02 '11 at 14:22
  • Here's a reference to a section about entry families in the course book: Burns, A., Wellings, A. (2009). *Real-Time Systems and Programming Languages*. 4th ed. Harlow, Essex, England: Pearson Education Limited. p197. – André Laszlo Mar 02 '11 at 22:50

2 Answers2

7

You can't actually use an entry's parameters in its own guard. You got that much, I gather.

The way guards work, all of them are evaluated before the wait starts, and only the ones that are active at that time will be available. They don't get periodicly re-evaluated or dynamicaly read or anything.

This means it will be tough to get the logic for your guards right, unless you write your code so that only other entries in your protected object modify the guards. If you want to use some data from outside of your protected object to control its behavior, you will probably need to use some mechanisim other than guards to do it. Like check just inside the entry and exit immediately or something.

There is one possibility for what you are trying to do though: Entry families. You should be able to use an entry family index in a guard.

The spec would change to:

entry track_req(track_part_type); 
entry track_rel(track_part_type); 

And the body would change to

entry track_req(for n in track_part_type) when track_available(n) is 
    begin
        req(n);
    end track_req;

entry track_rel(for n in track_part_type) when track_available(n) is
    begin
        rel(n);
    end track_rel;
end track_handler;
T.E.D.
  • 44,016
  • 10
  • 73
  • 134
  • Thanks for the answer. As I understand the above code goes through all tracks and if one or more is available, it makes a request[req(n)/rel(n)] for that particular track number. Is that correct? – Ahmet Keskin Jan 31 '11 at 16:27
  • 1
    @Ahmet Keskin - Think of it as saying "I have one of these entries for each value of `track_part_type`, but only the ones for which `track_avilable()` is true will be available this time around". – T.E.D. Jan 31 '11 at 17:57
  • Actually, that is a very good tip. But that is not exactly what I want to do. Imagine that there is another task randomly making request for different track numbers. In your implementation, the entry will make request for every track number which are available while the task only wants request for a particular track number.I guess the entry families are what I am looking for. – Ahmet Keskin Jan 31 '11 at 21:57
  • @Ahmet Keskin - One of the two of us is confused, I think. Entries aren't an active thing. They are just "entry points" into the protected object. They don't do anything unless some other code attempts to call them. So no requests are being made above, just made available to others. – T.E.D. Jan 31 '11 at 22:55
  • Yes, I know. What I meant was when the entry was called by an other code, the entry calls req() or rel() procedures. I just realized that I did not make it clear in above comment. – Ahmet Keskin Jan 31 '11 at 23:32
1

In the code below you are trying to use track_available(n), before it has been fully defined by (n: in track_part_type).

entry track_req(n: in track_part_type) when track_available(n) is 

See also http://en.wikibooks.org/wiki/Ada_Programming/Tasking#Protected_types

NWS

NWS
  • 3,080
  • 1
  • 19
  • 34