Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Problem where a function is invoked once but called twice (when invocation is within an allocator).

30 views
Skip to first unread message

Rod Kay

unread,
May 4, 2011, 11:52:06 PM5/4/11
to
hi,

Any clues on why the use of an allocator would cause a single
function invocation to be called twice ?


the_Movie : media.Video.view := new_Movie;

the_next_Frame : openGL.Image :=
the_Movie.next_Frame; -- case 1
the_next_Frame : access openGL.Image := new
opengl.Image' (the_Movie.next_Frame); -- case 2

In the 1st case, the 'next_Frame' function is called once.
In the 2nd case, it is called twice.


'the_Movie' is an access to an object of tagged type
'media.Video.item'.

package media.Video is
type Item is tagged limited private;
type View is access all Item;
...
function next_Frame (Self : access Item) return opengl.Image;
...
end media.Video;

'opengl.Image' is an array with two unconstrained indices ...

package openGL is
...
type Image is array (Index_t range <>, Index_t range <>) of
Color;
end openGL;

In case it matters, the 'next_Frame' function contains a rendezvous
with a decoder task.
The decoder task is a component of the 'media.Video.item' record.

regards,
Rod.

J-P. Rosen

unread,
May 5, 2011, 1:43:08 AM5/5/11
to
Le 05/05/2011 05:52, Rod Kay a écrit :
> Any clues on why the use of an allocator would cause a single
> function invocation to be called twice ?
>
>
> the_Movie : media.Video.view := new_Movie;
>
> the_next_Frame : openGL.Image :=
> the_Movie.next_Frame; -- case 1
> the_next_Frame : access openGL.Image := new
> opengl.Image' (the_Movie.next_Frame); -- case 2
>
> In the 1st case, the 'next_Frame' function is called once.
> In the 2nd case, it is called twice.
>

Wouldn't Image be controlled by any chance? In that case, the assignment
may involve the creation of an intermediate object
--
---------------------------------------------------------
J-P. Rosen (ro...@adalog.fr)
Adalog a déménagé / Adalog has moved:
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00

Rod Kay

unread,
May 5, 2011, 2:12:08 AM5/5/11
to
On May 5, 3:43 pm, "J-P. Rosen" <ro...@adalog.fr> wrote:
>
> Wouldn't Image be controlled by any chance? In that case, the assignment
> may involve the creation of an intermediate object

Not in this case, no.

'opengl.Image' is fairly simple array type with 2 unconstrained
indices ...

Yannick Duchêne (Hibou57)

unread,
May 5, 2011, 4:22:38 AM5/5/11
to
Le Thu, 05 May 2011 07:43:08 +0200, J-P. Rosen <ro...@adalog.fr> a écrit:
> Wouldn't Image be controlled by any chance? In that case, the assignment
> may involve the creation of an intermediate object
Even if this was, this would not be a reason for “the_Movie.next_Frame” to
be invoked twice.

Rod, may be you should have a look at the produced assembly ? and post an
excerpt here

--
Si les chats miaulent et font autant de vocalises bizarres, c’est pas pour
les chiens.
“ c++; /* this makes c bigger but returns the old value */ ” [Anonymous]

Rod Kay

unread,
May 5, 2011, 6:59:12 AM5/5/11
to
On May 5, 6:22 pm, Yannick Duchêne (Hibou57)

<yannick_duch...@yahoo.fr> wrote:
>
> Rod, may be you should have a look at the produced assembly ? and post an  
> excerpt here

A good idea.

I created a small test program ...


with media.Video;
with openGL;

procedure Tester
is
the_Movie : media.Video.view := media.Video.new_Video ("xyz.avi");

Case_1 : openGL.Image := the_Movie.next_Frame;
Case_2 : access openGL.Image := new
opengl.Image' (the_Movie.next_Frame);
begin
null;
end;


... and generated the mixed ada/asm, which is here:
http://109.74.196.91:8080/doubled_next_Frame_call_results.txt


In brief, the mixed ada/asm shows next_Frame being called twice for
Case_2 ...


**** Case_2 : access openGL.Image := new
opengl.Image' (the_Movie.next_Frame);
...
call media__video__next_frame
...
call __gnat_malloc
...
call media__video__next_frame
...
call memcpy

