From 09a213afc1fa3b7d7607182752b67e0f4197ad0c Mon Sep 17 00:00:00 2001 From: Brendan Emery Date: Thu, 26 Mar 2026 16:42:02 +0100 Subject: [PATCH 1/3] lola: Remove unintentional clang-format suppression --- score/mw/com/impl/bindings/lola/skeleton.cpp | 45 +++++++++----------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/score/mw/com/impl/bindings/lola/skeleton.cpp b/score/mw/com/impl/bindings/lola/skeleton.cpp index 449c7b003..673f18c5c 100644 --- a/score/mw/com/impl/bindings/lola/skeleton.cpp +++ b/score/mw/com/impl/bindings/lola/skeleton.cpp @@ -1062,7 +1062,6 @@ EventDataControlComposite<> Skeleton::CreateEventControlComposite( // coverity[autosar_cpp14_a3_8_1_violation] control_asil_result = &iterator.first->second.data_control; } - // clang-format off // The lifetime of the "control_asil_result" object lasts as long as the Skeleton is alive. // coverity[autosar_cpp14_m7_5_1_violation] // coverity[autosar_cpp14_m7_5_2_violation] @@ -1071,22 +1070,21 @@ EventDataControlComposite<> Skeleton::CreateEventControlComposite( } std::pair, EventDataControlComposite<>> -Skeleton::CreateEventDataFromOpenedSharedMemory( - const ElementFqId element_fq_id, - const SkeletonEventProperties& element_properties, - size_t sample_size, - size_t sample_alignment) noexcept +Skeleton::CreateEventDataFromOpenedSharedMemory(const ElementFqId element_fq_id, + const SkeletonEventProperties& element_properties, + size_t sample_size, + size_t sample_alignment) noexcept { // Guard against over-aligned types (Short-term solution protection) if (sample_alignment > alignof(std::max_align_t)) { score::mw::log::LogFatal("Skeleton") - << "Requested sample alignment (" << sample_alignment - << ") exceeds max_align_t (" << alignof(std::max_align_t) - << "). Safe shared memory layout cannot be guaranteed."; + << "Requested sample alignment (" << sample_alignment << ") exceeds max_align_t (" + << alignof(std::max_align_t) << "). Safe shared memory layout cannot be guaranteed."; - SCORE_LANGUAGE_FUTURECPP_ASSERT_PRD_MESSAGE(sample_alignment <= alignof(std::max_align_t),"Requested sample alignment exceeds maximum supported alignment."); + SCORE_LANGUAGE_FUTURECPP_ASSERT_PRD_MESSAGE(sample_alignment <= alignof(std::max_align_t), + "Requested sample alignment exceeds maximum supported alignment."); } // Calculate the aligned size for a single sample to ensure proper padding between slots @@ -1098,27 +1096,25 @@ Skeleton::CreateEventDataFromOpenedSharedMemory( (total_data_size_bytes + sizeof(std::max_align_t) - 1) / sizeof(std::max_align_t); auto* data_storage = storage_resource_->construct>( - num_max_align_elements, - memory::shared::PolymorphicOffsetPtrAllocator(*storage_resource_)); + num_max_align_elements, memory::shared::PolymorphicOffsetPtrAllocator(*storage_resource_)); - auto inserted_data_slots = storage_->events_.emplace(std::piecewise_construct, - std::forward_as_tuple(element_fq_id), - std::forward_as_tuple(data_storage)); + auto inserted_data_slots = storage_->events_.emplace( + std::piecewise_construct, std::forward_as_tuple(element_fq_id), std::forward_as_tuple(data_storage)); SCORE_LANGUAGE_FUTURECPP_ASSERT_PRD_MESSAGE(inserted_data_slots.second, - "Couldn't register/emplace event-storage in data-section."); - + "Couldn't register/emplace event-storage in data-section."); const DataTypeMetaInfo sample_meta_info{sample_size, static_cast(sample_alignment)}; void* const event_data_raw_array = data_storage->data(); - auto inserted_meta_info = storage_->events_metainfo_.emplace( - std::piecewise_construct, - std::forward_as_tuple(element_fq_id), - std::forward_as_tuple(sample_meta_info, event_data_raw_array)); + auto inserted_meta_info = + storage_->events_metainfo_.emplace(std::piecewise_construct, + std::forward_as_tuple(element_fq_id), + std::forward_as_tuple(sample_meta_info, event_data_raw_array)); SCORE_LANGUAGE_FUTURECPP_ASSERT_PRD_MESSAGE(inserted_meta_info.second, - "Couldn't register/emplace event-meta-info in data-section."); + "Couldn't register/emplace event-meta-info in data-section."); - return {score::memory::shared::OffsetPtr(data_storage), CreateEventControlComposite(element_fq_id, element_properties)}; + return {score::memory::shared::OffsetPtr(data_storage), + CreateEventControlComposite(element_fq_id, element_properties)}; } std::pair, EventDataControlComposite<>> Skeleton::RegisterGeneric( const ElementFqId element_fq_id, @@ -1147,8 +1143,7 @@ std::pair, EventDataControlComposite<>> S } else { - return CreateEventDataFromOpenedSharedMemory( - element_fq_id, element_properties, sample_size, sample_alignment); + return CreateEventDataFromOpenedSharedMemory(element_fq_id, element_properties, sample_size, sample_alignment); } } From 8219a7b1a64add394478ba4c448ef810abe33092 Mon Sep 17 00:00:00 2001 From: Brendan Emery Date: Thu, 26 Mar 2026 16:26:01 +0100 Subject: [PATCH 2/3] lola: Use allocate instead of construct for creating byte array In this case, we want to create a type erased byte array. Construct is used to allocate memory and instantiate a type in the allocated memory. In this case, we only want to allocate the memory. Therefore, instead of using construct with a dummy template type to force the correct alignment to be used, we simply use allocate. --- score/mw/com/impl/bindings/lola/skeleton.cpp | 30 ++++---------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/score/mw/com/impl/bindings/lola/skeleton.cpp b/score/mw/com/impl/bindings/lola/skeleton.cpp index 673f18c5c..162e835c4 100644 --- a/score/mw/com/impl/bindings/lola/skeleton.cpp +++ b/score/mw/com/impl/bindings/lola/skeleton.cpp @@ -1075,28 +1075,11 @@ Skeleton::CreateEventDataFromOpenedSharedMemory(const ElementFqId element_fq_id, size_t sample_size, size_t sample_alignment) noexcept { - - // Guard against over-aligned types (Short-term solution protection) - if (sample_alignment > alignof(std::max_align_t)) - { - score::mw::log::LogFatal("Skeleton") - << "Requested sample alignment (" << sample_alignment << ") exceeds max_align_t (" - << alignof(std::max_align_t) << "). Safe shared memory layout cannot be guaranteed."; - - SCORE_LANGUAGE_FUTURECPP_ASSERT_PRD_MESSAGE(sample_alignment <= alignof(std::max_align_t), - "Requested sample alignment exceeds maximum supported alignment."); - } - // Calculate the aligned size for a single sample to ensure proper padding between slots const auto aligned_sample_size = memory::shared::CalculateAlignedSize(sample_size, sample_alignment); const auto total_data_size_bytes = aligned_sample_size * element_properties.number_of_slots; - // Convert total bytes to the number of std::max_align_t elements needed (round up) - const size_t num_max_align_elements = - (total_data_size_bytes + sizeof(std::max_align_t) - 1) / sizeof(std::max_align_t); - - auto* data_storage = storage_resource_->construct>( - num_max_align_elements, memory::shared::PolymorphicOffsetPtrAllocator(*storage_resource_)); + auto* data_storage = storage_resource_->allocate(total_data_size_bytes, sample_alignment); auto inserted_data_slots = storage_->events_.emplace( std::piecewise_construct, std::forward_as_tuple(element_fq_id), std::forward_as_tuple(data_storage)); @@ -1104,17 +1087,14 @@ Skeleton::CreateEventDataFromOpenedSharedMemory(const ElementFqId element_fq_id, "Couldn't register/emplace event-storage in data-section."); const DataTypeMetaInfo sample_meta_info{sample_size, static_cast(sample_alignment)}; - void* const event_data_raw_array = data_storage->data(); - auto inserted_meta_info = - storage_->events_metainfo_.emplace(std::piecewise_construct, - std::forward_as_tuple(element_fq_id), - std::forward_as_tuple(sample_meta_info, event_data_raw_array)); + auto inserted_meta_info = storage_->events_metainfo_.emplace(std::piecewise_construct, + std::forward_as_tuple(element_fq_id), + std::forward_as_tuple(sample_meta_info, data_storage)); SCORE_LANGUAGE_FUTURECPP_ASSERT_PRD_MESSAGE(inserted_meta_info.second, "Couldn't register/emplace event-meta-info in data-section."); - return {score::memory::shared::OffsetPtr(data_storage), - CreateEventControlComposite(element_fq_id, element_properties)}; + return {data_storage, CreateEventControlComposite(element_fq_id, element_properties)}; } std::pair, EventDataControlComposite<>> Skeleton::RegisterGeneric( const ElementFqId element_fq_id, From 7f5a8c20b72e05b4997d59fbbc4c0142f6fad79b Mon Sep 17 00:00:00 2001 From: Brendan Emery Date: Thu, 26 Mar 2026 16:28:03 +0100 Subject: [PATCH 3/3] lola: Return raw ptr instead of OffsetPtr from RegisterGeneric Since the pointer to the type erased memory buffer which is returned by RegisterGeneric never resides in shared memory, there's no reason to not simply use a raw pointer. --- .../bindings/lola/generic_skeleton_event.cpp | 28 ++++++++----------- .../bindings/lola/generic_skeleton_event.h | 2 +- score/mw/com/impl/bindings/lola/skeleton.cpp | 19 ++++++------- score/mw/com/impl/bindings/lola/skeleton.h | 28 ++++++++----------- 4 files changed, 32 insertions(+), 45 deletions(-) diff --git a/score/mw/com/impl/bindings/lola/generic_skeleton_event.cpp b/score/mw/com/impl/bindings/lola/generic_skeleton_event.cpp index d2114eedd..9e13eed6a 100644 --- a/score/mw/com/impl/bindings/lola/generic_skeleton_event.cpp +++ b/score/mw/com/impl/bindings/lola/generic_skeleton_event.cpp @@ -32,8 +32,11 @@ GenericSkeletonEvent::GenericSkeletonEvent(Skeleton& parent, ResultBlank GenericSkeletonEvent::PrepareOffer() noexcept { - std::tie(data_storage_, control_) = event_shared_impl_.GetParent().RegisterGeneric( + void* data_storage; + std::tie(data_storage, control_) = event_shared_impl_.GetParent().RegisterGeneric( event_shared_impl_.GetElementFQId(), event_properties_, size_info_.size, size_info_.alignment); + data_storage_ = static_cast(data_storage); + SCORE_LANGUAGE_FUTURECPP_ASSERT_PRD(data_storage_ != nullptr); event_shared_impl_.PrepareOfferCommon(); return {}; @@ -92,31 +95,22 @@ Result> GenericSkeletonEvent::All if (slot.IsValidQM() || slot.IsValidAsilB()) { - // Get the actual CONTAINER object (using the max_align_t type we allocated it with!) - using StorageType = lola::EventDataStorage; - StorageType* storage_ptr = data_storage_.get(); - SCORE_LANGUAGE_FUTURECPP_ASSERT_PRD(storage_ptr != nullptr); - - std::uint8_t* byte_ptr = reinterpret_cast(storage_ptr->data()); - // Calculate the exact slot spacing based on alignment padding const auto aligned_size = memory::shared::CalculateAlignedSize(size_info_.size, size_info_.alignment); std::size_t offset = static_cast(slot.GetIndex()) * aligned_size; - void* data_ptr = byte_ptr + offset; + void* data_ptr = static_cast(memory::shared::AddOffsetToPointer(data_storage_, offset)); auto lola_ptr = lola::SampleAllocateePtr(data_ptr, control_.value(), slot); return impl::MakeSampleAllocateePtr(std::move(lola_ptr)); } - else + + if (!event_properties_.enforce_max_samples) { - if (!event_properties_.enforce_max_samples) - { - ::score::mw::log::LogError("lola") - << "GenericSkeletonEvent: Allocation of event slot failed. Hint: enforceMaxSamples was " - "disabled by config. Might be the root cause!"; - } - return MakeUnexpected(ComErrc::kBindingFailure); + ::score::mw::log::LogError("lola") + << "GenericSkeletonEvent: Allocation of event slot failed. Hint: enforceMaxSamples was " + "disabled by config. Might be the root cause!"; } + return MakeUnexpected(ComErrc::kBindingFailure); } std::pair GenericSkeletonEvent::GetSizeInfo() const noexcept diff --git a/score/mw/com/impl/bindings/lola/generic_skeleton_event.h b/score/mw/com/impl/bindings/lola/generic_skeleton_event.h index 6765d93a6..c1e485109 100644 --- a/score/mw/com/impl/bindings/lola/generic_skeleton_event.h +++ b/score/mw/com/impl/bindings/lola/generic_skeleton_event.h @@ -61,7 +61,7 @@ class GenericSkeletonEvent : public GenericSkeletonEventBinding const SkeletonEventProperties event_properties_; std::optional> control_{}; EventSlotStatus::EventTimeStamp current_timestamp_{1U}; - score::memory::shared::OffsetPtr data_storage_{nullptr}; + std::uint8_t* data_storage_{nullptr}; bool qm_disconnect_{false}; SkeletonEventCommon event_shared_impl_; diff --git a/score/mw/com/impl/bindings/lola/skeleton.cpp b/score/mw/com/impl/bindings/lola/skeleton.cpp index 162e835c4..e87b4073c 100644 --- a/score/mw/com/impl/bindings/lola/skeleton.cpp +++ b/score/mw/com/impl/bindings/lola/skeleton.cpp @@ -1069,11 +1069,11 @@ EventDataControlComposite<> Skeleton::CreateEventControlComposite( return EventDataControlComposite{&control_qm.first->second.data_control, control_asil_result}; } -std::pair, EventDataControlComposite<>> -Skeleton::CreateEventDataFromOpenedSharedMemory(const ElementFqId element_fq_id, - const SkeletonEventProperties& element_properties, - size_t sample_size, - size_t sample_alignment) noexcept +std::pair> Skeleton::CreateEventDataFromOpenedSharedMemory( + const ElementFqId element_fq_id, + const SkeletonEventProperties& element_properties, + size_t sample_size, + size_t sample_alignment) noexcept { // Calculate the aligned size for a single sample to ensure proper padding between slots const auto aligned_sample_size = memory::shared::CalculateAlignedSize(sample_size, sample_alignment); @@ -1096,7 +1096,8 @@ Skeleton::CreateEventDataFromOpenedSharedMemory(const ElementFqId element_fq_id, return {data_storage, CreateEventControlComposite(element_fq_id, element_properties)}; } -std::pair, EventDataControlComposite<>> Skeleton::RegisterGeneric( + +std::pair> Skeleton::RegisterGeneric( const ElementFqId element_fq_id, const SkeletonEventProperties& element_properties, const size_t sample_size, @@ -1121,10 +1122,8 @@ std::pair, EventDataControlComposite<>> S return {data_storage, control_composite}; } - else - { - return CreateEventDataFromOpenedSharedMemory(element_fq_id, element_properties, sample_size, sample_alignment); - } + + return CreateEventDataFromOpenedSharedMemory(element_fq_id, element_properties, sample_size, sample_alignment); } ResultBlank Skeleton::OnServiceMethodsSubscribed(const ProxyInstanceIdentifier& proxy_instance_identifier, diff --git a/score/mw/com/impl/bindings/lola/skeleton.h b/score/mw/com/impl/bindings/lola/skeleton.h index 5099d4b27..ac8a44719 100644 --- a/score/mw/com/impl/bindings/lola/skeleton.h +++ b/score/mw/com/impl/bindings/lola/skeleton.h @@ -116,13 +116,12 @@ class Skeleton final : public SkeletonBinding /// \param sample_size The size of a single data sample in bytes. /// \param sample_alignment The alignment requirement of the data sample in bytes. /// \return A pair containing: - /// - An OffsetPtr to the allocated data storage (void*). + /// - An type erased pointer to the allocated data storage (void*). /// - The EventDataControlComposite for managing the event's control data. - std::pair, EventDataControlComposite<>> RegisterGeneric( - const ElementFqId element_fq_id, - const SkeletonEventProperties& element_properties, - const size_t sample_size, - const size_t sample_alignment) noexcept; + std::pair> RegisterGeneric(const ElementFqId element_fq_id, + const SkeletonEventProperties& element_properties, + const size_t sample_size, + const size_t sample_alignment) noexcept; /// \brief Enables dynamic registration of Events at the Skeleton. /// \tparam SampleType The type of the event @@ -209,11 +208,11 @@ class Skeleton final : public SkeletonBinding /// \param sample_size The size of a single data sample. /// \param sample_alignment The alignment of the data sample. /// \return A pair containing the data storage pointer (void*) and the control composite. - std::pair, EventDataControlComposite<>> - CreateEventDataFromOpenedSharedMemory(const ElementFqId element_fq_id, - const SkeletonEventProperties& element_properties, - size_t sample_size, - size_t sample_alignment) noexcept; + std::pair> CreateEventDataFromOpenedSharedMemory( + const ElementFqId element_fq_id, + const SkeletonEventProperties& element_properties, + size_t sample_size, + size_t sample_alignment) noexcept; class ShmResourceStorageSizes { @@ -360,13 +359,8 @@ auto Skeleton::Register(const ElementFqId element_fq_id, SkeletonEventProperties } return {typed_event_data_storage_ptr, event_data_control_composite}; } - else - { - auto [typed_event_data_storage_ptr, event_data_control_composite] = - CreateEventDataFromOpenedSharedMemory(element_fq_id, element_properties); - return {typed_event_data_storage_ptr, event_data_control_composite}; - } + return CreateEventDataFromOpenedSharedMemory(element_fq_id, element_properties); } template