Skip to content

Commit

Permalink
Merge pull request #122 from shivaprasad-basavaraj/users/sbasavaraj/f…
Browse files Browse the repository at this point in the history
…ix64bitByteAlignmentIssues

Fix byte alignment issues with 64 bit grpc-labview
  • Loading branch information
shivaprasad-basavaraj authored Aug 30, 2022
2 parents 9056abe + caa1b0f commit de6d457
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 76 deletions.
4 changes: 2 additions & 2 deletions src/cluster_copier.cc
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ namespace grpc_labview {
int x = 0;
for (auto str : repeatedNested->_value)
{
auto lvCluster = (*array)->bytes<LVCluster*>(x * clusterSize);
auto lvCluster = (LVCluster**)(*array)->bytes(x * clusterSize, nestedMetadata->alignmentRequirement);
*lvCluster = nullptr;
CopyToCluster(*str, (int8_t*)lvCluster);
x += 1;
Expand Down Expand Up @@ -667,7 +667,7 @@ namespace grpc_labview {

for (int x = 0; x < count; ++x)
{
auto data = (*array)->bytes<LVCluster*>(nestedMetadata->clusterSize * x);
auto data = (LVCluster*)(*array)->bytes(nestedMetadata->clusterSize * x, nestedMetadata->alignmentRequirement);
auto nested = std::make_shared<LVMessage>(nestedMetadata);
repeatedValue->_value.push_back(nested);
CopyFromCluster(*nested, (int8_t*)data);
Expand Down
6 changes: 4 additions & 2 deletions src/grpc_interop.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ namespace grpc_labview
int clusterOffset = 0;
if (lvMetadata->elements != nullptr)
{
auto lvElement = (*lvMetadata->elements)->bytes<LVMesageElementMetadata>();
// byteAlignment for LVMesageElementMetadata would be the size of its largest element which is a LStrHandle
auto lvElement = (LVMesageElementMetadata*)(*lvMetadata->elements)->bytes(0, sizeof(LStrHandle));
for (int x = 0; x < (*lvMetadata->elements)->cnt; ++x, ++lvElement)
{
auto element = std::make_shared<MessageElementMetadata>(metadataOwner);
Expand Down Expand Up @@ -75,7 +76,8 @@ namespace grpc_labview
int clusterOffset = 0;
if (lvMetadata->elements != nullptr)
{
auto lvElement = (*lvMetadata->elements)->bytes<LVMesageElementMetadata>();
// byteAlignment for LVMesageElementMetadata would be the size of its largest element which is a LStrHandle
auto lvElement = (LVMesageElementMetadata*)(*lvMetadata->elements)->bytes(0, sizeof(LStrHandle));
for (int x = 0; x < (*lvMetadata->elements)->cnt; ++x, ++lvElement)
{
auto element = std::make_shared<MessageElementMetadata>(metadataOwner);
Expand Down
14 changes: 14 additions & 0 deletions src/lv_interop.cc
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,18 @@ namespace grpc_labview
{
return RTSetCleanupProc(cleanUpProc, id, kCleanOnRemove);
}

int AlignClusterOffset(int clusterOffset, int alignmentRequirement)
{
#ifndef _PS_4
int remainder = abs(clusterOffset) % alignmentRequirement;
if (remainder == 0)
{
return clusterOffset;
}
return clusterOffset + alignmentRequirement - remainder;
#else
return clusterOffset;
#endif
}
}
29 changes: 11 additions & 18 deletions src/lv_interop.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ namespace grpc_labview
virtual ~gRPCid() { }
};

int AlignClusterOffset(int clusterOffset, int alignmentRequirement);

//---------------------------------------------------------------------
// LabVIEW definitions
//---------------------------------------------------------------------
Expand All @@ -69,29 +71,20 @@ namespace grpc_labview
template<typename T>
T* bytes()
{
#ifndef _PS_4
if (sizeof(T) < 8)
{
return (T*)rawBytes;
}
return (T*)(rawBytes + 4); // 8-byte aligned data
#else
return (T*)rawBytes;
#endif
static_assert(!std::is_class<T>::value, "T must not be a struct/class type.");
return (T*)(bytes(0, sizeof(T)));
}

template<typename T>
T* bytes(int byteOffset)
{
#ifndef _PS_4
if (sizeof(T) < 8)
{
return (T*)(rawBytes + byteOffset);
}
return (T*)(rawBytes + 4 + byteOffset); // 8-byte aligned data
#else
return (T*)(rawBytes + byteOffset);
#endif
static_assert(!std::is_class<T>::value, "T must not be a struct/class type.");
return (T*)(bytes(byteOffset, sizeof(T)));
}

void* bytes(int byteOffset, int byteAlignment)
{
return (void*)(rawBytes + AlignClusterOffset(4, byteAlignment) - 4 + byteOffset);
}
};

Expand Down
84 changes: 30 additions & 54 deletions src/message_element_metadata_owner.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,74 +20,41 @@ namespace grpc_labview {
//---------------------------------------------------------------------
int ClusterElementSize(LVMessageMetadataType type, bool repeated)
{
#ifndef _PS_4
if (repeated)
{
return 8;
return sizeof(void*);
}
switch (type)
{
case LVMessageMetadataType::BoolValue:
return 1;
case LVMessageMetadataType::EnumValue:
case LVMessageMetadataType::Int32Value:
case LVMessageMetadataType::UInt32Value:
case LVMessageMetadataType::EnumValue:
case LVMessageMetadataType::FloatValue:
return 4;
case LVMessageMetadataType::Int64Value:
case LVMessageMetadataType::UInt64Value:
case LVMessageMetadataType::DoubleValue:
case LVMessageMetadataType::StringValue:
case LVMessageMetadataType::BytesValue:
case LVMessageMetadataType::MessageValue:
return 8;
}
#else
if (repeated)
{
return 4;
}
switch (type)
{
case LVMessageMetadataType::BoolValue:
return 1;
case LVMessageMetadataType::Int32Value:
case LVMessageMetadataType::UInt32Value:
case LVMessageMetadataType::EnumValue:
case LVMessageMetadataType::FloatValue:
return 4;
case LVMessageMetadataType::StringValue:
case LVMessageMetadataType::BytesValue:
case LVMessageMetadataType::MessageValue:
return 4;
case LVMessageMetadataType::Int64Value:
case LVMessageMetadataType::UInt64Value:
case LVMessageMetadataType::DoubleValue:
return 8;
return sizeof(void*);
}
#endif
return 0;
}

//---------------------------------------------------------------------
//---------------------------------------------------------------------
int AlignClusterOffset(int clusterOffset, LVMessageMetadataType type, bool repeated)
{
#ifndef _PS_4
if (clusterOffset == 0)
{
return 0;
}
auto multiple = ClusterElementSize(type, repeated);
int remainder = abs(clusterOffset) % multiple;
if (remainder == 0)
{
return clusterOffset;
}
return clusterOffset + multiple - remainder;
#else
return clusterOffset;
#endif
auto multiple = ClusterElementSize(type, repeated);
return AlignClusterOffset(clusterOffset, multiple);
}

//---------------------------------------------------------------------
Expand Down Expand Up @@ -120,37 +87,46 @@ namespace grpc_labview {
return;
}
int clusterOffset = 0;
int maxAlignmentRequirement = 0;
for (auto element: metadata->_elements)
{
auto elementType = element->type;
auto nestedElement = element;
while (elementType == LVMessageMetadataType::MessageValue)
{
auto nestedMetadata = FindMetadata(element->embeddedMessageName);
auto nestedElement = nestedMetadata->_elements.front();
elementType = nestedElement->type;
}
clusterOffset = AlignClusterOffset(clusterOffset, element->type, element->isRepeated);
element->clusterOffset = clusterOffset;
if (element->type == LVMessageMetadataType::MessageValue)
{
{
auto nestedMetadata = FindMetadata(element->embeddedMessageName);
UpdateMetadataClusterLayout(nestedMetadata);
int alignmentRequirement = 0;
int elementSize = 0;
if (element->isRepeated)
{
clusterOffset += ClusterElementSize(element->type, element->isRepeated);
{
alignmentRequirement = elementSize = ClusterElementSize(element->type, element->isRepeated);
}
else
{
clusterOffset += nestedMetadata->clusterSize;
alignmentRequirement = nestedMetadata->alignmentRequirement;
elementSize = nestedMetadata->clusterSize;
}
clusterOffset = AlignClusterOffset(clusterOffset, alignmentRequirement);
element->clusterOffset = clusterOffset;
clusterOffset += elementSize;
if (maxAlignmentRequirement < alignmentRequirement)
{
maxAlignmentRequirement = alignmentRequirement;
}
}
else
{
clusterOffset += ClusterElementSize(element->type, element->isRepeated);
clusterOffset = AlignClusterOffset(clusterOffset, element->type, element->isRepeated);
element->clusterOffset = clusterOffset;
int elementSize = ClusterElementSize(element->type, element->isRepeated);
clusterOffset += elementSize;
if (maxAlignmentRequirement < elementSize)
{
maxAlignmentRequirement = elementSize;
}
}
}
metadata->clusterSize = AlignClusterOffset(clusterOffset, LVMessageMetadataType::StringValue, true);
metadata->alignmentRequirement = maxAlignmentRequirement;
metadata->clusterSize = AlignClusterOffset(clusterOffset, maxAlignmentRequirement);
}

//---------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions src/message_metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ namespace grpc_labview
std::string messageName;
std::string typeUrl;
int clusterSize;
int alignmentRequirement;
LVMessageMetadataList _elements;
LVMessageMetadataMap _mappedElements;
};
Expand Down

0 comments on commit de6d457

Please sign in to comment.