diff --git a/score/mw/com/impl/bindings/lola/shm_path_builder.cpp b/score/mw/com/impl/bindings/lola/shm_path_builder.cpp index f13d869d9..e8666742f 100644 --- a/score/mw/com/impl/bindings/lola/shm_path_builder.cpp +++ b/score/mw/com/impl/bindings/lola/shm_path_builder.cpp @@ -30,6 +30,7 @@ constexpr auto kDataChannelPrefix = "lola-data-"; constexpr auto kControlChannelPrefix = "lola-ctl-"; constexpr auto kMethodChannelPrefix = "lola-methods-"; constexpr auto kAsilBControlChannelSuffix = "-b"; +constexpr auto kInterVmSharedShmPrefix = "/intervm-shared-shmem/"; /// Emit file name of the control file to an ostream /// @@ -110,7 +111,8 @@ void EmitMethodFileName(std::ostream& out, std::string ShmPathBuilder::GetDataChannelShmName(const LolaServiceInstanceId::InstanceId instance_id) const noexcept { - return EmitWithPrefix('/', [this, instance_id](auto& out) { + const auto prefix = inter_vm_support_ ? kInterVmSharedShmPrefix : "/"; + return EmitWithPrefix(prefix, [this, instance_id](auto& out) { EmitDataFileName(out, service_id_, instance_id); }); } @@ -118,7 +120,8 @@ std::string ShmPathBuilder::GetDataChannelShmName(const LolaServiceInstanceId::I std::string ShmPathBuilder::GetControlChannelShmName(const LolaServiceInstanceId::InstanceId instance_id, const QualityType channel_type) const noexcept { - return EmitWithPrefix('/', [this, channel_type, instance_id](auto& out) noexcept { + const auto prefix = inter_vm_support_ ? kInterVmSharedShmPrefix : "/"; + return EmitWithPrefix(prefix, [this, channel_type, instance_id](auto& out) noexcept { EmitControlFileName(out, channel_type, service_id_, instance_id); }); } @@ -127,7 +130,8 @@ std::string ShmPathBuilder::GetMethodChannelShmName( const LolaServiceInstanceId::InstanceId instance_id, const ProxyInstanceIdentifier& proxy_instance_identifier) const noexcept { - return EmitWithPrefix('/', [this, instance_id, proxy_instance_identifier](auto& out) noexcept { + const auto prefix = inter_vm_support_ ? kInterVmSharedShmPrefix : "/"; + return EmitWithPrefix(prefix, [this, instance_id, proxy_instance_identifier](auto& out) noexcept { EmitMethodFileName(out, service_id_, instance_id, proxy_instance_identifier); }); } diff --git a/score/mw/com/impl/bindings/lola/shm_path_builder.h b/score/mw/com/impl/bindings/lola/shm_path_builder.h index 8784ee623..3de263b49 100644 --- a/score/mw/com/impl/bindings/lola/shm_path_builder.h +++ b/score/mw/com/impl/bindings/lola/shm_path_builder.h @@ -29,7 +29,19 @@ namespace score::mw::com::impl::lola class ShmPathBuilder : public IShmPathBuilder { public: - explicit ShmPathBuilder(const std::uint16_t service_id) noexcept : IShmPathBuilder{}, service_id_{service_id} {} + /// \brief Constructs a ShmPathBuilder for the given service. + /// + /// \param service_id Numeric identifier of the LoLa service. + /// \param inter_vm_support When \c true, the prefix \c "/intervm-shared-shmem/" is prepended + /// to all generated SHM object path names. + /// \note This is an interim solution to express the intent to have a + /// shared-memory object that supports sharing across VMs by encoding it + /// into the path name. A future solution will be based on a redesigned + /// \c lib/memory/shared API abstraction. + explicit ShmPathBuilder(const std::uint16_t service_id, const bool inter_vm_support = false) noexcept + : IShmPathBuilder{}, service_id_{service_id}, inter_vm_support_{inter_vm_support} + { + } std::string GetDataChannelShmName(const LolaServiceInstanceId::InstanceId instance_id) const noexcept override; @@ -42,6 +54,7 @@ class ShmPathBuilder : public IShmPathBuilder private: const std::uint16_t service_id_; + const bool inter_vm_support_; }; } // namespace score::mw::com::impl::lola diff --git a/score/mw/com/impl/bindings/lola/shm_path_builder_test.cpp b/score/mw/com/impl/bindings/lola/shm_path_builder_test.cpp index ca1156bc6..b3fce629c 100644 --- a/score/mw/com/impl/bindings/lola/shm_path_builder_test.cpp +++ b/score/mw/com/impl/bindings/lola/shm_path_builder_test.cpp @@ -136,6 +136,62 @@ TEST_P(ShmPathBuilderMethodParamaterizedTestFixture, TestBuildingMethodChannelSh EXPECT_EQ(expected_path, actual_path); } +TEST(ShmPathBuilderInterVmSupportTest, BuildsDataChannelShmNamePathWithInterVmPrefix) +{ + constexpr LolaServiceInstanceId::InstanceId instance_id{1}; + + // Given a ShmPathBuilder with inter-vm support enabled + ShmPathBuilder builder{kServiceId, true}; + + // When creating the data channel shm name + const auto actual_path = builder.GetDataChannelShmName(instance_id); + + // Then the returned path should use the inter-vm prefix with standard padding + EXPECT_EQ("/intervm-shared-shmem/lola-data-0000000000004660-00001", actual_path); +} + +TEST(ShmPathBuilderInterVmSupportTest, BuildsControlChannelShmNamePathWithInterVmPrefix) +{ + constexpr LolaServiceInstanceId::InstanceId instance_id{1}; + + // Given a ShmPathBuilder with inter-vm support enabled + ShmPathBuilder builder{kServiceId, true}; + + // When creating the control channel shm name + const auto actual_path = builder.GetControlChannelShmName(instance_id, QualityType::kASIL_B); + + // Then the returned path should use the inter-vm prefix with standard padding + EXPECT_EQ("/intervm-shared-shmem/lola-ctl-0000000000004660-00001-b", actual_path); +} + +TEST(ShmPathBuilderInterVmSupportTest, BuildsMethodChannelShmNamePathWithInterVmPrefix) +{ + constexpr LolaServiceInstanceId::InstanceId instance_id{1}; + constexpr ProxyInstanceIdentifier proxy_instance_identifier{2U, 3U}; + + // Given a ShmPathBuilder with inter-vm support enabled + ShmPathBuilder builder{kServiceId, true}; + + // When creating the method channel shm name + const auto actual_path = builder.GetMethodChannelShmName(instance_id, proxy_instance_identifier); + + // Then the returned path should use the inter-vm prefix with standard padding + EXPECT_EQ("/intervm-shared-shmem/lola-methods-0000000000004660-00001-00002-00003", actual_path); +} + +TEST(ShmPathBuilderInterVmSupportDeathTests, GetControlChannelShmNameDiesWithInvalidQualityType) +{ + constexpr LolaServiceInstanceId::InstanceId instance_id{1}; + constexpr QualityType invalid_quality_type = QualityType::kInvalid; + + // Given a ShmPathBuilder with inter-vm support enabled + ShmPathBuilder builder{kServiceId, true}; + + // When creating the control channel shm name with an invalid quality type + // Then we expect it to die + EXPECT_DEATH(builder.GetControlChannelShmName(instance_id, invalid_quality_type), ""); +} + INSTANTIATE_TEST_SUITE_P( ShmPathBuilderMethodTests, ShmPathBuilderMethodParamaterizedTestFixture,