comp.lang.ada
 help / color / mirror / Atom feed
* This can't be done in Ada...or?
@ 2005-02-11 16:33 Per Lindquist
  2005-02-11 16:51 ` Duncan Sands
                   ` (4 more replies)
  0 siblings, 5 replies; 48+ messages in thread
From: Per Lindquist @ 2005-02-11 16:33 UTC (permalink / raw)


Hi, this question has already sort of been discussed in topics about
multiple target platforms, conditional compilation, preprocessors and
build strategies. Before giving up I thought I'd give it a try one last
time...

My impression from reading some threads is that Ada DOES NOT offer a
decent way to implement trace printouts (log messages), at least not
with the features stated below.

The problem
-----------

We want to be able to output log messages, or traces as we call it,
from an Ada program. There will be a few trace categories like Error,
Warning, Note etc. The messages (strings) can be sent to a file or
stdout or whatever (not important).

A call might look something like this:

Trace.Error(Package_Name, Subprogram_Name, "Woops, V=" &
Some_Type'Image(V));

How do we write a tracing utility in Ada that:
1. has different behaviour on different target platforms
2. can disable some categories depending on target platform at
compile-time.
3. does *not* cause any execution overhead if disabled.
4. does not need yucky "if Trace_Wanted then ... end if;" around all
calls
5. does not need preprocessing (some of you say it's never needed in
Ada...)

I say it can't be done in Ada. Please prove me wrong!

Appendix
--------
I don't want to clutter the post with too much info but some additional
stuff  may be of interest:

There are two target platforms:
"target variant":
HW: Sun workstation, OS: Solaris, Real-time: no, Compiler: gcc (gnat)

"host variant":
HW: PowerPC, OS: Integrity 5, Real-time: yes, Compiler: Adamulti (Green
Hills)

If we could get rid of those hardcoded constants

  Package_Name : constant String := "Some_Package";
  ...
  Subprogram_Name : constant String := "Some_Procedure1";
  ...
  Subprogram_Name : constant String := "Some_Procedure2";

it would be a great bonus, but I reckon it can't be done either..?




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

* Re: This can't be done in Ada...or?
  2005-02-11 16:33 This can't be done in Ada...or? Per Lindquist
@ 2005-02-11 16:51 ` Duncan Sands
  2005-02-12 19:55   ` Florian Weimer
  2005-02-14  8:17   ` Per Lindquist
  2005-02-11 17:02 ` Jeff C
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 48+ messages in thread
From: Duncan Sands @ 2005-02-11 16:51 UTC (permalink / raw)
  To: Per Lindquist; +Cc: comp.lang.ada

Hi,

> 3. does *not* cause any execution overhead if disabled.

presumably you mean: when disabled at compile time?

Ciao,

Duncan.




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

* Re: This can't be done in Ada...or?
  2005-02-11 16:33 This can't be done in Ada...or? Per Lindquist
  2005-02-11 16:51 ` Duncan Sands
@ 2005-02-11 17:02 ` Jeff C
  2005-02-11 18:27   ` Robert A Duff
  2005-02-11 17:08 ` Jerome Hugues
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 48+ messages in thread
From: Jeff C @ 2005-02-11 17:02 UTC (permalink / raw)


Per Lindquist wrote:
> Hi, this question has already sort of been discussed in topics about
> multiple target platforms, conditional compilation, preprocessors and
> build strategies. Before giving up I thought I'd give it a try one last
> time...
> 
> My impression from reading some threads is that Ada DOES NOT offer a
> decent way to implement trace printouts (log messages), at least not
> with the features stated below.
> 
> The problem
> -----------
> 
> We want to be able to output log messages, or traces as we call it,
> from an Ada program. There will be a few trace categories like Error,
> Warning, Note etc. The messages (strings) can be sent to a file or
> stdout or whatever (not important).
> 
> A call might look something like this:
> 
> Trace.Error(Package_Name, Subprogram_Name, "Woops, V=" &
> Some_Type'Image(V));
> 
> How do we write a tracing utility in Ada that:
> 1. has different behaviour on different target platforms
> 2. can disable some categories depending on target platform at
> compile-time.
> 3. does *not* cause any execution overhead if disabled.
> 4. does not need yucky "if Trace_Wanted then ... end if;" around all
> calls
> 5. does not need preprocessing (some of you say it's never needed in
> Ada...)
> 
> I say it can't be done in Ada. Please prove me wrong!
> 
> Appendix
> --------
> I don't want to clutter the post with too much info but some additional
> stuff  may be of interest:
> 
> There are two target platforms:
> "target variant":
> HW: Sun workstation, OS: Solaris, Real-time: no, Compiler: gcc (gnat)
> 
> "host variant":
> HW: PowerPC, OS: Integrity 5, Real-time: yes, Compiler: Adamulti (Green
> Hills)
> 
> If we could get rid of those hardcoded constants
> 
>   Package_Name : constant String := "Some_Package";
>   ...
>   Subprogram_Name : constant String := "Some_Procedure1";
>   ...
>   Subprogram_Name : constant String := "Some_Procedure2";
> 
> it would be a great bonus, but I reckon it can't be done either..?
> 

1) Use different package bodies on different platforms..Or (if 
differences are small and don't really require target dependant 
packages) then have the main body be the same but key some branches of 
static constants in a separate spec.
2) Basically I'd go with a variant of #1 above. Have a Logging_Control 
package that just declares constants for what should be enabled. Rely on 
your revision control system to select the appropriate spec
3) Pragma Inline the procedure calls.  Put the "if Logging_Enabled" 
inside the logging procedures. Make the Logging_Enabled a static 
constant. Compiler should optimize away the entire procedure call if 
done properly (it does on GNAT and VADS for the cases I have tried)
4)See #3...This is only done inside the logging procedure. Same as the
#ifdef approach you are missing.
5) OK. Done.


I think the above approach gets you close enough that you should be 
happy. If it does not work for a particular vendor..Fire the vendor.

  Note that
I agree it would be nice to have some way to avoid your constants (Like 
GNAT.Source_Info)

Unfortuntely this is not seen as a priority and I dont think it will 
make it aven into Ada 2005

http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00282.TXT?rev=1.4







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

* Re: This can't be done in Ada...or?
  2005-02-11 16:33 This can't be done in Ada...or? Per Lindquist
  2005-02-11 16:51 ` Duncan Sands
  2005-02-11 17:02 ` Jeff C
@ 2005-02-11 17:08 ` Jerome Hugues
  2005-02-14  9:05   ` Per Lindquist
  2005-02-12  1:10 ` Jeffrey Carter
  2005-02-14 15:21 ` Peter Amey
  4 siblings, 1 reply; 48+ messages in thread
From: Jerome Hugues @ 2005-02-11 17:08 UTC (permalink / raw)


In article <1108139611.709714.36170@o13g2000cwo.googlegroups.com>, Per Lindquist wrote:

> My impression from reading some threads is that Ada DOES NOT offer a
> decent way to implement trace printouts (log messages), at least not
> with the features stated below.

Where did you read that ?

