comp.lang.ada
 help / color / mirror / Atom feed
* Interfacing between Ada and C: records and structs
@ 2012-07-31 16:38 awdorrin
  2012-07-31 17:16 ` Niklas Holsti
  0 siblings, 1 reply; 12+ messages in thread
From: awdorrin @ 2012-07-31 16:38 UTC (permalink / raw)


I have some legacy code that I am working with, they share common data structures.

Simplifying my code, In Ada, I have a record:

type FP_SHARED_BUF_TYPE is
record
  LOCK_SHM_1 : aliased Mutex;
  LOCK_SHM_2 : aliased Mutex;
  LOCK_SHM_3 : aliased Mutex;
end record;
pragma Convention(C,FP_SHARED_BUF_TYPE);

In C:

struct FP_SHARED_TYPE {
  pthread_mutex_t LOCK_SHM_1;
  pthread_mutex_t LOCK_SHM_2;
  pthread_mutex_t LOCK_SHM_3;
};

Now, the Mutex/pthread_mutex_t is 192bits, not 255bits, but when I compile the program.

The Ada code defines the record as:

for FP_SHARED_BUF_TYPE'Alignment use 9;
for FP_SHARED_BUF_TYPE use record
  LOCK_SHM_1 at - range  0 .. 255;
  LOCK_SHM_1 at - range 32 .. 255;
  LOCK_SHM_1 at - range 64 .. 255;
end record;

While the C code defines the structure elements as 192bits, and packs them right next to each other

Addresses of:
LOCK_SHM_1	0xF5650008
LOCK_SHM_2	0xF5650020
LOCK_SHM_3	0xF5650038

The only way I can get this to work, is to add padding to my C struct definition:

struct FP_SHARED_TYPE {
  pthread_mutex_t LOCK_SHM_1;
  int pad_for_m1[2];
  pthread_mutex_t LOCK_SHM_2;
  int pad_for_m2[2];
  pthread_mutex_t LOCK_SHM_3;
  int pad_for_m3[2];
};

Which, makes the C code really ugly.

Is there a way to make the Ada code pack the record?

I have been looking through the docs and haven't seen it yet.



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

* Re: Interfacing between Ada and C: records and structs
  2012-07-31 16:38 Interfacing between Ada and C: records and structs awdorrin
@ 2012-07-31 17:16 ` Niklas Holsti
  2012-07-31 18:44   ` awdorrin
  0 siblings, 1 reply; 12+ messages in thread
From: Niklas Holsti @ 2012-07-31 17:16 UTC (permalink / raw)


On 12-07-31 19:38 , awdorrin wrote:
> I have some legacy code that I am working with, they share common data structures.
> 
> Simplifying my code, In Ada, I have a record:
> 
> type FP_SHARED_BUF_TYPE is
> record
>   LOCK_SHM_1 : aliased Mutex;
>   LOCK_SHM_2 : aliased Mutex;
>   LOCK_SHM_3 : aliased Mutex;
> end record;
> pragma Convention(C,FP_SHARED_BUF_TYPE);
> 
> In C:
> 
> struct FP_SHARED_TYPE {
>   pthread_mutex_t LOCK_SHM_1;
>   pthread_mutex_t LOCK_SHM_2;
>   pthread_mutex_t LOCK_SHM_3;
> };
> 
> Now, the Mutex/pthread_mutex_t is 192bits, not 255bits, but when I compile the program.

How is pthread_mutex_t declared in Ada form? And in C form?

Have you checked that in Ada, pthread_mutex_t'Size is 192?

What is the storage unit of your target processor? 8 bits?

> The Ada code defines the record as:
> 
> for FP_SHARED_BUF_TYPE'Alignment use 9;

That is a strange alignment. Do you see any need for it? If not, try
removing it.

> for FP_SHARED_BUF_TYPE use record
>   LOCK_SHM_1 at - range  0 .. 255;
>   LOCK_SHM_1 at - range 32 .. 255;
>   LOCK_SHM_1 at - range 64 .. 255;
> end record;

Do you see any need for this representation clause? If not, remove it.
Or change it to use 192 bits per component.

(What are the "-" characters after the "at" keywords? Shouldn't it read
"at 0 range"?)

> While the C code defines the structure elements as 192bits, and packs them right next to each other
> 
> Addresses of:
> LOCK_SHM_1	0xF5650008
> LOCK_SHM_2	0xF5650020
> LOCK_SHM_3	0xF5650038
> 
> The only way I can get this to work, is to add padding to my C struct definition:
> 
> struct FP_SHARED_TYPE {
>   pthread_mutex_t LOCK_SHM_1;
>   int pad_for_m1[2];
>   pthread_mutex_t LOCK_SHM_2;
>   int pad_for_m2[2];
>   pthread_mutex_t LOCK_SHM_3;
>   int pad_for_m3[2];
> };
> 
> Which, makes the C code really ugly.
> 
> Is there a way to make the Ada code pack the record?

If your Ada code includes the record representation clause quoted above,
just remove it, or change it to specify 192 bits per component.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .



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

* Re: Interfacing between Ada and C: records and structs
  2012-07-31 17:16 ` Niklas Holsti
