comp.lang.ada
 help / color / mirror / Atom feed
* for X'Address use - and Volatile
@ 2016-08-31 13:01 Maciej Sobczak
  2016-08-31 14:00 ` AdaMagica
  2016-08-31 19:36 ` Randy Brukardt
  0 siblings, 2 replies; 8+ messages in thread
From: Maciej Sobczak @ 2016-08-31 13:01 UTC (permalink / raw)


Hi,

Consider:

X : Integer;
Y : Integer;
for Y'Address use X'Address;

The above is a simple overlay, typically used for under-the-table type conversions.

AARM 13.3 says:

"If the Address of an object is specified [...], then the implementation should not perform optimizations based on assumptions of no aliases."

Interestingly, in the above example there are two objects involved in the overlay, yet only one (Y) is affected by this rule (becaue Address is *specified* only for Y, not for X). Let's assume that this is an omission and that the intent is that both object (X and Y) should be excluded from such optimizations, otherwise it will not work.

The question is - do we need pragma Volatile on these objects as well?

C.6 (16c/3):
"If for a shared variable X, a read of X occurs sequentially after an update of X, then the read will return the updated value if X is volatile or atomic, but may or or may not return the updated value if X is nonvolatile."

My understanding is that Volatile is *not* needed to ensure proper working of this overlay, even though C.6 seems to imply otherwise. My feeling is that C.6 focuses on data sharing between tasks only and in the case of overlays, the lack of non-aliasing optimizations is enough.

The question comes from analyzing of the code which contains such an overlay together with pragma Volatile. This is a single-tasking program.
My feeling is that Volatile is superfluous - unless there are other reasons for it, for example related to I/O register mapping, etc.

-- 
Maciej Sobczak * http://www.inspirel.com


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: for X'Address use - and Volatile
  2016-08-31 13:01 for X'Address use - and Volatile Maciej Sobczak
@ 2016-08-31 14:00 ` AdaMagica
  2016-08-31 19:36 ` Randy Brukardt
  1 sibling, 0 replies; 8+ messages in thread
From: AdaMagica @ 2016-08-31 14:00 UTC (permalink / raw)


If you declare a task, there are always two tasks: your declared one and the environment task (your main subprogram). Shared variables if not volatile are guaranteed to be updated only at task synchronization points.
Thus, volatile is not superfluous.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: for X'Address use - and Volatile
  2016-08-31 13:01 for X'Address use - and Volatile Maciej Sobczak
  2016-08-31 14:00 ` AdaMagica
@ 2016-08-31 19:36 ` Randy Brukardt
  2016-08-31 22:17   ` Maciej Sobczak
  2016-09-01  8:12   ` J-P. Rosen
  1 sibling, 2 replies; 8+ messages in thread
From: Randy Brukardt @ 2016-08-31 19:36 UTC (permalink / raw)


"Maciej Sobczak" <see.my.homepage@gmail.com> wrote in message 
news:7595494c-3398-4fd9-ab4b-80a79383ae33@googlegroups.com...
Hi,

>Consider:

>X : Integer;
>Y : Integer;
>for Y'Address use X'Address;
>
>The above is a simple overlay, typically used for under-the-table type 
>conversions.

Ada does not now, nor ever has, officially supported overlays. Such code 
might work on a particular implementation, but it's not portable (even to 
another version of the same compiler).

Indeed, address clauses ought to be avoided for all but their intended 
purpose (mapping to hardware registers); for other purposes, better 
solutions exist (Unchecked_Conversion, Address_to_Access_Conversions, etc.)

In addition, since you didn't declare these objects aliased, the compiler is 
allowed to optimize them completely away.

>AARM 13.3 says:
>
>"If the Address of an object is specified [...], then the implementation 
>should not perform optimizations based on >assumptions of no aliases."
>
>Interestingly, in the above example there are two objects involved in the 
>overlay, yet only one (Y)
>is affected by this rule (becaue Address is *specified* only for Y, not for 
>X). Let's assume that
>this is an omission

It's not. You ignored the important rule, 13.3(13/3):

If an Address is specified, it is the programmer's responsibility to ensure 
that the address is valid and appropriate for the entity and its use; 
otherwise, program execution is erroneous.

The associated AARM note says that "Appropriate for the entity and its use" 
covers cases like "addresses which would force objects that are supposed to 
be independently addressable to not be". Since X and Y are independently 
addressable and there is no way to avoid that, this case *always* will cause 
erroneous execution. Compilers (obviously) don't have to protect against 
that, so any optimization on X is allowed.

Indeed, since X isn't aliased, it's not even required that X'Address is 
meaningful (it could be in a machine register).

These things *might* work on a particular implementation, but no guarantees.