> We want to be able to output log messages, or traces as we call it,
> from an Ada program. There will be a few trace categories like Error,
> Warning, Note etc. The messages (strings) can be sent to a file or
> stdout or whatever (not important).
> 
> A call might look something like this:
> 
> Trace.Error(Package_Name, Subprogram_Name, "Woops, V=" &
> Some_Type'Image(V));
> 
> How do we write a tracing utility in Ada that:
> 1. has different behaviour on different target platforms

=> provide one body/target + GNAT project files

> 2. can disable some categories depending on target platform at
> compile-time.

=> build a spec-only package that looks like

package My_Flags is

  Feature_1 : constant Boolean := False;

end My_Flags

In the implementation of Trace.Error, use My_Flags.Feature_x to
disable code. Any decent (all ?) Ada compiler should remove all "if
False then .. end if;" blocks at compile-time

> 3. does *not* cause any execution overhead if disabled.

=> pragma Debug (Trace.Error  ..);

(GNAT specific)

> 4. does not need yucky "if Trace_Wanted then ... end if;" around all
> calls

=> pragma Debug ..

> 5. does not need preprocessing (some of you say it's never needed in
> Ada...)

=> My solution doesn't, yet it requires tweaking your compilation
process so that you can select the correct package depending on your
configuration.

> I say it can't be done in Ada. Please prove me wrong!

You can, but I confess my solution is in part vendor specific.

The only kludge is the one body/implementation, GNAT project files
should handle this easily.

> If we could get rid of those hardcoded constants
> 
>   Package_Name : constant String := "Some_Package";
>   ...
>   Subprogram_Name : constant String := "Some_Procedure1";
>   ...
>   Subprogram_Name : constant String := "Some_Procedure2";
> 
> it would be a great bonus, but I reckon it can't be done either..?

See GNAT.Source_Info

in your code, just try

Ada.Text_IO.Put_Line (GNAT.Source_Info (Source_Location));

and see the magic occurs. GNAT.Source_Info is the equivalent of
__FILE__, __LINE__ macros from C.

-- 
Jerome



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

* Re: This can't be done in Ada...or?
  2005-02-11 17:02 ` Jeff C
@ 2005-02-11 18:27   ` Robert A Duff
  2005-02-11 23:51     ` Ludovic Brenta
                       ` (2 more replies)
  0 siblings, 3 replies; 48+ messages in thread
From: Robert A Duff @ 2005-02-11 18:27 UTC (permalink / raw)


Jeff C <jcreem@yahoo.com> writes:

> Per Lindquist wrote:
> > 3. does *not* cause any execution overhead if disabled.
...
> > I say it can't be done in Ada. Please prove me wrong!


> 3) Pragma Inline the procedure calls.  Put the "if Logging_Enabled"
> inside the logging procedures. Make the Logging_Enabled a static
> constant. Compiler should optimize away the entire procedure call if
> done properly (it does on GNAT and VADS for the cases I have tried)

The compiler can optimize away everything inside the "if
Logging_Enabled".  But it can't optimize away the evaluation of the
parameters unless it can prove the absence of side effects.
For example:

    Trace.Error(..., "Bad value of X " & Debug_Info(X));

where Debug_Info is some user-defined function that produces useful
debug info about some complicated data structure called X.
It has no side effects, but the compiler doesn't know that, usually.

I suppose you could always write Debug_Info like this:

    function Debug_Info(...) return String;
    pragma Inline(Debug_Info);
    -- Don't call this unless Logging_Enabled is True!

    function Debug_Info(...) return String is
    begin
        if Logging_Enabled then
            return The_Real_Debug_Info(...);
        else
            raise Program_Error;
        end if;
    end Debug_Info;

But then you have to write two versions of Debug_Info
for every type.  So I'd say the original poster's statement,
"it can't be done in Ada" is pretty true, if zero run-time overhead
is required.

In my code, I usually do as you suggested, but *also* add "if
Logging_Enabled" or whatever around calls if the parameter evaluation
could be expensive.  This provides *almost* what the original poster
asked for -- you need the annoying "if Logging_Enabled" only sometimes.

- Bob



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

* Re: This can't be done in Ada...or?
  2005-02-11 18:27   ` Robert A Duff
@ 2005-02-11 23:51     ` Ludovic Brenta
  2005-02-11 23:52       ` Robert A Duff
  2005-02-12 13:55     ` Duncan Sands
  2005-02-14  8:49     ` Per Lindquist
  2 siblings, 1 reply; 48+ messages in thread
From: Ludovic Brenta @ 2005-02-11 23:51 UTC (permalink / raw)


Robert A Duff writes:
> The compiler can optimize away everything inside the "if
> Logging_Enabled".  But it can't optimize away the evaluation of the
> parameters unless it can prove the absence of side effects.  For
> example:
>
>     Trace.Error(..., "Bad value of X " & Debug_Info(X));
>
> where Debug_Info is some user-defined function that produces useful
> debug info about some complicated data structure called X.  It has
> no side effects, but the compiler doesn't know that, usually.

What if Debug_Info is in a Pure package?  Does the compiler still have
to consider possible side effects?  I'm really curious.

-- 
Ludovic Brenta.




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

* Re: This can't be done in Ada...or?
  2005-02-11 23:51     ` Ludovic Brenta
@ 2005-02-11 23:52       ` Robert A Duff
  0 siblings, 0 replies; 48+ messages in thread
From: Robert A Duff @ 2005-02-11 23:52 UTC (permalink / raw)


Ludovic Brenta <ludovic.brenta@insalien.org> writes:

> Robert A Duff writes:
> > The compiler can optimize away everything inside the "if
> > Logging_Enabled".  But it can't optimize away the evaluation of the
> > parameters unless it can prove the absence of side effects.  For
> > example:
> >
> >     Trace.Error(..., "Bad value of X " & Debug_Info(X));
> >
> > where Debug_Info is some user-defined function that produces useful
> > debug info about some complicated data structure called X.  It has
> > no side effects, but the compiler doesn't know that, usually.
> 
> What if Debug_Info is in a Pure package?  Does the compiler still have
> to consider possible side effects?

No.

It's usually a good idea to make things pragma-Pure when possible.
Unfortunately, it's not usually possible.  The restrictions on
pure packages are pretty severe.  No access types, for example.
And you usually need access types to make complicated data
structures.  I think Ada 2005 relaxes that restriction.

>...  I'm really curious.

- Bob



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

* Re: This can't be done in Ada...or?
  2005-02-11 16:33 This can't be done in Ada...or? Per Lindquist
                   ` (2 preceding siblings ...)
  2005-02-11 17:08 ` Jerome Hugues
@ 2005-02-12  1:10 ` Jeffrey Carter
  2005-02-12 14:01   ` Duncan Sands
  2005-02-14 15:21 ` Peter Amey
  4 siblings, 1 reply; 48+ messages in thread
From: Jeffrey Carter @ 2005-02-12  1:10 UTC (permalink / raw)


Per Lindquist wrote:

> If we could get rid of those hardcoded constants
> 
>   Package_Name : constant String := "Some_Package";
>   ...
>   Subprogram_Name : constant String := "Some_Procedure1";
>   ...
>   Subprogram_Name : constant String := "Some_Procedure2";
> 
> it would be a great bonus, but I reckon it can't be done either..?

See PragmARC.Reflection.

http://home.earthlink.net/~jrcarter010/pragmarc.htm

-- 
Jeff Carter
"If you think you got a nasty taunting this time,
you ain't heard nothing yet!"
Monty Python and the Holy Grail
23



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

* Re: This can't be done in Ada...or?
  2005-02-11 18:27   ` Robert A Duff
  2005-02-11 23:51     ` Ludovic Brenta
@ 2005-02-12 13:55     ` Duncan Sands
  2005-02-12 14:58       ` Martin Krischik
  2005-02-12 19:02       ` Robert A Duff
  2005-02-14  8:49     ` Per Lindquist
  2 siblings, 2 replies; 48+ messages in thread
From: Duncan Sands @ 2005-02-12 13:55 UTC (permalink / raw)
  To: Robert A Duff; +Cc: comp.lang.ada

> The compiler can optimize away everything inside the "if
> Logging_Enabled".  But it can't optimize away the evaluation of the
> parameters unless it can prove the absence of side effects.
> For example:
> 
>     Trace.Error(..., "Bad value of X " & Debug_Info(X));
> 
> where Debug_Info is some user-defined function that produces useful
> debug info about some complicated data structure called X.
> It has no side effects, but the compiler doesn't know that, usually.

GNAT's pragma Pure_Function might help here.  Is something like that
planned for Ada 2005?

All the best,

Duncan.




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

* Re: This can't be done in Ada...or?
  2005-02-12  1:10 ` Jeffrey Carter
@ 2005-02-12 14:01   ` Duncan Sands
  2005-02-13  0:27     ` Jeffrey Carter
  0 siblings, 1 reply; 48+ messages in thread
From: Duncan Sands @ 2005-02-12 14:01 UTC (permalink / raw)
  To: Jeffrey Carter; +Cc: comp.lang.ada

> See PragmARC.Reflection.
> 
> http://home.earthlink.net/~jrcarter010/pragmarc.htm

That's a great trick - made my day!

Duncan.




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

* Re: This can't be done in Ada...or?
  2005-02-12 13:55     ` Duncan Sands
