Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions score/mw/com/impl/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ cc_library(
"//score/mw/com:__subpackages__",
],
deps = [
":method_type",
":skeleton_event",
":skeleton_field_base",
"//score/mw/com/impl/methods:method_signature_element_ptr",
Expand Down Expand Up @@ -285,9 +286,11 @@ cc_library(
"//score/mw/com:__subpackages__",
],
deps = [
":method_type",
":proxy_event",
":proxy_event_binding",
":proxy_field_base",
"//score/mw/com/impl/methods:proxy_method",
"//score/mw/com/impl/mocking:i_proxy_event",
"//score/mw/com/impl/plumbing:field",
"@score_baselibs//score/language/futurecpp",
Expand Down Expand Up @@ -674,6 +677,16 @@ cc_library(
],
)

cc_library(
name = "method_type",
srcs = ["method_type.cpp"],
hdrs = ["method_type.h"],
features = COMPILER_WARNING_FEATURES,
tags = ["FFI"],
visibility = ["//score/mw/com:__subpackages__"],
deps = ["@score_baselibs//score/language/futurecpp"],
)

cc_library(
name = "service_element_type",
srcs = ["service_element_type.cpp"],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ constexpr gid_t kRemoteGid{40};

const ProxyInstanceIdentifier kProxyInstanceIdentifier{kLocalUid, 1U};

const ProxyMethodInstanceIdentifier kProxyMethodInstanceIdentifier{kProxyInstanceIdentifier, LolaMethodId{35U}};
const ProxyMethodInstanceIdentifier kProxyMethodInstanceIdentifier2{kProxyInstanceIdentifier, LolaMethodId{36U}};
const ProxyMethodInstanceIdentifier kProxyMethodInstanceIdentifier{kProxyInstanceIdentifier, {LolaMethodId{35U}}};
const ProxyMethodInstanceIdentifier kProxyMethodInstanceIdentifier2{kProxyInstanceIdentifier, {LolaMethodId{36U}}};

const SkeletonInstanceIdentifier kSkeletonInstanceIdentifier{LolaServiceId{12U},
LolaServiceInstanceId::InstanceId{22U}};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ namespace
using namespace ::testing;

const QualityType kAsilLevel{QualityType::kASIL_B};
const ProxyMethodInstanceIdentifier kProxyMethodInstanceIdentifier{{5U, 1U}, LolaMethodId{55U}};
const ProxyMethodInstanceIdentifier kProxyMethodInstanceIdentifier{{5U, 1U}, {LolaMethodId{55U}}};

class RegistrationGuardFixture : public ::testing::Test
{
Expand Down
26 changes: 25 additions & 1 deletion score/mw/com/impl/bindings/lola/methods/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ cc_library(
"//score/mw/com/impl/bindings/lola/messaging:__pkg__",
],
deps = [
":unique_method_identifier",
"//score/mw/com/impl/bindings/lola:proxy_instance_identifier",
"//score/mw/com/impl/configuration",
"@score_baselibs//score/mw/log",
],
)
Expand All @@ -45,6 +45,7 @@ cc_library(
visibility = ["//score/mw/com/impl/bindings/lola:__pkg__"],
deps = [
":type_erased_call_queue",
":unique_method_identifier",
"//score/mw/com/impl/configuration",
"@score_baselibs//score/containers:dynamic_array",
"@score_baselibs//score/language/futurecpp",
Expand Down Expand Up @@ -119,6 +120,28 @@ cc_library(
visibility = ["//score/mw/com/impl/bindings/lola:__pkg__"],
)

cc_library(
name = "unique_method_identifier",
srcs = ["unique_method_identifier.cpp"],
hdrs = ["unique_method_identifier.h"],
features = COMPILER_WARNING_FEATURES,
tags = ["FFI"],
visibility = ["//score/mw/com:__subpackages__"],
deps = [
"//score/mw/com/impl:method_type",
"//score/mw/com/impl/configuration:lola_field_id",
"//score/mw/com/impl/configuration:lola_method_id",
"//score/mw/com/impl/configuration:lola_method_or_field_id",
"@score_baselibs//score/mw/log",
],
)

cc_gtest_unit_test(
name = "unique_method_identifier_test",
srcs = ["unique_method_identifier_test.cpp"],
deps = [":unique_method_identifier"],
)

cc_unit_test(
name = "type_erased_call_queue_test",
srcs = [
Expand Down Expand Up @@ -211,6 +234,7 @@ cc_unit_test_suites_for_host_and_qnx(
name = "unit_test_suite",
cc_unit_tests = [
":proxy_method_instance_identifier_test",
":unique_method_identifier_test",
":type_erased_call_queue_test",
":method_data_test",
":method_error_test",
Expand Down
6 changes: 3 additions & 3 deletions score/mw/com/impl/bindings/lola/methods/method_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#define SCORE_MW_COM_IMPL_BINDINGS_LOLA_METHODS_METHOD_DATA_H

#include "score/mw/com/impl/bindings/lola/methods/type_erased_call_queue.h"
#include "score/mw/com/impl/configuration/lola_method_id.h"
#include "score/mw/com/impl/bindings/lola/methods/unique_method_identifier.h"

#include "score/containers/non_relocatable_vector.h"
#include "score/memory/shared/managed_memory_resource.h"
Expand All @@ -40,9 +40,9 @@ class MethodData
// be private.". There are no class invariants to maintain which could be violated by directly accessing member
// variables.
// coverity[autosar_cpp14_m11_0_1_violation]
containers::NonRelocatableVector<std::pair<LolaMethodId, TypeErasedCallQueue>,
containers::NonRelocatableVector<std::pair<UniqueMethodIdentifier, TypeErasedCallQueue>,
std::scoped_allocator_adaptor<memory::shared::PolymorphicOffsetPtrAllocator<
std::pair<LolaMethodId, TypeErasedCallQueue>>>>
std::pair<UniqueMethodIdentifier, TypeErasedCallQueue>>>>
method_call_queues_;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ namespace score::mw::com::impl::lola

bool operator==(const ProxyMethodInstanceIdentifier& lhs, const ProxyMethodInstanceIdentifier& rhs) noexcept
{
return ((lhs.proxy_instance_identifier == rhs.proxy_instance_identifier) && (lhs.method_id == rhs.method_id));
return ((lhs.proxy_instance_identifier == rhs.proxy_instance_identifier) &&
(lhs.unique_method_identifier == rhs.unique_method_identifier));
}

mw::log::LogStream& operator<<(score::mw::log::LogStream& stream, const ProxyMethodInstanceIdentifier& value) noexcept
{
stream << "ProxyInstanceIdentifier:" << value.proxy_instance_identifier << ". Method ID:" << value.method_id;
stream << "ProxyInstanceIdentifier:" << value.proxy_instance_identifier
<< ". UniqueMethodIdentifier:" << value.unique_method_identifier;
return stream;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
#ifndef SCORE_MW_COM_IMPL_BINDINGS_LOLA_METHODS_PROXY_METHOD_INSTANCE_IDENTIFIER_H
#define SCORE_MW_COM_IMPL_BINDINGS_LOLA_METHODS_PROXY_METHOD_INSTANCE_IDENTIFIER_H

#include "score/mw/com/impl/bindings/lola/methods/unique_method_identifier.h"
#include "score/mw/com/impl/bindings/lola/proxy_instance_identifier.h"
#include "score/mw/com/impl/configuration/lola_method_id.h"

#include "score/mw/log/logging.h"

Expand All @@ -30,7 +30,7 @@ namespace score::mw::com::impl::lola
struct ProxyMethodInstanceIdentifier
{
ProxyInstanceIdentifier proxy_instance_identifier;
LolaMethodId method_id;
UniqueMethodIdentifier unique_method_identifier;
};

bool operator==(const ProxyMethodInstanceIdentifier& lhs, const ProxyMethodInstanceIdentifier& rhs) noexcept;
Expand All @@ -49,23 +49,20 @@ class hash<score::mw::com::impl::lola::ProxyMethodInstanceIdentifier>
std::size_t operator()(const score::mw::com::impl::lola::ProxyMethodInstanceIdentifier&
proxy_method_instance_identifier) const noexcept
{
using ProxyMethodInstanceIdentifier = score::mw::com::impl::lola::ProxyMethodInstanceIdentifier;
using UniqueMethodIdentifier = score::mw::com::impl::lola::UniqueMethodIdentifier;
using ProxyInstanceIdentifier = score::mw::com::impl::lola::ProxyInstanceIdentifier;
static_assert((sizeof(ProxyInstanceIdentifier::application_id) +
sizeof(ProxyInstanceIdentifier::proxy_instance_counter) +
sizeof(ProxyMethodInstanceIdentifier::method_id)) <= sizeof(std::uint64_t));

constexpr auto proxy_instance_counter_bit_width = std::numeric_limits<
decltype(proxy_method_instance_identifier.proxy_instance_identifier.proxy_instance_counter)>::digits;
constexpr auto method_id_bit_width =
std::numeric_limits<decltype(proxy_method_instance_identifier.method_id)>::digits;
return std::hash<std::uint64_t>{}(
(static_cast<std::uint64_t>(proxy_method_instance_identifier.proxy_instance_identifier.application_id)
<< (proxy_instance_counter_bit_width + method_id_bit_width)) |
(static_cast<std::uint64_t>(
proxy_method_instance_identifier.proxy_instance_identifier.proxy_instance_counter)
<< method_id_bit_width) |
static_cast<std::uint64_t>(proxy_method_instance_identifier.method_id));
static constexpr std::size_t kGoldenRatioConstant = 0x9e3779b9U;
static constexpr unsigned int kLeftShiftBits = 6U;
static constexpr unsigned int kRightShiftBits = 2U;

// The previous implementation packed all fields into a single uint64_t, but with the addition of
// MethodType to UniqueMethodIdentifier, the total bit width (72 bits) exceeds 64 bits.
// We now combine the hashes of the sub-structs instead using the boost hash_combine pattern.
auto seed = std::hash<ProxyInstanceIdentifier>{}(proxy_method_instance_identifier.proxy_instance_identifier);
seed ^= std::hash<UniqueMethodIdentifier>{}(proxy_method_instance_identifier.unique_method_identifier) +
kGoldenRatioConstant + (seed << kLeftShiftBits) + (seed >> kRightShiftBits);
return seed;
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#include "score/mw/com/impl/bindings/lola/methods/proxy_method_instance_identifier.h"

#include "score/mw/com/impl/configuration/global_configuration.h"
#include "score/mw/com/impl/configuration/lola_method_id.h"
#include "score/mw/com/impl/configuration/lola_method_or_field_id.h"

#include "score/mw/log/logging.h"

Expand All @@ -30,13 +30,16 @@ namespace

constexpr GlobalConfiguration::ApplicationId kDummyProcessIdentifier{10U};
constexpr ProxyInstanceIdentifier::ProxyInstanceCounter kDummyProxyInstanceCounter{15U};
constexpr LolaMethodId kDummyMethodId{20U};
constexpr LolaMethodOrFieldId kDummyMethodOrFieldId{20U};
const UniqueMethodIdentifier kDummyUniqueMethodIdentifier{kDummyMethodOrFieldId, MethodType::kMethod};

TEST(ProxyMethodInstanceIdentifierTest, EqualObjectsReturnTheSameHash)
{
// Given two ProxyMethodInstanceIdentifier objects containing the same values
const ProxyMethodInstanceIdentifier unit_0{{kDummyProcessIdentifier, kDummyProxyInstanceCounter}, kDummyMethodId};
const ProxyMethodInstanceIdentifier unit_1{{kDummyProcessIdentifier, kDummyProxyInstanceCounter}, kDummyMethodId};
const ProxyMethodInstanceIdentifier unit_0{{kDummyProcessIdentifier, kDummyProxyInstanceCounter},
kDummyUniqueMethodIdentifier};
const ProxyMethodInstanceIdentifier unit_1{{kDummyProcessIdentifier, kDummyProxyInstanceCounter},
kDummyUniqueMethodIdentifier};

// When hashing the two objects
auto hash_result0 = std::hash<ProxyMethodInstanceIdentifier>{}(unit_0);
Expand All @@ -52,11 +55,11 @@ TEST(ProxyMethodInstanceIdentifierTest, EqualObjectsWithMaxValuesReturnTheSameHa
const ProxyMethodInstanceIdentifier unit_0{
{std::numeric_limits<GlobalConfiguration::ApplicationId>::max(),
std::numeric_limits<ProxyInstanceIdentifier::ProxyInstanceCounter>::max()},
std::numeric_limits<LolaMethodId>::max()};
{std::numeric_limits<LolaMethodOrFieldId>::max(), MethodType::kSet}};
const ProxyMethodInstanceIdentifier unit_1{
{std::numeric_limits<GlobalConfiguration::ApplicationId>::max(),
std::numeric_limits<ProxyInstanceIdentifier::ProxyInstanceCounter>::max()},
std::numeric_limits<LolaMethodId>::max()};
{std::numeric_limits<LolaMethodOrFieldId>::max(), MethodType::kSet}};

// When hashing the two objects
auto hash_result0 = std::hash<ProxyMethodInstanceIdentifier>{}(unit_0);
Expand All @@ -69,9 +72,10 @@ TEST(ProxyMethodInstanceIdentifierTest, EqualObjectsWithMaxValuesReturnTheSameHa
TEST(ProxyMethodInstanceIdentifierTest, ObjectsWithDifferentProcessIdentifierReturnsDifferentHash)
{
// Given two ProxyMethodInstanceIdentifier objects containing different process identifiers
const ProxyMethodInstanceIdentifier unit_0{{kDummyProcessIdentifier, kDummyProxyInstanceCounter}, kDummyMethodId};
const ProxyMethodInstanceIdentifier unit_0{{kDummyProcessIdentifier, kDummyProxyInstanceCounter},
kDummyUniqueMethodIdentifier};
const ProxyMethodInstanceIdentifier unit_1{{kDummyProcessIdentifier + 1U, kDummyProxyInstanceCounter},
kDummyMethodId};
kDummyUniqueMethodIdentifier};

// When hashing the two objects
auto hash_result0 = std::hash<ProxyMethodInstanceIdentifier>{}(unit_0);
Expand All @@ -85,8 +89,9 @@ TEST(ProxyMethodInstanceIdentifierTest, ObjectsWithDifferentProxyInstanceCounter
{
// Given two ProxyMethodInstanceIdentifier objects containing different proxy instance counters
const ProxyMethodInstanceIdentifier unit_0{{kDummyProcessIdentifier, kDummyProxyInstanceCounter + 1U},
kDummyMethodId};
const ProxyMethodInstanceIdentifier unit_1{{kDummyProcessIdentifier, kDummyProxyInstanceCounter}, kDummyMethodId};
kDummyUniqueMethodIdentifier};
const ProxyMethodInstanceIdentifier unit_1{{kDummyProcessIdentifier, kDummyProxyInstanceCounter},
kDummyUniqueMethodIdentifier};

// When hashing the two objects
auto hash_result0 = std::hash<ProxyMethodInstanceIdentifier>{}(unit_0);
Expand All @@ -99,9 +104,10 @@ TEST(ProxyMethodInstanceIdentifierTest, ObjectsWithDifferentProxyInstanceCounter
TEST(ProxyMethodInstanceIdentifierTest, ObjectsWithDifferentMethodIdsReturnsDifferentHash)
{
// Given two ProxyMethodInstanceIdentifier objects containing different method ids
const ProxyMethodInstanceIdentifier unit_0{{kDummyProcessIdentifier, kDummyProxyInstanceCounter}, kDummyMethodId};
const ProxyMethodInstanceIdentifier unit_0{{kDummyProcessIdentifier, kDummyProxyInstanceCounter},
kDummyUniqueMethodIdentifier};
const ProxyMethodInstanceIdentifier unit_1{{kDummyProcessIdentifier, kDummyProxyInstanceCounter},
kDummyMethodId + 1U};
{kDummyMethodOrFieldId + 1U, MethodType::kMethod}};

// When hashing the two objects
auto hash_result0 = std::hash<ProxyMethodInstanceIdentifier>{}(unit_0);
Expand All @@ -116,9 +122,10 @@ TEST(ProxyMethodInstanceIdentifierTest,
{
// Given two ProxyMethodInstanceIdentifier objects containing different process identifiers, proxy instance
// counters and method IDs
const ProxyMethodInstanceIdentifier unit_0{{kDummyProcessIdentifier, kDummyProxyInstanceCounter}, kDummyMethodId};
const ProxyMethodInstanceIdentifier unit_0{{kDummyProcessIdentifier, kDummyProxyInstanceCounter},
kDummyUniqueMethodIdentifier};
const ProxyMethodInstanceIdentifier unit_1{{kDummyProcessIdentifier + 1U, kDummyProxyInstanceCounter + 1U},
kDummyMethodId + 1U};
{kDummyMethodOrFieldId + 1U, MethodType::kMethod}};

// When hashing the two objects
auto hash_result0 = std::hash<ProxyMethodInstanceIdentifier>{}(unit_0);
Expand All @@ -131,7 +138,8 @@ TEST(ProxyMethodInstanceIdentifierTest,
TEST(ProxyMethodInstanceIdentifierTest, OperatorStreamOutputsExpectedString)
{
// Given a ProxyMethodInstanceIdentifier
const ProxyMethodInstanceIdentifier unit{{kDummyProcessIdentifier, kDummyProxyInstanceCounter}, kDummyMethodId};
const ProxyMethodInstanceIdentifier unit{{kDummyProcessIdentifier, kDummyProxyInstanceCounter},
kDummyUniqueMethodIdentifier};
testing::internal::CaptureStdout();

// When streaming the ProxyMethodInstanceIdentifier to a log
Expand All @@ -140,8 +148,8 @@ TEST(ProxyMethodInstanceIdentifierTest, OperatorStreamOutputsExpectedString)

// Then the output should contain the expected string
EXPECT_THAT(output,
::testing::HasSubstr(
"ProxyInstanceIdentifier: Application ID: 10 . Proxy Instance Counter: 15 . Method ID: 20"));
::testing::HasSubstr("ProxyInstanceIdentifier: Application ID: 10 . Proxy Instance Counter: 15 "
". UniqueMethodIdentifier: MethodOrFieldId: 20 . MethodType: Method"));
}

} // namespace
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/********************************************************************************
* 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
********************************************************************************/
#include "score/mw/com/impl/bindings/lola/methods/unique_method_identifier.h"

namespace score::mw::com::impl::lola
{

bool operator==(const UniqueMethodIdentifier& lhs, const UniqueMethodIdentifier& rhs) noexcept
{
return ((lhs.method_or_field_id == rhs.method_or_field_id) && (lhs.method_type == rhs.method_type));
}

bool operator!=(const UniqueMethodIdentifier& lhs, const UniqueMethodIdentifier& rhs) noexcept
{
return !(lhs == rhs);
}

mw::log::LogStream& operator<<(score::mw::log::LogStream& stream, const UniqueMethodIdentifier& value) noexcept
{
stream << "MethodOrFieldId:" << value.method_or_field_id << ". MethodType:" << to_string(value.method_type);
return stream;
}

} // namespace score::mw::com::impl::lola
Loading
Loading