Hope this helps.

regards.

Florian Weimer

unread,
May 5, 2011, 1:07:25 PM5/5/11
to
* Rod Kay:

> ... and generated the mixed ada/asm, which is here:
> http://109.74.196.91:8080/doubled_next_Frame_call_results.txt

Could you show the -gnatG output as well?

Rod Kay

unread,
May 5, 2011, 8:49:56 PM5/5/11
to
On May 6, 3:07 am, Florian Weimer <f...@deneb.enyo.de> wrote:
>
> Could you show the -gnatG output as well?

Source recreated from tree for Tester (body)
--------------------------------------------

with media;
with media.media__video;
with opengl;
with ada.ada__tags;
with system.system__secondary_stack;

procedure tester is
M13b : system__secondary_stack__mark_id :=
$system__secondary_stack__ss_mark;

procedure tester___clean is
begin
$system__secondary_stack__ss_release (M13b);
return;
end tester___clean;
begin
the_movie : media.media__video.media__video__view := media.
media__video.media__video__new_video__2 ("xyz.avi");
[constraint_error when
the_movie = null
"access check failed"]

-- Case 1 begins here ...
type tester__A3b is access all opengl__image;
R4b : constant tester__A3b := media__video__next_frame (the_movie,
selfL => 0)'reference;
subtype tester__Tcase_1S is opengl__image (R4b.all'first(1) ..
R4b.all'
last(1), R4b.all'first(2) .. R4b.all'last(2));
[constraint_error when
R4b.all'last(2) >= R4b.all'first(2) and then (R4b.all'first(2) <
0 or else R4b.all'last(2) > 65535)
"range check failed"]
[constraint_error when
R4b.all'last(1) >= R4b.all'first(1) and then (R4b.all'first(1) <
0 or else R4b.all'last(1) > 65535)
"range check failed"]
case_1 : opengl__image (R4b.all'first(1) .. R4b.all'last(1),
R4b.all'
first(2) .. R4b.all'last(2)) := R4b.all;

-- Case 2 begins here ...
type tester__A10b is access all opengl__image;
R11b : constant tester__A10b := (media__video__next_frame
(the_movie,
selfL => 0))'reference;
subtype tester__A9b is opengl__image ((R11b.all)'first(1) ..
(R11b.all)'
last(1), (R11b.all)'first(2) .. (R11b.all)'last(2));
[constraint_error when
(R11b.all)'last(2) >= (R11b.all)'first(2) and then ((R11b.all)'
first(2) < 0 or else (R11b.all)'last(2) > 65535)
"range check failed"]
[constraint_error when
(R11b.all)'last(1) >= (R11b.all)'first(1) and then ((R11b.all)'
first(1) < 0 or else (R11b.all)'last(1) > 65535)
"range check failed"]
case_2 : access opengl.opengl__image := new opengl.opengl__image'(
tester__A9b?((media__video__next_frame (the_movie, selfL =>
0))));
[subtype tester__T6b is access opengl__image]
reference tester__T6b
null;
return;
at end
tester___clean;
end tester;

For Case_2, it appears the 1st call to next_Frame is used purely to
get the bounds of the returned array. The bounds are then used to
define 'tester__A9b' which is a subtype of opengl.Image of the correct
size. 'tester__A9b' is then used to convert the result of the 2nd call
to next_Frame, during allocation.

Anh Vo

unread,
May 6, 2011, 7:41:44 PM5/6/11
to

What compiler do you use? Do you mind to post the complete (minimum
required) source. I would like to see if I get the same result on my
machine.

Anh Vo

Rod Kay

unread,
May 6, 2011, 9:38:45 PM5/6/11
to
On May 7, 9:41 am, Anh Vo <anhvofrc...@gmail.com> wrote:
>
> What compiler do you use? Do you mind to post the complete (minimum
> required) source. I would like to see if I get the same result on my
> machine.
>
> Anh Vo


I'm using the GPL10 edition of Gnat on Ubuntu 10.04 (32bit).

Here's a tarball of the testcase ... http://109.74.196.91:8080/double_next_frame_call.tar.gz

You may need to install ffmpeg development packages (libavutil-dev,
libswscale-dev, libavcodec-dev, libavformat-dev on debian/ubuntu).

Also, it should be built with gprbuild.

Georg Bauhaus

unread,
May 7, 2011, 5:06:03 AM5/7/11
to
On 5/7/11 3:38 AM, Rod Kay wrote:

> I'm using the GPL10 edition of Gnat on Ubuntu 10.04 (32bit).
>
> Here's a tarball of the testcase ... http://109.74.196.91:8080/double_next_frame_call.tar.gz
>
> You may need to install ffmpeg development packages (libavutil-dev,
> libswscale-dev, libavcodec-dev, libavformat-dev on debian/ubuntu).
>
> Also, it should be built with gprbuild.

First, I can confirm that on Mac OS X the assembly listing
of tester shows three calls, too:

$ grep _media__video__next_frame build/tester.s
call _media__video__next_frame
call _media__video__next_frame
call _media__video__next_frame
$

(I've had to make a few changes to c_media due to recent
changes in ffmpeg, viz. definitions CODEC_TYPE_VIDEO and
others seem to have been replaced with AVMEDIA_TYPE_VIDEO
and others; avcodec_decode_video2 is new for
avcodec_decode_video. Just grabbed patches from ffmpeg
clients from the net, I don't understand them.)

The following appears to be generating two calls only, FWIW:

the_Movie : media.Video.view := media.Video.new_Video ("xyz.avi");

Case_1 : openGL.Image := the_Movie.next_Frame;
Workaround : openGL.Image renames The_Movie.Next_Frame;
Case_2 : access openGL.Image := new opengl.Image' (Workaround);

$ grep _media__video__next_frame build/tester.s
call _media__video__next_frame
call _media__video__next_frame
$

Rod Kay

unread,
May 7, 2011, 5:45:46 AM5/7/11
to
On May 7, 7:06 pm, Georg Bauhaus <rm.dash-bauh...@futureapps.de>
wrote:

>
> First, I can confirm that on Mac OS X the assembly listing
> of tester shows three calls, too:
>
> $ grep _media__video__next_frame build/tester.s
>         call    _media__video__next_frame
>         call    _media__video__next_frame
>         call    _media__video__next_frame
> $

Thanks for the info.


> The following appears to be generating two calls only, FWIW:
>
>     the_Movie : media.Video.view := media.Video.new_Video ("xyz.avi");
>
>     Case_1 :        openGL.Image := the_Movie.next_Frame;
>     Workaround :    openGL.Image renames The_Movie.Next_Frame;
>     Case_2 : access openGL.Image := new opengl.Image' (Workaround);
>

Heh, this is indeed how I ended up tackling the problem in the real
source :).

Anh Vo

unread,
May 9, 2011, 12:01:12 PM5/9/11
to
On May 6, 6:38 pm, Rod Kay <rod....@aulace.com> wrote:
> On May 7, 9:41 am, Anh Vo <anhvofrc...@gmail.com> wrote:
>
>
>
> > What compiler do you use? Do you mind to post the complete (minimum
> > required) source. I would like to see if I get the same result on my
> > machine.
>
> > Anh Vo
>
>    I'm using the GPL10 edition of Gnat on Ubuntu 10.04 (32bit).
>
>    Here's a tarball of the testcase ...http://109.74.196.91:8080/double_next_frame_call.tar.gz

>
>    You may need to install ffmpeg development packages (libavutil-dev,
> libswscale-dev, libavcodec-dev, libavformat-dev on debian/ubuntu).
>
>    Also, it should be built with gprbuild.

Thank you for posting the code. However, I had problem to download
this tar file. Any one else had problem as I did?

Anh Vo

Dan

unread,
May 9, 2011, 7:00:14 PM5/9/11
to
Here's a simpler test case. Taking out the Pragma Pack makes it work.

package Media is

type Color is
record
val : integer;
end record;

type Image is array (integer range <>) of Color;
pragma pack (Image); -- matters!

function next_Frame return Image;

end Media;

with Ada.Text_IO; use Ada.Text_IO;
package body Media is
counter: integer := 0;

function next_Frame return Image is
begin
put_line("in next_frame");
counter := counter + 1;
return (1..10 => (val => counter));
end next_Frame;

end Media;

with Media;
with text_io;
procedure Test1 is

Case_1 : Media.Image := Media.Image' (Media.next_Frame);
Case_2 : access Media.Image := new Media.Image' (Media.next_Frame);
begin
text_io.put_line(case_1(5).val'img);
text_io.put_line(case_2(5).val'img);
end;

Anh Vo

unread,
May 9, 2011, 8:14:07 PM5/9/11
to

Thank you for making the simplest test case.

I got double calls, too. It is absolutely a compiler bug.

Anh Vo

Rod Kay

unread,
May 9, 2011, 8:21:22 PM5/9/11
to
On May 10, 9:00 am, Dan <d...@irvine.com> wrote:
> Here's a simpler test case.  Taking out the Pragma Pack makes it work.
>

Ah, very nice, thank you.

Yes, I also 'pragma pack' the openGL.Image type.

Rod Kay

unread,
May 9, 2011, 8:24:10 PM5/9/11
to
On May 10, 10:14 am, Anh Vo <anhvofrc...@gmail.com> wrote:
>
> I got double calls, too. It is absolutely a compiler bug.
>

Yes, I suppose it must be. It will be interesting to try it again
when GPL11 arrives.

Anh Vo

unread,
May 9, 2011, 8:55:44 PM5/9/11
to

Have you sent a bug report yet? I hope you did if you want to see it
fix in GNAT-GPL-2011.

Dan

unread,
May 11, 2011, 1:23:28 PM5/11/11
to
Here's a version of the test case that fails in Ada83 mode.


package Media is

type Color is
record
val : integer;
end record;

type Image is array (integer range <>) of Color;
pragma pack (Image); -- matters!

function next_Frame return Image;

type Image_ptr is access Media.Image;

end Media;

with Text_IO; use Text_IO;


package body Media is
counter: integer := 0;

function next_Frame return Image is
begin
put_line("in next_frame");
counter := counter + 1;

return (1 .. 5-counter => (val => 10));
end next_Frame;

end Media;

with Media;
with text_io;
procedure Test2 is

Case_1 : Media.Image(1..4) := Media.Image' (Media.next_Frame);
Case_2 : Media.Image_ptr := new Media.Image' (Media.next_Frame);

procedure put(x: Media.Image) is
j: integer;
begin
for i in x'range loop
text_io.put_line(x(i).val'img);
j := 1/x(i).val; -- ensure val is not zero
end loop;
text_io.new_line;
end;

begin
put(case_1);
put(case_2.all);
end;

Rod Kay

unread,
May 12, 2011, 6:35:42 PM5/12/11
to
On May 10, 10:55 am, Anh Vo <anhvofrc...@gmail.com> wrote:
>
> Have you sent a bug report yet? I hope you did if you want to see it
> fix in GNAT-GPL-2011.

One has been sent now (thank you Jesse Lang).

And thanks to all who've replied and to Dan for taking the time to
simplify the test case.

Ludovic Brenta

unread,
May 13, 2011, 1:40:33 PM5/13/11
to
Rod Kay writes on comp.lang.ada:

> On May 10, 10:55 am, Anh Vo wrote:
>> Have you sent a bug report yet? I hope you did if you want to see it
>> fix in GNAT-GPL-2011.
>
> One has been sent now (thank you Jesse Lang).
>
> And thanks to all who've replied and to Dan for taking the time to
> simplify the test case.

I would like this bug report to be public in the GCC bugzilla database;
for multiple reasons, this is better than for the bug to remain private
in AdaCore's bug tracking system. Could someone take the time to file
it properly in Bugzilla?

--
Ludovic Brenta.

Rod Kay

unread,
May 13, 2011, 8:27:27 PM5/13/11
to
On May 14, 3:40 am, Ludovic Brenta <ludo...@ludovic-brenta.org> wrote:
>
> I would like this bug report to be public in the GCC bugzilla database;
> for multiple reasons, this is better than for the bug to remain private
> in AdaCore's bug tracking system.  Could someone take the time to file
> it properly in Bugzilla?
>

Submitted ... http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48995

regards.

0 new messages