@ 2005-02-12 14:58       ` Martin Krischik
  2005-02-12 15:56         ` Martin Dowie
  2005-02-12 19:02       ` Robert A Duff
  1 sibling, 1 reply; 48+ messages in thread
From: Martin Krischik @ 2005-02-12 14:58 UTC (permalink / raw)


Duncan Sands wrote:

>> The compiler can optimize away everything inside the "if
>> Logging_Enabled".  But it can't optimize away the evaluation of the
>> parameters unless it can prove the absence of side effects.
>> For example:
>> 
>>     Trace.Error(..., "Bad value of X " & Debug_Info(X));
>> 
>> where Debug_Info is some user-defined function that produces useful
>> debug info about some complicated data structure called X.
>> It has no side effects, but the compiler doesn't know that, usually.
> 
> GNAT's pragma Pure_Function might help here.  Is something like that
> planned for Ada 2005?

I heards rumors for "yes" but I could not confirm then.

Maritn
-- 
mailto://krischik@users.sourceforge.net
Ada programming at: http://ada.krischik.com




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

* Re: This can't be done in Ada...or?
  2005-02-12 14:58       ` Martin Krischik
@ 2005-02-12 15:56         ` Martin Dowie
  0 siblings, 0 replies; 48+ messages in thread
From: Martin Dowie @ 2005-02-12 15:56 UTC (permalink / raw)


>>GNAT's pragma Pure_Function might help here.  Is something like that
>>planned for Ada 2005?
> 
> 
> I heards rumors for "yes" but I could not confirm then.

Nope!

!status No Action (9-0-1) 04-03-05

There is a very useful search engine for AI's at

http://www.ada-auth.org/search-ais.html

Cheers

-- Martin



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

* Re: This can't be done in Ada...or?
  2005-02-12 13:55     ` Duncan Sands
  2005-02-12 14:58       ` Martin Krischik
@ 2005-02-12 19:02       ` Robert A Duff
  1 sibling, 0 replies; 48+ messages in thread
From: Robert A Duff @ 2005-02-12 19:02 UTC (permalink / raw)


Duncan Sands <baldrick@free.fr> writes:

> > The compiler can optimize away everything inside the "if
> > Logging_Enabled".  But it can't optimize away the evaluation of the
> > parameters unless it can prove the absence of side effects.
> > For example:
> > 
> >     Trace.Error(..., "Bad value of X " & Debug_Info(X));
> > 
> > where Debug_Info is some user-defined function that produces useful
> > debug info about some complicated data structure called X.
> > It has no side effects, but the compiler doesn't know that, usually.
> 
> GNAT's pragma Pure_Function might help here.

Yes.

Note that Pure_Function has different semantics than Pure (besides the
fact that Pure_Function has finer granularity).  Pragma Pure has rules
that require the thing to actually *be* pure.  The only way to
circumvent those rules is with things like machine code inserts.
But Pure_Function has no such rules: if you lie, the compiler will
believe you, and your program might malfunction.

Robert Dewar objected to the rules for pragma Pure during Ada 9X -- he
thought it should be like Pure_Function in that regard.  That's because
(like all compile time rules) the rules are conservative.  You can't
write a memoizing function and declare it Pure, but you can declare it
Pure_Function.

>...  Is something like that
> planned for Ada 2005?

Somebody answered that, "no".  If I were designing the language, I would
allow Pure on procedures and functions as well as library packages.
I would require compile time checking.  Then I would add *another*
pragma to turn off the checking; this could be placed in the body.
Seems like the best of both worlds: Robert can have his pure memoizing
functions, but in cases where the compiler *can* check the rules,
the rules are checked.

- Bob



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

* Re: This can't be done in Ada...or?
  2005-02-11 16:51 ` Duncan Sands
@ 2005-02-12 19:55   ` Florian Weimer
  2005-02-14  8:34     ` Per Lindquist
  2005-02-14  8:17   ` Per Lindquist
  1 sibling, 1 reply; 48+ messages in thread
From: Florian Weimer @ 2005-02-12 19:55 UTC (permalink / raw)


* Duncan Sands:

>> 3. does *not* cause any execution overhead if disabled.
>
> presumably you mean: when disabled at compile time?

In C, you can reach almost zero run-time overhead (certainly
non-measurable unless you put optional logging into inner loops) if
you use a preprocessor macro to fake lazy evaluation.  As far as I
know, it is not possible in Ada to suppress evaluation of subprogram
arguments at run-time.



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

* Re: This can't be done in Ada...or?
  2005-02-12 14:01   ` Duncan Sands
@ 2005-02-13  0:27     ` Jeffrey Carter
  2005-02-14  9:10       ` Per Lindquist
  0 siblings, 1 reply; 48+ messages in thread
From: Jeffrey Carter @ 2005-02-13  0:27 UTC (permalink / raw)


Duncan Sands wrote:
>>See PragmARC.Reflection.
>>
>>http://home.earthlink.net/~jrcarter010/pragmarc.htm
> 
> That's a great trick - made my day!

I'm glad someone likes it.

Obviously, compilers are required to have that information available. It 
shouldn't be so hard to extract it.

-- 
Jeff Carter
"So if I understand 'The Matrix Reloaded' correctly, the Matrix is
basically a Microsoft operating system--it runs for a while and
then crashes and reboots. By design, no less. Neo is just a
memory leak that's too hard to fix, so they left him in ... The
users don't complain because they're packed in slush and kept
sedated."
Marin D. Condic
65



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

* Re: This can't be done in Ada...or?
  2005-02-11 16:51 ` Duncan Sands
  2005-02-12 19:55   ` Florian Weimer
@ 2005-02-14  8:17   ` Per Lindquist
  1 sibling, 0 replies; 48+ messages in thread
From: Per Lindquist @ 2005-02-14  8:17 UTC (permalink / raw)


Yes (sorry for the slow response).




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

* Re: This can't be done in Ada...or?
  2005-02-12 19:55   ` Florian Weimer
@ 2005-02-14  8:34     ` Per Lindquist
  0 siblings, 0 replies; 48+ messages in thread
From: Per Lindquist @ 2005-02-14  8:34 UTC (permalink / raw)


Yes, in C this would have been no problem (we are experienced C
programmers just moving on to Ada and we're quite frustrated over this
issue). (The C solution requires use of macros but I think that's less
controversial than using macros in Ada.)




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

* Re: This can't be done in Ada...or?
  2005-02-11 18:27   ` Robert A Duff
  2005-02-11 23:51     ` Ludovic Brenta
  2005-02-12 13:55     ` Duncan Sands
@ 2005-02-14  8:49     ` Per Lindquist
  2 siblings, 0 replies; 48+ messages in thread
From: Per Lindquist @ 2005-02-14  8:49 UTC (permalink / raw)


>But it can't optimize away the evaluation of the
>parameters unless it can prove the absence of side effects.

This is actually the main reason for the post.

Jeff's suggestion is the direction we were heading for but the
parameter evaluation made it somewhat unsufficient.

>But then you have to write two versions of Debug_Info
>for every type.  So I'd say the original poster's statement,
>"it can't be done in Ada" is pretty true, if zero run-time overhead
>is required.
>
>In my code, I usually do as you suggested, but *also* add "if
>Logging_Enabled" or whatever around calls if the parameter evaluation
>could be expensive.  This provides *almost* what the original poster
>asked for -- you need the annoying "if Logging_Enabled" only
sometimes.

OK, maybe this is the way we must go...

Thanks for confirming.




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

* Re: This can't be done in Ada...or?
  2005-02-11 17:08 ` Jerome Hugues
@ 2005-02-14  9:05   ` Per Lindquist
  2005-02-14 13:07     ` Georg Bauhaus
  0 siblings, 1 reply; 48+ messages in thread
From: Per Lindquist @ 2005-02-14  9:05 UTC (permalink / raw)


I think your suggestions are all good but unfortunately we probably
cannot rely on anything GNAT specific. We have to cope with what's in
the Ada language standard basically.




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

* Re: This can't be done in Ada...or?
  2005-02-13  0:27     ` Jeffrey Carter
@ 2005-02-14  9:10       ` Per Lindquist
  2005-02-15  0:40         ` Jeffrey Carter
  0 siblings, 1 reply; 48+ messages in thread
From: Per Lindquist @ 2005-02-14  9:10 UTC (permalink / raw)


Thanks, I've tried your package before. Works great but I miss a
Subprogram_Name auto-assignment so... (Ah those users, always wanting
more more more... ;)




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