The correct way to do this is something like:

    package A2A is new System.Address_to_Access_Conversions (Integer);
    X : aliased Integer;
    Y : A2A.Object_Pointer := A2A.To_Pointer (X'Addresss);

or better still, avoid Address altogther:

   type Acc_Int is access all Integer;
   X : aliased Integer;
   Y : Acc_Int := X'Access; -- Or 'Unchecked_Access if accessibility is an 
issue.

(You need the former if the types are different, the latter if not. But Ada 
doesn't really allow the case with the types being different to be portable 
in any case - Unchecked_Conversion is needed, and even that isn't certain to 
be portable depending on the types involved.)

                                          Randy.

P.S. Yes, you hit two of my pet peeves about the way some people use Ada. 
Most compilers (but not Janus/Ada 95) try to support the overlay case 
because it was common in Ada 83 code -- both of the better alternatives 
didn't exist until Ada 95. Similarly with the use of Aliased on any 
stand-alone object that you're planning to take the 'Address of.

Trying to support these things makes Ada optimization many times more 
complex and substantially less effective than it otherwise could be. I 
suppose GNAT gets away with it since C has these issues many times worse and 
thus there already is support for that in the GCC backend. People not using 
a C backend have no such (dis?)advantage. Grrrrr.



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: for X'Address use - and Volatile
  2016-08-31 19:36 ` Randy Brukardt
@ 2016-08-31 22:17   ` Maciej Sobczak
  2016-09-01  1:22     ` Randy Brukardt
  2016-09-01  5:41     ` Simon Wright
  2016-09-01  8:12   ` J-P. Rosen
  1 sibling, 2 replies; 8+ messages in thread
From: Maciej Sobczak @ 2016-08-31 22:17 UTC (permalink / raw)



> Ada does not now, nor ever has, officially supported overlays. Such code 
> might work on a particular implementation, but it's not portable (even to 
> another version of the same compiler).
[...]

Thanks for the explanation, which hits some interesting point.

It is true that such code goes outside of the standard and relies on the programmer's knowledge about some particular implementation. This is similar in nature to many obscure hacks in C, too. It might work, because we *know* that it does - perhaps we have even verified it by whatever means. But once we rely on the details of some particular implementation, it does not make much sense to ask whether something is superfluous or not from the standard's perspective - we are already outside of the standard, so standard is no longer an authority. Oops. :-)

> Indeed, address clauses ought to be avoided for all but their intended 
> purpose (mapping to hardware registers);

I'd disagree here. Mapping to hardware registers (or mapping to memory regions in general) should be performed at the linker and loader level, which have much better tools for handling such tasks (also, at that level, there might be other languages involved, which really means that a common denominator is needed instead of pseudo-high-level solutions). I understand that standard authors did not presume the existence of the linker as a separate entity and therefore tried to solve everything in the language, but the whole idea of "mapping to hardware registers" is already target-specific and cannot be addressed (pun intended) in abstract terms, which is how the language is defined in the standard. In other words, for hardware registers I would use a pragma Imported objects and allocate them in the linker script instead. So, as far as I'm concerned, the whole "for X'Address use" idiom is useless. And last by not least - I don't like to tie the source code to the hardware this way.

But I have a code that resembles a pile of C hacks and now the only thing that leads me in its analysis is "if it works then it's good", because the standard was already thrown out the window. Sigh.

-- 
Maciej Sobczak * http://www.inspirel.com

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: for X'Address use - and Volatile
  2016-08-31 22:17   ` Maciej Sobczak
@ 2016-09-01  1:22     ` Randy Brukardt
  2016-09-01  5:41     ` Simon Wright
  1 sibling, 0 replies; 8+ messages in thread
From: Randy Brukardt @ 2016-09-01  1:22 UTC (permalink / raw)


"Maciej Sobczak" <see.my.homepage@gmail.com> wrote in message 
news:315a724f-0b77-47fd-9448-369e4670fc99@googlegroups.com...

...
>> Indeed, address clauses ought to be avoided for all but their intended
>> purpose (mapping to hardware registers);
>
>I'd disagree here. Mapping to hardware registers (or mapping to memory 
>regions in general)
>should be performed at the linker and loader level, which have much better 
>tools for handling
>such tasks...

That's not my experience. Getting a linker to do anything at all is a royal 
pain, we avoided it as much as possible (most versions of Janus/Ada can 
directly produce executables if no foreign code is needed, not the Windows 
version, unfortunately).

And by putting essentially everything in the the Ada code, it becomes 
portable to other Ada compilers. (Gnatmake might be specific to GNAT, but 
every Ada compiler has something like it, so compiling Ada source is easy 
with other Ada compilers. Problems arise mainly when one reaches the 
boundary of what Ada can do.)

