Essentially Ada’s protected objects encapsulate data and operations, and the operations then have automatic mutual exclusion. Guards can also then be placed on these operations for condition synchronization.
They used to be called protected records because the data is like a record structure.
You have protected procedures and protected entries and protected functions. What’s the difference?
- Function for just reading data.
- If you don’t need any conditions satisfied apart from mutual exclusion use a procedure.
- Otherwise use an entry.
The example he gave was a bounded buffer, where he needed to use entries for
put because it needed to make sure the buffer was not empty/full respectively.
Entries are declared similarly to a procedure, except the start of it looks like:
entry Get (Item : out Data_Item) when Num /= 0 is
Looks a bit like Erlang guards really. Note that the barrier/guard is evaluated under mutual exclusion as well.
Calling a protected object is how you would expect. Something like:
Which will now block indefinitely until you can put that data. Wow, this is exactly what the
Chute package uses for
Get_Ball(). So this is interesting:
If you want a timeout, you can use a
select My_Buffer.Put(Some_Data); or delay 10.0; -- do something else end select;
You can also use
else instead of
or delay x which is essentially like
or delay 0.
There is a
'Count attribute for Entries which maintains the number of tasks queued on the entry.
There are a couple of different examples in the slides of using all this:
- Resource Control
- Broadcast (broadcast to everyone queued on an entry, uses ‘Count)
Private Entries and Entry Families
Tasks can have private entries; entries that can’t be called from the outside. The Ada ‘requeue’ operation uses them, but we wont deal with that yet.
A family of entries is a way of declaring an array of entries with simple declarations. Sounds a bit odd. The example given was a multicast system (as opposed to the broadcast example) where you have different groups and an array of
Booleans that are used as guards. The body of the example is in the slides and isn’t too complicated.
What can’t protected objects do?
- The reason most people tend not to allow functions to be executed in parallel (apparently) is because protected objects are usually used to pass data around; and so code should be as short as possible. Therefore there’s no real need to have functions run in parallel.
- The Ada Runtime environment thing disallows blocking operations inside protected objects to encourage you to write code as short as possible. It can detect this at compile time or run time;
Program_Error. So for example you can’t use a delay statement, or task creation or activation or a select statement or an accept statement. That kind of thing.
- A call to an external protected procedure/function is not considered potentially blocking. Apparently there’s some reason for this, but he said we’d find out another time.
The Readers and Writers Problem, again
You may think that because Ada allows parallel reads that the Readers and Writers problem is simple because the runtime system can take care of it. However:
- The reading and writing may require you to access the disk which will block you, and you’re not allowed to do that in a protected object.
- Even if there isn’t, you can’t control the order of the read and writes.
Therefore you have to use the same theory we used with standard monitors last time, which is to define an access control protocol for the read and write operations rather than encapsulate them in the protected object.
Full code detail is in the slides. The implementation basically uses a protected object only for
Control, which is essentially a high level way of obtaining and releasing read/write locks by using commands like
Protected Objects, good or bad?
- They are elegant
- They are efficient
- They aren’t object oriented
- Ada’s protected objects give structured mutual exclusion and high-level synchronization using barriers (guard clauses).
- Protected procedures have read/write lock.
- Protected functions have read lock.
- Protected entries have read/write lock and can have conditions (barriers) associated with them.
You should (exam?) be able to compare these with Java synchronized methods.