@ 2012-07-31 18:44   ` awdorrin
  2012-07-31 19:08     ` awdorrin
                       ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: awdorrin @ 2012-07-31 18:44 UTC (permalink / raw)


On Tuesday, July 31, 2012 1:16:10 PM UTC-4, Niklas Holsti wrote:
> 
> How is pthread_mutex_t declared in Ada form? And in C form?
> 

Digging into the POSIX module:

private
  type Dummy is tagged null record;
  type Mutex is record
    Mutex : aliased POSIX.C.pthread_mutex_t;
    D : Dummy;
  end record

> 
> Have you checked that in Ada, pthread_mutex_t'Size is 192?
> 

In the POSIX.C package:
ALIGNMENT : constant := Natural'Min(Standard'Maximum_Alignment, 8);
type pthread_mutex_t'Alignment use ALIGNMENT;
type pthread_mutex_t'Size use 192;

However, when I write a simple test program I get 256 bits from 'Size, I'm not sure why...
But that is probably the source of my problem.
 
> 
> What is the storage unit of your target processor? 8 bits?

The system is an Intel core2Duo E4600 - so a 64bit processor running x86_64 variant of Debian. (32-bit mode) So the storage unit is 8 bits.

> 
> That is a strange alignment. Do you see any need for it? If not, try
> removing it.

That was a typo on my part, should have read 'Alignment use 8;

> 
> Do you see any need for this representation clause? If not, remove it.
> 
> Or change it to use 192 bits per component.

That is the output from the -gnatR3 parameter, I don't have the rep spec defined in the code.

> 
> (What are the "-" characters after the "at" keywords? Shouldn't it read
> "at 0 range"?)

Sorry, that was apparently another typo on my part. (Cut and paste isn't working between my Linux VNC session and my desktop Windows PC)






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

* Re: Interfacing between Ada and C: records and structs
  2012-07-31 18:44   ` awdorrin
@ 2012-07-31 19:08     ` awdorrin
  2012-07-31 19:27       ` Simon Wright
  2012-07-31 19:23     ` Simon Wright
  2012-08-02  4:39     ` Shark8
  2 siblings, 1 reply; 12+ messages in thread
From: awdorrin @ 2012-07-31 19:08 UTC (permalink / raw)


I am wondering if the Dummy element in the Mutex record is not being treated as a null, but as a null pointer, adding 8 bytes to the record size.

I tried forcing the sizes to '192' in Ada by adding the rep spec and got the following error messages:

size for "LOCK_SHM_1" too small, minimum allowed is 224
position of aliased field "LOCK_SHM_1" must be multiple of 64 bits

So I'm guessing 192 (pthread_mutex_t) + 32 ( tagged null record) = 224 bits, rounded to 256 due to the address position requirement of an aliased field. (Still not sure I understand what a tagged or aliased field is, will have to read up on it.)

So, I guess this turns out to be more of a C question - on if I can pad/align the structs via compiler flags, or if I am better off sticking with manually adding the padding.

Not sure if there is a standard method used 'in modern times' to do this, other than defining a record in Ada and a corresponding struct in C.








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

* Re: Interfacing between Ada and C: records and structs
  2012-07-31 18:44   ` awdorrin
  2012-07-31 19:08     ` awdorrin
@ 2012-07-31 19:23     ` Simon Wright
  2012-08-02  4:39     ` Shark8
  2 siblings, 0 replies; 12+ messages in thread
From: Simon Wright @ 2012-07-31 19:23 UTC (permalink / raw)


awdorrin <awdorrin@gmail.com> writes:

> private
>   type Dummy is tagged null record;
>   type Mutex is record
>     Mutex : aliased POSIX.C.pthread_mutex_t;
>     D : Dummy;
>   end record

What's D : Dummy doing here? There's no equivalent in the C.

Here, on an x86_64 compiler,

   package Mutex is
      type pthread_mutex_t is new Boolean with
        Alignment => 8,
        Size => 192;
      type Dummy is tagged null record;
      type Mutex is record
         Mutex : aliased pthread_mutex_t;
         D : Dummy;
      end record;
   end Mutex;

compiled with -gnat12 -gnatR3 gives

   for Pthread_Mutex_T'Size use 192;
   for Pthread_Mutex_T'Alignment use 8;

   for Dummy'Size use 64;
   for Dummy'Alignment use 8;
   for Dummy use record
      _Tag at 0 range  0 .. 63;
   end record;

   for Mutex'Size use 256;
   for Mutex'Alignment use 8;
   for Mutex use record
      Mutex at  0 range  0 .. 191;
      D     at 24 range  0 .. 63;
   end record;



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

* Re: Interfacing between Ada and C: records and structs
  2012-07-31 19:08     ` awdorrin
@ 2012-07-31 19:27       ` Simon Wright
  2012-07-31 19:44         ` awdorrin
  0 siblings, 1 reply; 12+ messages in thread
From: Simon Wright @ 2012-07-31 19:27 UTC (permalink / raw)


awdorrin <awdorrin@gmail.com> writes:

> I am wondering if the Dummy element in the Mutex record is not being
> treated as a null, but as a null pointer, adding 8 bytes to the record
> size.

If you say

   type Dummy is null record;

then no space is reserved for the tag.

But if that is OK, what is it _for_? Normally something like this is
needed to pad out parts of a C struct that you don't need to bother
with, but that's clearly not the case here.



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

* Re: Interfacing between Ada and C: records and structs
  2012-07-31 19:27       ` Simon Wright
@ 2012-07-31 19:44         ` awdorrin
  2012-07-31 20:46           ` Niklas Holsti
  0 siblings, 1 reply; 12+ messages in thread
From: awdorrin @ 2012-07-31 19:44 UTC (permalink / raw)


This is code from the POSIX Florist API for Ada. There is a comment in the code that says that the 'Dummy' tagged null record is:
 "to force by-reference parameter mode"

Your test code matches up with similar code I wrote on my system, except being 32-bit I get D as "range 0 .. 31"

The 'rep' files generated by -gnatR3s for the Florist POSIX API gives:
for DUMMY'Size use 32;
for DUMMY'Alignment use 4;
for DUMMY use record
   _TAG at 0 range  0 .. 31;
end record;

for MUTEX'Object_Size use 256;
for MUTEX'Value_Size use 224;
for MUTEX'Alignment use 8;
for MUTEX use record
   MUTEX at  0 range  0 .. 191;
   D     at 24 range  0 .. 31;
end record;


So at least I understand why it isn't 192 bits, but 256.



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

* Re: Interfacing between Ada and C: records and structs
  2012-07-31 19:44         ` awdorrin
@ 2012-07-31 20:46           ` Niklas Holsti
  2012-08-01 12:16             ` awdorrin
  0 siblings, 1 reply; 12+ messages in thread
From: Niklas Holsti @ 2012-07-31 20:46 UTC (permalink / raw)


On 12-07-31 22:44 , awdorrin wrote:
> This is code from the POSIX Florist API for Ada. There is a comment
> in the code that says that the 'Dummy' tagged null record is: "to
> force by-reference parameter mode"

Perhaps, in some earlier GNAT, a "tagged null record" would have a zero
size, but the same is not true in the current GNAT.

If the goal is to force passing by reference, another way is to make the
Mutex type limited:

   type Mutex is limited record
      Mutex : aliased POSIX.C.pthread_mutex_t;
   end record;

Being "limited" should not increase the size of the record. But it
forbids some operations on the type, chiefly ":=".

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .



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

* Re: Interfacing between Ada and C: records and structs
       [not found] <7beb59ba-ca6f-476e-8b39-604196b0b79f@googlegroups.com>
@ 2012-08-01  2:51 ` Jeffrey Carter
  0 siblings, 0 replies; 12+ messages in thread
From: Jeffrey Carter @ 2012-08-01  2:51 UTC (permalink / raw)


On 07/31/2012 09:27 AM, awdorrin wrote:
> I have some legacy code that I am working with, they share common data structures.
>
> Simplifying my code, In Ada, I have a record:
>
> type FP_SHARED_BUF_TYPE is
> record
>    LOCK_SHM_1 : aliased Mutex;
>    LOCK_SHM_2 : aliased Mutex;
>    LOCK_SHM_3 : aliased Mutex;
> end record;
>
> In C:
>
> struct FP_SHARED_TYPE {
>    pthread_mutex_t LOCK_SHM_1;
>    pthread_mutex_t LOCK_SHM_2;
>    pthread_mutex_t LOCK_SHM_3;
> };
>
> When I compile the program, the Ada code defines the record as:
>
> for FP_SHARED_BUF_TYPE'Alignment use 9;
> for FP_SHARED_BUF_TYPE use record
>    LOCK_SHM_1 at

Anything you define in Ada that should match something defined in C should have 
a "pragma Convention (C, ...);".

-- 
Jeff Carter
"The time has come to act, and act fast. I'm leaving."
Blazing Saddles
36



--- Posted via news://freenews.netfront.net/ - Complaints to news@netfront.net ---



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

* Re: Interfacing between Ada and C: records and structs
  2012-07-31 20:46           ` Niklas Holsti
@ 2012-08-01 12:16             ` awdorrin
  0 siblings, 0 replies; 12+ messages in thread
From: awdorrin @ 2012-08-01 12:16 UTC (permalink / raw)


On Tuesday, July 31, 2012 4:46:34 PM UTC-4, Niklas Holsti wrote:
>
> If the goal is to force passing by reference, another way is to make the
> Mutex type limited:
> 
>    type Mutex is limited record
>       Mutex : aliased POSIX.C.pthread_mutex_t;
>    end record;
> 
> Being "limited" should not increase the size of the record. But it
> forbids some operations on the type, chiefly ":=".

I am a bit hesitant to change the Florist library code in my project. But from looking at the Florist SourceForge website, it doesn't look like this API is actively developed by the open source community any longer.

For now, I think I'll keep padding in my C-code to match up to the memory space generated in Ada. I'm starting to get too 'distracted' from the main goal of running gnatpp on this legacy code. :)

Thanks!



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

* Re: Interfacing between Ada and C: records and structs
  2012-07-31 18:44   ` awdorrin
  2012-07-31 19:08     ` awdorrin
  2012-07-31 19:23     ` Simon Wright
@ 2012-08-02  4:39     ` Shark8
  2012-08-02 12:32       ` awdorrin
  2 siblings, 1 reply; 12+ messages in thread
From: Shark8 @ 2012-08-02  4:39 UTC (permalink / raw)


> Digging into the POSIX module:
> 
> 
> 
> private
> 
>   type Dummy is tagged null record;
> 
>   type Mutex is record
> 
>     Mutex : aliased POSIX.C.pthread_mutex_t;
> 
>     D : Dummy;
> 
>   end record
> 
> 
> 
> > 
> 
> > Have you checked that in Ada, pthread_mutex_t'Size is 192?
> 
> > 
> 
> 
> 
> In the POSIX.C package:
> 
> ALIGNMENT : constant := Natural'Min(Standard'Maximum_Alignment, 8);
> 
> type pthread_mutex_t'Alignment use ALIGNMENT;
> 
> type pthread_mutex_t'Size use 192;
> 
> 
> 
> However, when I write a simple test program I get 256 bits from 'Size, I'm not sure why...

Try adding Pragma Pack( DATA_STRUCTURE ); to the record.



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

* Re: Interfacing between Ada and C: records and structs
  2012-08-02  4:39     ` Shark8
@ 2012-08-02 12:32       ` awdorrin
  0 siblings, 0 replies; 12+ messages in thread
From: awdorrin @ 2012-08-02 12:32 UTC (permalink / raw)


On Thursday, August 2, 2012 12:39:46 AM UTC-4, Shark8 wrote:
>
> Try adding Pragma Pack( DATA_STRUCTURE ); to the record.
>

Even with the pragma Pack, it produces the same output.

I think Niklas is correct that an older version of GNAT must have treated the 'tagged null record' differently.



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

end of thread, other threads:[~2012-08-07  7:36 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-31 16:38 Interfacing between Ada and C: records and structs awdorrin
2012-07-31 17:16 ` Niklas Holsti
2012-07-31 18:44   ` awdorrin
2012-07-31 19:08     ` awdorrin
2012-07-31 19:27       ` Simon Wright
2012-07-31 19:44         ` awdorrin
2012-07-31 20:46           ` Niklas Holsti
2012-08-01 12:16             ` awdorrin
2012-07-31 19:23     ` Simon Wright
2012-08-02  4:39     ` Shark8
2012-08-02 12:32       ` awdorrin
     [not found] <7beb59ba-ca6f-476e-8b39-604196b0b79f@googlegroups.com>
2012-08-01  2:51 ` Jeffrey Carter

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