Rationale for Ada 2012

John Barnes
Contents   Index   References   Search   Previous   Next 

5.5 Volatile

This is a curious topic and created much debate. For the collector of statistics the real part of the AI is less than two pages but the appendix has nearly twenty pages of chatter!
The problem is all about sharing variables and ensuring that things happen in the correct order. Moreover, we need to avoid the overhead of protected objects particularly on microprocessors where we might be using low level features such as synchronous barriers discussed in section 5.2 above.
Suppose we have two tasks A and B which access some shared data perhaps in a nice package Common thus
package Common is
   ...
   Data: Integer;
   pragma Volatile(Data);
   Flag: Boolean;
   pragma Volatile(Flag);
   ...
end Common;
and in task A we write
with Common; use Common;
task A is
   ...
   Data := 42;
   Flag := True;
   ...
end A;
whereas in task B we have
with Common; use Common;
task B is
   Copy: Integer;
begin
   ...
   loop
      exit when Flag;  -- spin
   end loop;
   Copy := Data;
   ...
end B;
The idea is that task A assigns some value to Data and then indicates this to task B by setting Flag to true. Meanwhile, task B loops checking Flag and when it is found to be true, then reads the Data.
Does this work in Ada 2005? Hmm. Nearly. There are three things that need to be ensured. One is that Flag gets changed in one lump. Another is that the new value of Data assigned by task A truly is updated when task B reads it. And the third is that the actions happen sequentially. Well, we should have applied pragma Atomic to Flag to ensure the first but since it is of type Boolean we might get away with it. And note that Atomic implies Volatile anyway. Also Atomic ensures that the actions are sequential.
So, with the pragma Volatile changed to Atomic for Flag, it does indeed work in Ada 2005 because Volatile ensures that read and writes are to memory and so things do happen in the correct order. However, this is overkill. It is not necessary that all accesses are to memory; all that matters is that they happen in the correct order so they could be to some intermediate cache. Indeed, there might be nested caches and as hardware evolves it is becoming more difficult to make general statements about its structure; hence we can really only make statements about the effect.
The possibility of introducing a new pragma Coherent was debated for some time. However, it was ultimately concluded that the definition of Volatile should be weakened. In Ada 2005 it says
For a volatile object all reads and updates of the object as a whole are performed directly to memory. 
In Ada 2012 it says
All tasks of the program (on all processors) that read or write volatile variables see the same order of updates to the variables. 
Of course, in Ada 2012, we use aspects so the package Common becomes
package Common is
   ...
   Data: Integer
      with Volatile;
   Flag: Boolean
      with Atomic;   -- Atomic implies Volatile
   ...
end Common;
where we have given Atomic for Flag. As mentioned above, Atomic implies Volatile so it is not necessary to give both. However, if we do have to give two aspects, it is much neater that the one aspect specification does this whereas two distinct pragmas would be necessary.
It is said that this change brings the meaning of volatile into line with that in C. However, it has also been said that the definition of volatile in C is unclear.

Contents   Index   References   Search   Previous   Next 
© 2011, 2012, 2013 John Barnes Informatics.
Sponsored in part by:
The Ada Resource Association:

    ARA
  AdaCore:


    AdaCore
and   Ada-Europe:

Ada-Europe