-
Notifications
You must be signed in to change notification settings - Fork 84
Fix typed proxy access to generic skeleton event storage #394
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
78fd185
dcb34ed
c985515
e8d58b8
7b1b627
35c49d5
102ffbb
c29defc
b87e5a7
add906f
33be66a
cf0adce
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,7 +14,11 @@ | |
| #define SCORE_MW_COM_IMPL_BINDINGS_LOLA_PROXY_EVENT_H | ||
|
|
||
| #include "score/mw/com/impl/bindings/lola/event_data_storage.h" | ||
| #include "score/mw/com/impl/bindings/lola/event_meta_info.h" | ||
| #include "score/mw/com/impl/bindings/lola/proxy_event_common.h" | ||
|
|
||
| #include "score/language/safecpp/safe_math/safe_math.h" | ||
| #include "score/memory/shared/pointer_arithmetic_util.h" | ||
| #include "score/mw/com/impl/proxy_event_binding.h" | ||
| #include "score/mw/com/impl/sample_reference_tracker.h" | ||
| #include "score/mw/com/impl/subscription_state.h" | ||
|
|
@@ -64,7 +68,7 @@ class ProxyEvent final : public ProxyEventBinding<SampleType> | |
| ProxyEvent(Proxy& parent, const ElementFqId element_fq_id, const std::string_view event_name) | ||
| : ProxyEventBinding<SampleType>{}, | ||
| proxy_event_common_{parent, element_fq_id, event_name}, | ||
| samples_{parent.GetEventDataStorage<SampleType>(element_fq_id)} | ||
| meta_info_{parent.GetEventMetaInfo(element_fq_id)} | ||
| { | ||
| } | ||
|
|
||
|
|
@@ -134,7 +138,7 @@ class ProxyEvent final : public ProxyEventBinding<SampleType> | |
| Result<std::size_t> GetNumNewSamplesAvailableImpl() const noexcept; | ||
|
|
||
| ProxyEventCommon proxy_event_common_; | ||
| const EventDataStorage<SampleType>& samples_; | ||
| const EventMetaInfo& meta_info_; | ||
| }; | ||
|
|
||
| template <typename SampleType> | ||
|
|
@@ -192,9 +196,40 @@ inline Result<std::size_t> ProxyEvent<SampleType>::GetNewSamplesImpl(Callback&& | |
|
|
||
| auto& event_data_control_local = proxy_event_common_.GetConsumerEventDataControlLocal(); | ||
|
|
||
| const std::size_t aligned_sample_size = | ||
| memory::shared::CalculateAlignedSize(sizeof(SampleType), alignof(SampleType)); | ||
| const auto event_slots_raw_array_size = | ||
| safe_math::Multiply(aligned_sample_size, event_data_control_local.GetMaxSampleSlots()); | ||
| if (!event_slots_raw_array_size.has_value()) | ||
| { | ||
| score::mw::log::LogFatal("lola") << "Could not calculate the event slots raw array size. Terminating."; | ||
| std::terminate(); | ||
| } | ||
|
|
||
| const void* const event_slots_raw_array = meta_info_.event_slots_raw_array_.get(event_slots_raw_array_size.value()); | ||
| SCORE_LANGUAGE_FUTURECPP_PRECONDITION_PRD_MESSAGE(nullptr != event_slots_raw_array, "Null event slot array"); | ||
| SCORE_LANGUAGE_FUTURECPP_PRECONDITION_PRD_MESSAGE(meta_info_.data_type_info_.size == sizeof(SampleType), | ||
| "Event sample size mismatch"); | ||
| SCORE_LANGUAGE_FUTURECPP_PRECONDITION_PRD_MESSAGE(meta_info_.data_type_info_.alignment == alignof(SampleType), | ||
| "Event sample alignment mismatch"); | ||
|
|
||
| for (auto slot_index_it = slot_indices.begin; slot_index_it != slot_indices.end; ++slot_index_it) | ||
| { | ||
| const SampleType& sample_data{samples_.at(static_cast<std::size_t>(*slot_index_it))}; | ||
| // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) The pointer event_slots_raw_array points to | ||
| // the first byte of the type-erased event sample storage in shared memory. Samples may originate from either a | ||
| // typed SkeletonEvent or a GenericSkeletonEvent, therefore slot lookup must use the stable EventMetaInfo raw | ||
| // storage address and SampleType stride instead of interpreting the shared-memory DynamicArray object type. | ||
| const auto* const event_slots_array = static_cast<const std::uint8_t*>(event_slots_raw_array); | ||
| const auto* const object_start_address = &event_slots_array[aligned_sample_size * (*slot_index_it)]; | ||
| // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) | ||
|
|
||
| // Suppress "AUTOSAR C++14 M5-2-8" rule finding: "An object with integer type or pointer to void type shall | ||
| // not be converted to an object with pointer type.". | ||
| // The raw storage address is provided through EventMetaInfo. The regular typed proxy validates the expected | ||
| // type at compile time and calculates the slot offset with sizeof(SampleType)/alignof(SampleType). | ||
| // coverity[autosar_cpp14_m5_2_8_violation] | ||
| const auto* const typed_sample_data = reinterpret_cast<const SampleType*>(object_start_address); | ||
| const SampleType& sample_data{*typed_sample_data}; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why this temp var? |
||
| const EventSlotStatus event_slot_status{event_data_control_local[*slot_index_it]}; | ||
| const EventSlotStatus::EventTimeStamp sample_timestamp{event_slot_status.GetTimeStamp()}; | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -127,6 +127,14 @@ class SkeletonMemoryManager final | |
| template <typename SampleType> | ||
| auto RetrieveEventDataFromOpenedSharedMemory(const ElementFqId element_fq_id) -> EventDataStorage<SampleType>&; | ||
|
|
||
| /// \brief Retrieves the raw event sample storage pointer for a generic event from opened shared memory. | ||
| /// | ||
| /// Generic events use EventMetaInfo as the stable type-erased contract. This keeps generic skeleton restarts | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment is slightly "confusing" to me ;) But then this question comes up (I guess): If I now told you, that TypedSkeleton-GenericSkeleton interoperability on the same shm-object is NO supported use-case ... and in the light of the changes you did to the (typed) proxy event: Why are we STILL constructing a
|
||
| /// independent from the concrete DynamicArray<T> representation used by typed skeletons and proxies. | ||
| auto RetrieveGenericEventDataFromOpenedSharedMemory(const ElementFqId element_fq_id, | ||
| const SkeletonEventProperties& element_properties) noexcept | ||
| -> void*; | ||
|
|
||
| /// \brief Rolls back any existing operations in the TransactionLog corresponding to a SkeletonEvent | ||
| /// | ||
| /// The TransactionLog would only exist if a SkeletonEvent in a crashed process had tracing enabled. If tracing was | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| # ******************************************************************************* | ||
| # Copyright (c) 2026 Contributors to the Eclipse Foundation | ||
| # | ||
| # See the NOTICE file(s) distributed with this work for additional | ||
| # information regarding copyright ownership. | ||
| # | ||
| # This program and the accompanying materials are made available under the | ||
| # terms of the Apache License Version 2.0 which is available at | ||
| # https://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
| # ******************************************************************************* | ||
|
|
||
| load("@rules_cc//cc:defs.bzl", "cc_binary") | ||
| load("@score_baselibs//score/language/safecpp:toolchain_features.bzl", "COMPILER_WARNING_FEATURES") | ||
| load("//score/mw/com/test:pkg_application.bzl", "pkg_application") | ||
|
|
||
| cc_binary( | ||
| name = "generic_skeleton_typed_proxy", | ||
| srcs = [ | ||
| "generic_skeleton_typed_proxy_application.cpp", | ||
| "generic_skeleton_typed_proxy_application.h", | ||
| ], | ||
| data = ["mw_com_config.json"], | ||
| features = COMPILER_WARNING_FEATURES + [ | ||
| "aborts_upon_exception", | ||
| ], | ||
| deps = [ | ||
| "//score/mw/com", | ||
| "//score/mw/com/test/common_test_resources:bigdata_type", | ||
| "//score/mw/com/test/common_test_resources:sample_sender_receiver", | ||
| "//score/mw/com/test/common_test_resources:sctf_test_runner", | ||
| "@score_baselibs//score/language/futurecpp", | ||
| ], | ||
| ) | ||
|
|
||
| pkg_application( | ||
| name = "generic_skeleton_typed_proxy-pkg", | ||
| app_name = "generic_skeleton_typed_proxy", | ||
| bin = [":generic_skeleton_typed_proxy"], | ||
| etc = [ | ||
| "mw_com_config.json", | ||
| "logging.json", | ||
| ], | ||
| visibility = [ | ||
| "//platform/aas/test/mw/com:__pkg__", | ||
| "//score/mw/com/test/generic_skeleton_typed_proxy:__subpackages__", | ||
| ], | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The whole code-block/extension (line 199 - 215) you added here, now happens every time in
GetNewSamplesImpl, which is the absolute HOT-PATH (called with extremly high frequency!). This is unnecessary, because the code is completely independent from the call arguments.You should move this code to the Subscribe call (event better would be the
ctorif possible)