* Re: This can't be done in Ada...or?
  2005-02-14  9:05   ` Per Lindquist
@ 2005-02-14 13:07     ` Georg Bauhaus
  0 siblings, 0 replies; 48+ messages in thread
From: Georg Bauhaus @ 2005-02-14 13:07 UTC (permalink / raw)


Per Lindquist wrote:
> I think your suggestions are all good but unfortunately we probably
> cannot rely on anything GNAT specific. We have to cope with what's in
> the Ada language standard basically.
> 

As another solution which isn't perfect either, I use
something like

  pragma silent(Trace.Error("a", "b", "c"));

While this line needs preprocessing (or SCM) when the call is to become
a call, a pragma is within the Ada language. You might get additional
warnings from the compiler, but you don't get any code, i.e. any overhead.


-- Georg



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

* Re: This can't be done in Ada...or?
  2005-02-11 16:33 This can't be done in Ada...or? Per Lindquist
                   ` (3 preceding siblings ...)
  2005-02-12  1:10 ` Jeffrey Carter
@ 2005-02-14 15:21 ` Peter Amey
  4 siblings, 0 replies; 48+ messages in thread
From: Peter Amey @ 2005-02-14 15:21 UTC (permalink / raw)




Per Lindquist wrote:
> Hi, this question has already sort of been discussed in topics about
> multiple target platforms, conditional compilation, preprocessors and
> build strategies. Before giving up I thought I'd give it a try one last
> time...
> 
> My impression from reading some threads is that Ada DOES NOT offer a
> decent way to implement trace printouts (log messages), at least not
> with the features stated below.
> 
> The problem
> -----------
> 
> We want to be able to output log messages, or traces as we call it,
> from an Ada program. There will be a few trace categories like Error,
> Warning, Note etc. The messages (strings) can be sent to a file or
> stdout or whatever (not important).
> 
> A call might look something like this:
> 
> Trace.Error(Package_Name, Subprogram_Name, "Woops, V=" &
> Some_Type'Image(V));
> 
> How do we write a tracing utility in Ada that:
> 1. has different behaviour on different target platforms
> 2. can disable some categories depending on target platform at
> compile-time.
> 3. does *not* cause any execution overhead if disabled.
> 4. does not need yucky "if Trace_Wanted then ... end if;" around all
> calls
> 5. does not need preprocessing (some of you say it's never needed in
> Ada...)
> 
> I say it can't be done in Ada. Please prove me wrong!
> 

One useful approach I have used is to make us of subunits.  Each of the 
reporting routines in your package Trace can be made a subunit of Trace. 
  The subunit itself, e.g. Error,  can have two implementations, one 
that reports the error and one which is just a null body.  The compiler 
"make" system and library manager can be used to build different 
variants with different levels of reporting.  If the stub is marked as 
in_line then there is no overhead when the null version is called.

Peter




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

* Re: This can't be done in Ada...or?
  2005-02-15  8:27           ` This can't be done in Ada...or? Per Lindquist
@ 2005-02-14 22:10             ` Manuel G. R.
  2005-02-15  8:47             ` Mark Lorenzen
                               ` (2 subsequent siblings)
  3 siblings, 0 replies; 48+ messages in thread
From: Manuel G. R. @ 2005-02-14 22:10 UTC (permalink / raw)


Per Lindquist wrote:
> Jeffrey Carter wrote:
> 
>>   procedure Q is
>>      package That is new PragmARC.Reflection;
> 
> 
> Hm, I was so excited about your solution I didn't notice the potential
> problem with overhead, but a collegue of mine did:
> 
> One of our target environments is a time-critical real-time system. We
> are worried about the execution overhead implied by a package
> instantiation (or any 'new' statement) in every subprogram in the
> system.
> 
> Will your solution cause overhead for each subprogram call?
> 

GNAT does provide GNAT.Source_Info.Enclosing_Entity for the same thing 
and probably without overhead. Do other compilers provide something 
equivalent?

If I wrap GNAT.Source_Info, can I expect that when porting to other 
compiler there will be another package providing the same functionality?

-- 
Ada programming tutorial: http://en.wikibooks.org/wiki/Programming:Ada
Tutorial de programaci�n en Ada: 
http://es.wikibooks.org/wiki/Programaci%C3%B3n_en_Ada



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

* Re: This can't be done in Ada...or?
  2005-02-14  9:10       ` Per Lindquist
@ 2005-02-15  0:40         ` Jeffrey Carter
  2005-02-15  7:40           ` Per Lindquist
  2005-02-15  8:27           ` This can't be done in Ada...or? Per Lindquist
  0 siblings, 2 replies; 48+ messages in thread
From: Jeffrey Carter @ 2005-02-15  0:40 UTC (permalink / raw)


Per Lindquist wrote:
> Thanks, I've tried your package before. Works great but I miss a
> Subprogram_Name auto-assignment so... (Ah those users, always wanting
> more more more... ;)

It would be helpful if there was some indication of what you are 
replying to. I'm going to assume this is a response to my response.

I'm not sure what you mean by "Subprogram_Name auto-assignment". Could 
you explain further?

Note that you can instantiate PragmARC.Reflection inside a subprogram:

with Ada.Text_IO;
with PragmARC.Reflection;
package body P is
    package This is new PragmARC.Reflection;

    procedure Q is
       package That is new PragmARC.Reflection;
    begin -- Q
       Ada.Text_IO.Put_Line (Item => That.Unit_Name); -- "P.Q"
    end Q;
begin -- P
    Ada.Text_IO.Put_Line (Item => This.Unit_Name); -- "P"
end P;

-- 
Jeff Carter
"Sons of a silly person."
Monty Python & the Holy Grail
02



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

* Re: This can't be done in Ada...or?
  2005-02-15  0:40         ` Jeffrey Carter