There's a problem in that version control systems mostly fail to deal 
properly with multiple versions of a file (they should be kept in sync 
mostly automatically), but that's definitely not Ada-related (every language 
struggles with that problem more-or-less).

> ... So, as far as I'm concerned, the whole "for X'Address use" idiom is 
> useless.

I agree with this, but mainly because I rarely do hardware these days. :-)

> And last by not least - I don't like to tie the source code to the 
> hardware this way.

I'd rather tie Ada-standard source code (properly encapsulated, of course) 
to hardware than anything specific to a single implementation. There has to 
be a good reason to avoid portability, and there isn't one here.

> But I have a code that resembles a pile of C hacks and now the only thing 
> that
> leads me in its analysis is "if it works then it's good", because the 
> standard was
> already thrown out the window. Sigh.

Well, you made that choice. It doesn't have to be that way. (If you're an 
implementer, the situation is different, but one hopes that most programmers 
don't need to stick their fingers into those light sockets.)

                                    Randy.



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: for X'Address use - and Volatile
  2016-08-31 22:17   ` Maciej Sobczak
  2016-09-01  1:22     ` Randy Brukardt
@ 2016-09-01  5:41     ` Simon Wright
  2016-09-01 14:24       ` Maciej Sobczak
  1 sibling, 1 reply; 8+ messages in thread
From: Simon Wright @ 2016-09-01  5:41 UTC (permalink / raw)


Maciej Sobczak <see.my.homepage@gmail.com> writes:

>> Indeed, address clauses ought to be avoided for all but their
>> intended purpose (mapping to hardware registers);
>
> I'd disagree here. Mapping to hardware registers (or mapping to memory
> regions in general) should be performed at the linker and loader
> level, which have much better tools for handling such tasks

And I'd disagree with that. By the time you have

* many registers to be described to the bit level
* many peripherals in your SOC
* more than a couple of teams involved
* a need to handle interrupts at the Ada level (i.e. with POs)

a linker script is *not* the best place to specify addresses. Especially
if you can call in a tool like AdaCore's svd2ada -
https://github.com/AdaCore/svd2ada

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: for X'Address use - and Volatile
  2016-08-31 19:36 ` Randy Brukardt
  2016-08-31 22:17   ` Maciej Sobczak
@ 2016-09-01  8:12   ` J-P. Rosen
  1 sibling, 0 replies; 8+ messages in thread
From: J-P. Rosen @ 2016-09-01  8:12 UTC (permalink / raw)


Le 31/08/2016 à 21:36, Randy Brukardt a écrit :
>> Consider:
>> >X : Integer;
>> >Y : Integer;
>> >for Y'Address use X'Address;
>> >
>> >The above is a simple overlay, typically used for under-the-table type 
>> >conversions.
> Ada does not now, nor ever has, officially supported overlays. Such code 
> might work on a particular implementation, but it's not portable (even to 
> another version of the same compiler).
> 
> Indeed, address clauses ought to be avoided for all but their intended 
> purpose (mapping to hardware registers); for other purposes, better 
> solutions exist (Unchecked_Conversion, Address_to_Access_Conversions, etc.)
Shameless plug:

and this can be detected in AdaControl:
check representation_clauses (overlay);

-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: for X'Address use - and Volatile
  2016-09-01  5:41     ` Simon Wright
@ 2016-09-01 14:24       ` Maciej Sobczak
  0 siblings, 0 replies; 8+ messages in thread
From: Maciej Sobczak @ 2016-09-01 14:24 UTC (permalink / raw)


> And I'd disagree with that. By the time you have
> 
> * many registers to be described to the bit level
> * many peripherals in your SOC
> * more than a couple of teams involved
> * a need to handle interrupts at the Ada level (i.e. with POs)
> 
> a linker script is *not* the best place to specify addresses.

Why?

In what way are the "many"'s above more difficult in the linker script than in the Ada code? Linker scripts are source files and they can be managed like other source files.

The difference is - the linker script can deal not only with the registers, but with general memory mapping for everything - including program code, stack space, free store, etc. Doing only some of it in Ada and some of it outside of it is just inconsistent. I prefer to have a consistent approach for what I consider to be a single, although general, problem (mapping of program entities to hardware).

-- 
Maciej Sobczak * http://www.inspirel.com

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2016-09-01 14:24 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-31 13:01 for X'Address use - and Volatile Maciej Sobczak
2016-08-31 14:00 ` AdaMagica
2016-08-31 19:36 ` Randy Brukardt
2016-08-31 22:17   ` Maciej Sobczak
2016-09-01  1:22     ` Randy Brukardt
2016-09-01  5:41     ` Simon Wright
2016-09-01 14:24       ` Maciej Sobczak
2016-09-01  8:12   ` J-P. Rosen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox