Unions, memory and scaling

2 posts / 0 new
Last post
Offline
Last seen: 6 years 5 months ago
Joined: 05/05/2014
Posts: 4
Unions, memory and scaling

Hello there


We are looking at use unions in our application. Our IDL and generated code can be seen below.

 

struct LunaStyleCommandSelectNextArguments {
    long bo;
};

struct LunaStyleCommandSelectPrevArguments {
    long bo;
};

struct LunaStyleCommandSelectIndexArguments {
    long index;
};

union LunaStyleCommandArguments switch (LunaStyleCommandType) {
case SELECT_NEXT:
    LunaStyleCommandSelectNextArguments selectNextArguments;
case SELECT_PREV:
    LunaStyleCommandSelectPrevArguments selectPrevArguments;
case SELECT_INDEX:
    LunaStyleCommandSelectIndexArguments selectIndexArguments;
};

Which results in the generated code:

 

typedef struct LunaStyleCommandArguments {
#ifdef __cplusplus
    typedef struct LunaStyleCommandArgumentsSeq Seq;

#ifndef NDDS_STANDALONE_TYPE
    typedef LunaStyleCommandArgumentsTypeSupport TypeSupport;
    typedef LunaStyleCommandArgumentsDataWriter DataWriter;
    typedef LunaStyleCommandArgumentsDataReader DataReader;
#endif

#endif
    LunaStyleCommandType _d;

    struct LunaStyleCommandArguments_u

    {
    LunaStyleCommandSelectNextArguments  selectNextArguments;

    LunaStyleCommandSelectPrevArguments  selectPrevArguments;

    LunaStyleCommandSelectIndexArguments  selectIndexArguments;


    } _u;
} LunaStyleCommandArguments;

We are a little confused by the generated code. It looks like the data type might allocate memory for all possible members, rather than just the largest element. This makes us wonder about the scaling if the union contains many members. Is there any smart handling, both with respect to sending the data over DDS (Do we only send the used member?) and with respect to the datareader cache (Is there allocated memory for the unused parts of the struct?).

Offline
Last seen: 2 years 2 months ago
Joined: 01/31/2011
Posts: 37

You're correct that the data type is not a native C++ union but rather a structure that contains all of the possible branches in the union.  For the recieve side cache, the RTI core will allocate the top-level structure which includes fully allocating all possible members, not just the largest element.  The datawriter cache will be sized based on the maximum serialized size of the structure, which means the serialized size of the largest member of the union.

However, the discriminant determines which actual member is sent on the wire.  So not all members are sent on the wire; only the discriminant, and the corresponding member.

One thing to consider - the RTI Connext 5.1.0 release supports the XTypes spec and the concept of Optional members.  Optional members are not sent on the wire unless present in the sample, and the datareader cache does not allocate memory for the Optional members unless they are present in the sample.  Not quite the same as a union, but it does provide some savings for memory size at the expense of allocations in the critical path.