@ 2005-02-15  7:40           ` Per Lindquist
  2005-02-15  8:39             ` OT: Google reply (Was: Re: This can't be done in Ada...or?) Adrien Plisson
  2005-02-15  8:27           ` This can't be done in Ada...or? Per Lindquist
  1 sibling, 1 reply; 48+ messages in thread
From: Per Lindquist @ 2005-02-15  7:40 UTC (permalink / raw)


Jeffrey Carter wrote:
>It would be helpful if there was some indication of what you are
>replying to. I'm going to assume this is a response to my response.

OK, sorry. I read news through google groups and there is a "tree
navigator" that shows who is responding to who so for me it is clear.
Obviously not so for everybody.

(On the other hand the reply function is not very user friendly. I have
to copy&paste all citations manually...)

>Note that you can instantiate PragmARC.Reflection inside a
>subprogram:

Ah, that's exactly what I wanted, thanks! Wohoo! :)




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

* Re: This can't be done in Ada...or?
  2005-02-15  0:40         ` Jeffrey Carter
  2005-02-15  7:40           ` Per Lindquist
@ 2005-02-15  8:27           ` Per Lindquist
  2005-02-14 22:10             ` Manuel G. R.
                               ` (3 more replies)
  1 sibling, 4 replies; 48+ messages in thread
From: Per Lindquist @ 2005-02-15  8:27 UTC (permalink / raw)


Jeffrey Carter wrote:
>    procedure Q is
>       package That is new PragmARC.Reflection;

Hm, I was so excited about your solution I didn't notice the potential
problem with overhead, but a collegue of mine did:

One of our target environments is a time-critical real-time system. We
are worried about the execution overhead implied by a package
instantiation (or any 'new' statement) in every subprogram in the
system.

Will your solution cause overhead for each subprogram call?




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

* OT: Google reply (Was: Re: This can't be done in Ada...or?)
  2005-02-15  7:40           ` Per Lindquist
@ 2005-02-15  8:39             ` Adrien Plisson
  2005-02-15  9:42               ` Per Lindquist
  0 siblings, 1 reply; 48+ messages in thread
From: Adrien Plisson @ 2005-02-15  8:39 UTC (permalink / raw)


Per Lindquist wrote:
> Jeffrey Carter wrote:
> 
>>It would be helpful if there was some indication of what you are
>>replying to. I'm going to assume this is a response to my response.
> 
> 
> OK, sorry. I read news through google groups and there is a "tree
> navigator" that shows who is responding to who so for me it is clear.
> Obviously not so for everybody.
> 
> (On the other hand the reply function is not very user friendly. I have
> to copy&paste all citations manually...)

don't use the "reply" link at the end of each post. instead, click on 
show options at the top of the post, then use the "reply" link below 
headers. it will open a new page for reply with the post you are 
replying to properly quoted.

-- 
rien



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

* Re: This can't be done in Ada...or?
  2005-02-15  8:27           ` This can't be done in Ada...or? Per Lindquist
  2005-02-14 22:10             ` Manuel G. R.
@ 2005-02-15  8:47             ` Mark Lorenzen
  2005-02-15  9:09               ` Jacob Sparre Andersen
  2005-02-17 22:06               ` Randy Brukardt
  2005-02-16  0:04             ` Jeffrey Carter
  2005-02-16  0:09             ` Jeffrey Carter
  3 siblings, 2 replies; 48+ messages in thread
From: Mark Lorenzen @ 2005-02-15  8:47 UTC (permalink / raw)


"Per Lindquist" <commander@death-star.com> writes:

> Jeffrey Carter wrote:
> >    procedure Q is
> >       package That is new PragmARC.Reflection;
> 
> Hm, I was so excited about your solution I didn't notice the potential
> problem with overhead, but a collegue of mine did:
> 
> One of our target environments is a time-critical real-time system. We
> are worried about the execution overhead implied by a package
> instantiation (or any 'new' statement) in every subprogram in the
> system.
> 
> Will your solution cause overhead for each subprogram call?

A compile-time instantiation of a package has nothing to do with
run-time efficiency. You can also define a new type in a subprogram,
which doesn't affect run-time efficiency either.

- Mark Lorenzen



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

* Re: This can't be done in Ada...or?
  2005-02-15  8:47             ` Mark Lorenzen
@ 2005-02-15  9:09               ` Jacob Sparre Andersen
  2005-02-15  9:31                 ` Mark Lorenzen
  2005-02-15 13:41                 ` Robert A Duff
  2005-02-17 22:06               ` Randy Brukardt
  1 sibling, 2 replies; 48+ messages in thread
From: Jacob Sparre Andersen @ 2005-02-15  9:09 UTC (permalink / raw)


Mark Lorenzen wrote:
> "Per Lindquist" <commander@death-star.com> writes:

> > One of our target environments is a time-critical real-time
> > system. We are worried about the execution overhead implied by a
> > package instantiation (or any 'new' statement) in every subprogram
> > in the system.
> > 
> > Will your solution cause overhead for each subprogram call?
> 
> A compile-time instantiation of a package has nothing to do with
> run-time efficiency. You can also define a new type in a subprogram,
> which doesn't affect run-time efficiency either.

Aren't the compilers (theoretically) allowed to delay the
instantiation of the packgage until run-time?

Jacob
-- 
"Only Hogwarts students really need spellcheckers"
                                -- An anonymous RISKS reader




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

* Re: This can't be done in Ada...or?
  2005-02-15  9:09               ` Jacob Sparre Andersen
@ 2005-02-15  9:31                 ` Mark Lorenzen
  2005-02-15  9:48                   ` Jacob Sparre Andersen
                                     ` (2 more replies)
  2005-02-15 13:41                 ` Robert A Duff
  1 sibling, 3 replies; 48+ messages in thread
From: Mark Lorenzen @ 2005-02-15  9:31 UTC (permalink / raw)


Jacob Sparre Andersen <sparre@nbi.dk> writes:

> Mark Lorenzen wrote:
> > "Per Lindquist" <commander@death-star.com> writes:
> 
> > > One of our target environments is a time-critical real-time
> > > system. We are worried about the execution overhead implied by a
> > > package instantiation (or any 'new' statement) in every subprogram
> > > in the system.
> > > 
> > > Will your solution cause overhead for each subprogram call?
> > 
> > A compile-time instantiation of a package has nothing to do with
> > run-time efficiency. You can also define a new type in a subprogram,
> > which doesn't affect run-time efficiency either.
> 
> Aren't the compilers (theoretically) allowed to delay the
> instantiation of the packgage until run-time?

Hm yes, I think they are - as the semantics is written as an "as-if"
semantics. But if the generic package body does not need to be
elaborated, there will probably not be any overhead.

> 
> Jacob
> -- 
> "Only Hogwarts students really need spellcheckers"
>                                 -- An anonymous RISKS reader

- Mark



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

* Re: OT: Google reply (Was: Re: This can't be done in Ada...or?)
  2005-02-15  8:39             ` OT: Google reply (Was: Re: This can't be done in Ada...or?) Adrien Plisson
@ 2005-02-15  9:42               ` Per Lindquist
  0 siblings, 0 replies; 48+ messages in thread
From: Per Lindquist @ 2005-02-15  9:42 UTC (permalink / raw)


Adrien Plisson wrote:
> don't use the "reply" link at the end of each post. instead, click on

> show options at the top of the post, then use the "reply" link below
> headers. it will open a new page for reply with the post you are
> replying to properly quoted.
>
> --
> rien

Ah. That's better! (Odd this isn't default behavior...) Thanks Adrien!




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

* Re: This can't be done in Ada...or?
  2005-02-15  9:31                 ` Mark Lorenzen
@ 2005-02-15  9:48                   ` Jacob Sparre Andersen
  2005-02-15 10:07                     ` Mark Lorenzen
  2005-02-15 10:15                   ` Martin Dowie
  2005-02-15 13:46                   ` Robert A Duff
  2 siblings, 1 reply; 48+ messages in thread
From: Jacob Sparre Andersen @ 2005-02-15  9:48 UTC (permalink / raw)


Mark Lorenzen wrote:
> Jacob Sparre Andersen <sparre@nbi.dk> writes:

> > Aren't the compilers (theoretically) allowed to delay the
> > instantiation of the packgage until run-time?
> 
> Hm yes, I think they are - as the semantics is written as an "as-if"
> semantics. But if the generic package body does not need to be
> elaborated, there will probably not be any overhead.

Would a Preelaborate or Pure pragma in the generic package make any
difference here?  (although I don't think Preelaborate would be legal
in PragmARC.Reflection)

What do the compilers actually do?  My guess is that they all
instantiate the package(s) at compile-time, but I don't know (and I
only have access to GNAT).

Jacob
-- 
"Three can keep a secret if two of them are dead."



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

* Re: This can't be done in Ada...or?
  2005-02-15  9:48                   ` Jacob Sparre Andersen
@ 2005-02-15 10:07                     ` Mark Lorenzen
  0 siblings, 0 replies; 48+ messages in thread
From: Mark Lorenzen @ 2005-02-15 10:07 UTC (permalink / raw)


Jacob Sparre Andersen <sparre@nbi.dk> writes:

> Mark Lorenzen wrote:
> > Jacob Sparre Andersen <sparre@nbi.dk> writes:
> 
> > > Aren't the compilers (theoretically) allowed to delay the
> > > instantiation of the packgage until run-time?
> > 
> > Hm yes, I think they are - as the semantics is written as an "as-if"
> > semantics. But if the generic package body does not need to be
> > elaborated, there will probably not be any overhead.
> 
> Would a Preelaborate or Pure pragma in the generic package make any
> difference here?  (although I don't think Preelaborate would be legal
> in PragmARC.Reflection)
> 
> What do the compilers actually do?  My guess is that they all
> instantiate the package(s) at compile-time, but I don't know (and I
> only have access to GNAT).
> 
> Jacob
> -- 
> "Three can keep a secret if two of them are dead."

I think that GNAT instantiates the packages at compile-time.

- Mark



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

* Re: This can't be done in Ada...or?
  2005-02-15  9:31                 ` Mark Lorenzen
  2005-02-15  9:48                   ` Jacob Sparre Andersen
@ 2005-02-15 10:15                   ` Martin Dowie
  2005-02-17 22:09                     ` Randy Brukardt
  2005-02-15 13:46                   ` Robert A Duff
  2 siblings, 1 reply; 48+ messages in thread
From: Martin Dowie @ 2005-02-15 10:15 UTC (permalink / raw)


Mark Lorenzen wrote:
> Hm yes, I think they are - as the semantics is written as an "as-if"
> semantics. But if the generic package body does not need to be
> elaborated, there will probably not be any overhead.

That 'probably' looks a little worrying to me! :-)

There's only one way to do this and that's to actually try it in your 
system.

Another change you could make that might make a difference is to change:

    Name : constant String := Expanded_Name (T'Tag);

to:

    Name : constant String := T'External_Tag;

That way you can make PragmARC.Reflection "pragma Preelaborate" and not 
have any dependency on "Ada.Tags". This change works with at least GNAT 
3.15p and ObjectAda 7.2.2.

Cheers

-- Martin





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

* Re: This can't be done in Ada...or?
  2005-02-15  9:09               ` Jacob Sparre Andersen
  2005-02-15  9:31                 ` Mark Lorenzen
@ 2005-02-15 13:41                 ` Robert A Duff
  2005-02-15 16:30                   ` Per Lindquist
  2005-02-17 21:52                   ` Simon Wright
  1 sibling, 2 replies; 48+ messages in thread
From: Robert A Duff @ 2005-02-15 13:41 UTC (permalink / raw)


Jacob Sparre Andersen <sparre@nbi.dk> writes:

> Mark Lorenzen wrote:
> > "Per Lindquist" <commander@death-star.com> writes:
> 
> > > One of our target environments is a time-critical real-time
> > > system. We are worried about the execution overhead implied by a
> > > package instantiation (or any 'new' statement) in every subprogram
> > > in the system.
> > > 
> > > Will your solution cause overhead for each subprogram call?

Probably.

> > A compile-time instantiation of a package has nothing to do with
> > run-time efficiency. You can also define a new type in a subprogram,
> > which doesn't affect run-time efficiency either.
> 
> Aren't the compilers (theoretically) allowed to delay the
> instantiation of the packgage until run-time?

No, instantiation is a compile-time concept.  I'm not sure what
it would mean to delay it until run time.

The issue here is the cost of running the elaboration code of the
instance.  Theoretically, the compiler could optimize it away in this
case, but I don't think any Ada compilers are that smart.  The only
way to know for sure is to try it.

This Reflection package has a bunch of string manipulation code,
and if you instantiate it in a procedure, it will happen
every time that procedure is called (unless the compiler
is smarter than I think it is).  This could indeed be very
costly.

- Bob



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

* Re: This can't be done in Ada...or?
  2005-02-15  9:31                 ` Mark Lorenzen
  2005-02-15  9:48                   ` Jacob Sparre Andersen
  2005-02-15 10:15                   ` Martin Dowie
@ 2005-02-15 13:46                   ` Robert A Duff
  2 siblings, 0 replies; 48+ messages in thread
From: Robert A Duff @ 2005-02-15 13:46 UTC (permalink / raw)


Mark Lorenzen <mark.lorenzen@ofir.dk> writes:

>...But if the generic package body does not need to be
> elaborated, there will probably not be any overhead.

This generic package doesn't even *have* a body!
The code in question is the code to elaborate
the spec of the instance.

- Bob



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

* Re: This can't be done in Ada...or?
  2005-02-15 13:41                 ` Robert A Duff
@ 2005-02-15 16:30                   ` Per Lindquist
  2005-02-15 19:38                     ` Martin Dowie
  2005-02-15 20:20                     ` Robert A Duff
  2005-02-17 21:52                   ` Simon Wright
  1 sibling, 2 replies; 48+ messages in thread
From: Per Lindquist @ 2005-02-15 16:30 UTC (permalink / raw)


Robert A Duff wrote:
> No, instantiation is a compile-time concept.  I'm not sure what
> it would mean to delay it until run time.
>
> The issue here is the cost of running the elaboration code of the
> instance.  Theoretically, the compiler could optimize it away in this
> case, but I don't think any Ada compilers are that smart.  The only
> way to know for sure is to try it.
>
> This Reflection package has a bunch of string manipulation code,
> and if you instantiate it in a procedure, it will happen
> every time that procedure is called (unless the compiler
> is smarter than I think it is).  This could indeed be very
> costly.

I can now confirm that the Reflection package, in our case, indeed
causes considerable overhead compared to hardcoded constants.

The test consisted of 1_000_000 calls to procedure Q in either package
P1 or P2:

package body P1 is
  procedure Q is
    package Reflect is new PragmARC.Reflection;
  begin
    Dummy := Dummy + 1;
  end;
end P1;

package body P2 is
  procedure Q is
    Subprogram_Name : constant String := "Q";
  begin
    Dummy := Dummy + 1;
  end;
end P2;

(I'm aware that Reflect.Unit_Name is longer ("P1.Q") than
Subprogram_NAme ("Q") but this test is relevant in our case.)

I tested on a Sun (Solaris) machine using the GNAT compiler and on a
PowerPC (Integrity) using GreenHill's Ada compiler.

There was really no need for an accurate time measurement since the
difference was large on both platforms. The constant test finished
immediately and the Reflection test took several seconds.

Optimization flags (GNAT only) didn't do much difference.

So although PragmARC.Reflection offers very nice features we cannot use
it in our particular system.

Thanks for your help!

/PerL




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

* Re: This can't be done in Ada...or?
  2005-02-15 16:30                   ` Per Lindquist
@ 2005-02-15 19:38                     ` Martin Dowie
  2005-02-15 20:20                     ` Robert A Duff
  1 sibling, 0 replies; 48+ messages in thread
From: Martin Dowie @ 2005-02-15 19:38 UTC (permalink / raw)


Per Lindquist wrote:
> Optimization flags (GNAT only) didn't do much difference.
> 
> So although PragmARC.Reflection offers very nice features we cannot use
> it in our particular system.

Similar results for ObjectAda, over 1,000,000 iterations:

PragmARC:  1.9216 seconds
Constants: 0.0048 seconds

Cheers

-- Martin



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

* Re: This can't be done in Ada...or?
  2005-02-15 16:30                   ` Per Lindquist
  2005-02-15 19:38                     ` Martin Dowie
@ 2005-02-15 20:20                     ` Robert A Duff
  1 sibling, 0 replies; 48+ messages in thread
From: Robert A Duff @ 2005-02-15 20:20 UTC (permalink / raw)


"Per Lindquist" <commander@death-star.com> writes:

> So although PragmARC.Reflection offers very nice features we cannot use
> it in our particular system.

You could probably use it in library packages.
It's just inside subprograms where the overhead
is so large.

- Bob



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

* Re: This can't be done in Ada...or?
  2005-02-15  8:27           ` This can't be done in Ada...or? Per Lindquist
  2005-02-14 22:10             ` Manuel G. R.
  2005-02-15  8:47             ` Mark Lorenzen
@ 2005-02-16  0:04             ` Jeffrey Carter
  2005-02-16  0:09             ` Jeffrey Carter
  3 siblings, 0 replies; 48+ messages in thread
From: Jeffrey Carter @ 2005-02-16  0:04 UTC (permalink / raw)


Per Lindquist wrote:
> Jeffrey Carter wrote:
> 
>>   procedure Q is
>>      package That is new PragmARC.Reflection;
> 
> 
> Hm, I was so excited about your solution I didn't notice the potential
> problem with overhead, but a collegue of mine did:
> 
> One of our target environments is a time-critical real-time system. We
> are worried about the execution overhead implied by a package
> instantiation (or any 'new' statement) in every subprogram in the
> system.
> 
> Will your solution cause overhead for each subprogram call?

It will definitely cause overhead, as I see you've discovered. There's a 
call to Expanded_Name, 2 to Index, and another to Mixed_Case. This 
component is certainly not suitable for systems with critical timing 
requirements.

There may also be overhead in terms of the amount of storage used. The 
package declares a number of constant Strings, and I doubt if we can 
rely on a compiler to discard them (although inside a subprogram, they 
should go away when the subprogram returns).

You can eliminate the call to Mixed_Case, if you don't mind what the 
result looks like, and one of the calls to Index (it will always return 
'Last - 1), and possibly the call to Expanded_Name, if your compilers 
have 'External_Tag returning the same thing and you're willing to have 
that compiler dependency in your code (though 'External_Tag probably has 
similar overhead to Expanded_Name in that case). That still leaves a 
call to Index.

This is really only a problem in subprograms, where the package is 
elaborated every time the subprogram is called. In packages and other 
things where the elaboration will only occur once, it may be acceptable 
overhead.

-- 
Jeff Carter
"C++ is like jamming a helicopter inside a Mata
and expecting some sort of improvement."
Drew Olbrich
51



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

* Re: This can't be done in Ada...or?
  2005-02-15  8:27           ` This can't be done in Ada...or? Per Lindquist
                               ` (2 preceding siblings ...)
  2005-02-16  0:04             ` Jeffrey Carter
@ 2005-02-16  0:09             ` Jeffrey Carter
  2005-02-17  9:47               ` Per Lindquist
  2005-02-17 22:36               ` Randy Brukardt
  3 siblings, 2 replies; 48+ messages in thread
From: Jeffrey Carter @ 2005-02-16  0:09 UTC (permalink / raw)


Per Lindquist wrote:
> Jeffrey Carter wrote:
> 
>>   procedure Q is
>>      package That is new PragmARC.Reflection;
> 
> 
> Hm, I was so excited about your solution I didn't notice the potential
> problem with overhead, but a collegue of mine did:
> 
> One of our target environments is a time-critical real-time system. We
> are worried about the execution overhead implied by a package
> instantiation (or any 'new' statement) in every subprogram in the
> system.
> 
> Will your solution cause overhead for each subprogram call?

It will definitely cause overhead, as I see you've discovered. There's a 
call to Expanded_Name, 2 to Index, and another to Mixed_Case. This 
component is certainly not suitable for systems with critical timing 
requirements.

There may also be overhead in terms of the amount of storage used. The 
package declares a number of constant Strings, and I doubt if we can 
rely on a compiler to discard them (although inside a subprogram, they 
should go away when the subprogram returns).

You can eliminate the call to Mixed_Case, if you don't mind what the 
result looks like, and one of the calls to Index (it will always return 
'Last - 1), and possibly the call to Expanded_Name, if your compilers 
have 'External_Tag returning the same thing and you're willing to have 
that compiler dependency in your code (though 'External_Tag probably has 
similar overhead to Expanded_Name in that case). That still leaves a 
call to Index. You could eliminate that if you always name your 
instantiations the same thing and don't mind that extra name on the end.

This is really only a problem in subprograms, where the package is 
elaborated every time the subprogram is called. In packages and other 
things where the elaboration will only occur once, it may be acceptable 
overhead.

It's too late now, but this might have been a good thing to suggest for 
Ada 0X. Compilers already have to have this information available, or 
PragmARC.Reflection wouldn't work. We should be able to get at it 
without all this overhead.

Finally, if you only need the name in exceptional circumstances (error 
logging or the like), I could make Unit_Name a function. Then you'd only 
have the overhead when you actually use the name.

-- 
Jeff Carter
"C++ is like jamming a helicopter inside a Miata
and expecting some sort of improvement."
Drew Olbrich
51



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

* Re: This can't be done in Ada...or?
  2005-02-16  0:09             ` Jeffrey Carter
@ 2005-02-17  9:47               ` Per Lindquist
  2005-02-17 22:36               ` Randy Brukardt
  1 sibling, 0 replies; 48+ messages in thread
From: Per Lindquist @ 2005-02-17  9:47 UTC (permalink / raw)


Jeffrey Carter wrote:
> It's too late now, but this might have been a good thing to suggest
for
> Ada 0X. Compilers already have to have this information available, or

> PragmARC.Reflection wouldn't work. We should be able to get at it
> without all this overhead.

Seems reasonable.

> Finally, if you only need the name in exceptional circumstances
(error
> logging or the like), I could make Unit_Name a function. Then you'd
only
> have the overhead when you actually use the name.

We have concluded that we probably will log more than just fatal errors
so I think we're stuck with those hardcoded constants after all.

Thanks for your offer anyway. It's a good idea. 

/PerL




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

* Re: This can't be done in Ada...or?
  2005-02-15 13:41                 ` Robert A Duff
  2005-02-15 16:30                   ` Per Lindquist
@ 2005-02-17 21:52                   ` Simon Wright
  1 sibling, 0 replies; 48+ messages in thread
From: Simon Wright @ 2005-02-17 21:52 UTC (permalink / raw)


Robert A Duff <bobduff@shell01.TheWorld.com> writes:

> This Reflection package has a bunch of string manipulation code,
> and if you instantiate it in a procedure, it will happen
> every time that procedure is called (unless the compiler
> is smarter than I think it is).  This could indeed be very
> costly.

The output of

   with Ada.Text_IO; use Ada.Text_IO;
   with BC.Support.High_Resolution_Time;
   with PragmaRC.Reflection;

   procedure Refl is

      use type BC.Support.High_Resolution_Time.Time;

      Start, Finish : BC.Support.High_Resolution_Time.Time;

   begin

      Start := BC.Support.High_Resolution_Time.Clock;

      declare
         package R is new PragmaRC.Reflection;
      begin
         null;
      end;

      Finish := BC.Support.High_Resolution_Time.Clock;

      Put_Line ("took " & Duration'Image (Finish - Start));

   end Refl;
 
here (gnatmake -O2, gnat 5.02a1 i686-pc-linux-gnu) is

   smaug.pushface.org[13]$ ./refl
   Clock rate is 0.400914522 GHz
   took  0.000023852

-- 
Simon Wright                               100% Ada, no bugs.



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

* Re: This can't be done in Ada...or?
  2005-02-15  8:47             ` Mark Lorenzen
  2005-02-15  9:09               ` Jacob Sparre Andersen
@ 2005-02-17 22:06               ` Randy Brukardt
  2005-02-17 22:40                 ` Mark Lorenzen
  1 sibling, 1 reply; 48+ messages in thread
From: Randy Brukardt @ 2005-02-17 22:06 UTC (permalink / raw)


"Mark Lorenzen" <mark.lorenzen@ofir.dk> wrote in message
news:m3wttaciqw.fsf@0x53586c67.boanxx18.adsl-dhcp.tele.dk...
> "Per Lindquist" <commander@death-star.com> writes:
...
> > Will your solution cause overhead for each subprogram call?
>
> A compile-time instantiation of a package has nothing to do with
> run-time efficiency. You can also define a new type in a subprogram,
> which doesn't affect run-time efficiency either.

That's sometimes true, but never on a compiler that code shared generics by
default (like Janus/Ada). And even on compilers that treat generics as
macros, it depends on the elaboration overhead. So it is a mistake to give
that as a general rule. Similarly, a type declared in a subprogram might or
might not have run-time overhead (it depends on what the elaboration of the
type does - if it depends on a parameter, for instance, there almost
certainly is some overhead).

Not having the code for the generic in question (I couldn't find any easy
way to see it on the PragmaARC site, and I didn't want to download the whole
thing), I can't say what overhead it has. Clearly there is some size
overhead, but that might not be much more than the size overhead of the
explicit constants.

Personally, I'd stick with the constants, because they can be tailored to
disambiguate overloaded subprograms, and there is no possibility of
overhead. But YMMV.

                   Randy Brukardt.

P.S. I don't find the "if" statements surrounding the tracing particularly
"yucky". Unless your system is rather small, you'll need a way to control
what is traced, and that can be combined into the if statement with no
overhead when the traces are all off. One way is to use an extra constant:

    if (not Tracing.No_Logging) and then Tracing.Log_This (Where => ...)
then
        Tracing.Log_Item (Where => ..., Item => "This is a log entry.");
    end if;

We use variations on this in the Janus/Ada compiler, the AdaIC web server,
the Trash Finder spam filter, and other tools. (Claw doesn't have any
built-in tracing; it's too intrusive.)

If you only need a variable to control tracing, you can change that to a
constant to get rid of all of the overhead and use if statements with a
single item:

    if Tracing.Log_Me then
       ...

This solution requires a bit more version control (which is outside of Ada,
of course), but it isn't bad.

                RLB






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

* Re: This can't be done in Ada...or?
  2005-02-15 10:15                   ` Martin Dowie
@ 2005-02-17 22:09                     ` Randy Brukardt
  2005-02-18  6:53                       ` Martin Dowie
  0 siblings, 1 reply; 48+ messages in thread
From: Randy Brukardt @ 2005-02-17 22:09 UTC (permalink / raw)


"Martin Dowie" <martin.dowie@btopenworld.com> wrote in message
news:cusi3o$af8$1@hercules.btinternet.com...
...
> Another change you could make that might make a difference is to change:
>
>     Name : constant String := Expanded_Name (T'Tag);
>
> to:
>
>     Name : constant String := T'External_Tag;
>
> That way you can make PragmARC.Reflection "pragma Preelaborate" and not
> have any dependency on "Ada.Tags". This change works with at least GNAT
> 3.15p and ObjectAda 7.2.2.

External_Tag can be specified (and thus changed); Expanded_Name cannot.

In any case, Ada.Tags is Preelaborated in Ada 2005, so this is not
necessary. (Everyone should start using Ada 2005, immediately, right? :-)

                    Randy Brukardt.







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

* Re: This can't be done in Ada...or?
  2005-02-16  0:09             ` Jeffrey Carter
  2005-02-17  9:47               ` Per Lindquist
@ 2005-02-17 22:36               ` Randy Brukardt
  1 sibling, 0 replies; 48+ messages in thread
From: Randy Brukardt @ 2005-02-17 22:36 UTC (permalink / raw)



"Jeffrey Carter" <spam@spam.com> wrote in message
news:1bwQd.1171$kU3.57@newsread1.news.pas.earthlink.net...
...
> It's too late now, but this might have been a good thing to suggest for
> Ada 0X. Compilers already have to have this information available, or
> PragmARC.Reflection wouldn't work. We should be able to get at it
> without all this overhead.

It was suggested, as someone else noted. AI-282 was the result. It failed to
go anywhere for a variety of reasons: there was no champion on the ARG (no
one that wanted it badly enough to do the work needed); the proposal was too
magic for the tastes of many members; at least one major compiler uses
incremental compilation that would be destroyed by access to line numbers
(which could change without any other significant change), so they opposed
the package; exactly what the full subprogram name would be in a generic is
unclear (the instance name or the template name?); we don't like code that
changes its meaning if it is moved, and so on.

I personally don't feel strongly, but I think it's unnecessary. And there
would be a lot of space overhead whenever it is used (maybe that's not as
important anymore, but Janus/Ada at least was designed around space
minimization). Usually there is something better to report than the name of
a subprogram. (I may be spoiled by the exception walkbacks built into the
Janus/Ada runtime, which provides the information only when you actually
need it -- to debug an unexpected exception.)

One alternative to a lot of constants, especially for the package names, is
to declare an enumeration type in your tracing package. For instance, from
the Janus/Ada compiler:

    package J2Trace is
      type Unit_Names is (J2Type_Decs, J2CodeGen, J2Resolution,
J2Symbol_Table,...);
      function Trace_Unit (Unit : in Unit_Names) return Boolean;
      procedure Elaboration_Trace (Unit : in Unit_Names);
      ...
   end J2Trace;

Passing an enumeration has less overhead than passing a string (because
there is no need to construct and pass the bounds), you can make sure that
the names are spelled consistently, you can use the names for tracing
control (as above with function Trace_Unit), and you can use
Unit_Names'Image to display the unit when you need it. The main downside is
that you have to update the tracing package when a new unit is added to the
program, but that usually is a rare event.

                 Randy Brukardt







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

* Re: This can't be done in Ada...or?
  2005-02-17 22:06               ` Randy Brukardt
@ 2005-02-17 22:40                 ` Mark Lorenzen
  0 siblings, 0 replies; 48+ messages in thread
From: Mark Lorenzen @ 2005-02-17 22:40 UTC (permalink / raw)


"Randy Brukardt" <randy@rrsoftware.com> writes:

> "Mark Lorenzen" <mark.lorenzen@ofir.dk> wrote in message
> news:m3wttaciqw.fsf@0x53586c67.boanxx18.adsl-dhcp.tele.dk...
> > "Per Lindquist" <commander@death-star.com> writes:
> ...
> > > Will your solution cause overhead for each subprogram call?
> >
> > A compile-time instantiation of a package has nothing to do with
> > run-time efficiency. You can also define a new type in a subprogram,
> > which doesn't affect run-time efficiency either.
> 
> That's sometimes true, but never on a compiler that code shared generics by
> default (like Janus/Ada). And even on compilers that treat generics as
> macros, it depends on the elaboration overhead. So it is a mistake to give
> that as a general rule. Similarly, a type declared in a subprogram might or
> might not have run-time overhead (it depends on what the elaboration of the
> type does - if it depends on a parameter, for instance, there almost
> certainly is some overhead).

Yes, I made a boo-boo. I thought about the elaboration problem _after_
I made the posting.

[snip]

- Mark Lorenzen



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

* Re: This can't be done in Ada...or?
  2005-02-17 22:09                     ` Randy Brukardt
@ 2005-02-18  6:53                       ` Martin Dowie
  0 siblings, 0 replies; 48+ messages in thread
From: Martin Dowie @ 2005-02-18  6:53 UTC (permalink / raw)


Randy Brukardt wrote:
> "Martin Dowie" <martin.dowie@btopenworld.com> wrote in message
> news:cusi3o$af8$1@hercules.btinternet.com...
> ...
> 
>>Another change you could make that might make a difference is to change:
>>
>>    Name : constant String := Expanded_Name (T'Tag);
>>
>>to:
>>
>>    Name : constant String := T'External_Tag;
>>
>>That way you can make PragmARC.Reflection "pragma Preelaborate" and not
>>have any dependency on "Ada.Tags". This change works with at least GNAT
>>3.15p and ObjectAda 7.2.2.
> 
> 
> External_Tag can be specified (and thus changed); Expanded_Name cannot.
> 
> In any case, Ada.Tags is Preelaborated in Ada 2005, so this is not
> necessary. (Everyone should start using Ada 2005, immediately, right? :-)

Send me Janus/Ada2005 and I'll start on Monday! ;-)

Cheers

-- Martin



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

end of thread, other threads:[~2005-02-18  6:53 UTC | newest]

Thread overview: 48+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-02-11 16:33 This can't be done in Ada...or? Per Lindquist
2005-02-11 16:51 ` Duncan Sands
2005-02-12 19:55   ` Florian Weimer
2005-02-14  8:34     ` Per Lindquist
2005-02-14  8:17   ` Per Lindquist
2005-02-11 17:02 ` Jeff C
2005-02-11 18:27   ` Robert A Duff
2005-02-11 23:51     ` Ludovic Brenta
2005-02-11 23:52       ` Robert A Duff
2005-02-12 13:55     ` Duncan Sands
2005-02-12 14:58       ` Martin Krischik
2005-02-12 15:56         ` Martin Dowie
2005-02-12 19:02       ` Robert A Duff
2005-02-14  8:49     ` Per Lindquist
2005-02-11 17:08 ` Jerome Hugues
2005-02-14  9:05   ` Per Lindquist
2005-02-14 13:07     ` Georg Bauhaus
2005-02-12  1:10 ` Jeffrey Carter
2005-02-12 14:01   ` Duncan Sands
2005-02-13  0:27     ` Jeffrey Carter
2005-02-14  9:10       ` Per Lindquist
2005-02-15  0:40         ` Jeffrey Carter
2005-02-15  7:40           ` Per Lindquist
2005-02-15  8:39             ` OT: Google reply (Was: Re: This can't be done in Ada...or?) Adrien Plisson
2005-02-15  9:42               ` Per Lindquist
2005-02-15  8:27           ` This can't be done in Ada...or? Per Lindquist
2005-02-14 22:10             ` Manuel G. R.
2005-02-15  8:47             ` Mark Lorenzen
2005-02-15  9:09               ` Jacob Sparre Andersen
2005-02-15  9:31                 ` Mark Lorenzen
2005-02-15  9:48                   ` Jacob Sparre Andersen
2005-02-15 10:07                     ` Mark Lorenzen
2005-02-15 10:15                   ` Martin Dowie
2005-02-17 22:09                     ` Randy Brukardt
2005-02-18  6:53                       ` Martin Dowie
2005-02-15 13:46                   ` Robert A Duff
2005-02-15 13:41                 ` Robert A Duff
2005-02-15 16:30                   ` Per Lindquist
2005-02-15 19:38                     ` Martin Dowie
2005-02-15 20:20                     ` Robert A Duff
2005-02-17 21:52                   ` Simon Wright
2005-02-17 22:06               ` Randy Brukardt
2005-02-17 22:40                 ` Mark Lorenzen
2005-02-16  0:04             ` Jeffrey Carter
2005-02-16  0:09             ` Jeffrey Carter
2005-02-17  9:47               ` Per Lindquist
2005-02-17 22:36               ` Randy Brukardt
2005-02-14 15:21 ` Peter Amey

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