Skip to content
Draft
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
8 changes: 4 additions & 4 deletions SilKit/IntegrationTests/ITest_MessageAggregation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ TEST_F(ITest_MessageAggregation, timeout_in_case_of_deadlock_when_using_async_si
SilKit::Services::PubSub::PubSubSpec dataSpecPing{"ping", {}};
SilKit::Services::PubSub::PubSubSpec dataSpecPong{"pong", {}};

bool msgReceived{false};
std::atomic_bool msgReceived{false};

// participant with async simulation step handler & enabled message aggregation
{
Expand All @@ -105,8 +105,8 @@ TEST_F(ITest_MessageAggregation, timeout_in_case_of_deadlock_when_using_async_si
});

timeSyncService->SetSimulationStepHandlerAsync(
[dataPublisher, lifecycleService, &msgReceived](std::chrono::nanoseconds /*now*/,
std::chrono::nanoseconds /*duration*/) {
[dataPublisher, lifecycleService, &msgReceived](std::chrono::nanoseconds,
std::chrono::nanoseconds) {
// send ping
std::vector<uint8_t> ping(1, '?');
dataPublisher->Publish(std::move(ping));
Expand Down Expand Up @@ -135,7 +135,7 @@ TEST_F(ITest_MessageAggregation, timeout_in_case_of_deadlock_when_using_async_si
});

timeSyncService->SetSimulationStepHandlerAsync(
[timeSyncService](std::chrono::nanoseconds /*now*/, std::chrono::nanoseconds /*duration*/) {
[timeSyncService](std::chrono::nanoseconds, std::chrono::nanoseconds) {
timeSyncService->CompleteSimulationStep();
}, 1s);
}
Expand Down
23 changes: 17 additions & 6 deletions SilKit/IntegrationTests/ITest_NetSimFlexRay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// SPDX-License-Identifier: MIT

#include "ITest_NetSim.hpp"
#include "ITestThreadSafeLogger.hpp"
#include "silkit/services/flexray/all.hpp"

namespace {
Expand All @@ -23,8 +24,9 @@ struct ITest_NetSimFlexray : ITest_NetSim
CallCountsSilKitHandlersFlexray& callCountsSilKitHandlersFlexray)
{
controller->AddCycleStartHandler(
[&callCountsSilKitHandlersFlexray](IFlexrayController*, const FlexrayCycleStartEvent& /*msg*/) {
[&callCountsSilKitHandlersFlexray](IFlexrayController*, const FlexrayCycleStartEvent& msg) {
callCountsSilKitHandlersFlexray.CycleStartHandler++;
Log() << "Cycle Start: " << (int)msg.cycleCounter << " timestamp: " << msg.timestamp;
});
controller->AddFrameHandler(
[&callCountsSilKitHandlersFlexray](IFlexrayController*, const FlexrayFrameEvent& /*msg*/) {
Expand Down Expand Up @@ -273,13 +275,20 @@ void MySimulatedFlexrayController::OnTxBufferUpdate(

TEST_F(ITest_NetSimFlexray, basic_networksimulation_flexray)
{
const auto configSynchronizationPoints = R"(
Logging:
Sinks:
- Type: Stdout
Level: Info
EnableSynchronizationPoints: true
)";
{
// ----------------------------
// NetworkSimulator
// ----------------------------

//auto configWithLogging = MakeParticipantConfigurationStringWithLogging(SilKit::Services::Logging::Level::Info);
auto&& simParticipant = _simTestHarness->GetParticipant(_participantNameNetSim);
auto&& simParticipant = _simTestHarness->GetParticipant(_participantNameNetSim, configSynchronizationPoints);
auto&& lifecycleService = simParticipant->GetOrCreateLifecycleService();
auto&& timeSyncService = simParticipant->GetOrCreateTimeSyncService();
auto&& networkSimulator = simParticipant->GetOrCreateNetworkSimulator();
Expand Down Expand Up @@ -307,7 +316,8 @@ TEST_F(ITest_NetSimFlexray, basic_networksimulation_flexray)

timeSyncService->SetSimulationStepHandler(
[this, simulatedNetworkPtr, lifecycleService, flexrayController](
auto now, const std::chrono::nanoseconds /*duration*/) {
auto now, const std::chrono::nanoseconds duration) {
(void)duration;
if (now == _stopAtMs)
{
lifecycleService->Stop("stopping the simulation");
Expand All @@ -328,7 +338,7 @@ TEST_F(ITest_NetSimFlexray, basic_networksimulation_flexray)

for (const auto& participantName : _participantNamesSimulated)
{
auto&& simParticipant = _simTestHarness->GetParticipant(participantName);
auto&& simParticipant = _simTestHarness->GetParticipant(participantName, configSynchronizationPoints);
auto&& lifecycleService = simParticipant->GetOrCreateLifecycleService();
auto&& timeSyncService = simParticipant->GetOrCreateTimeSyncService();

Expand All @@ -337,8 +347,9 @@ TEST_F(ITest_NetSimFlexray, basic_networksimulation_flexray)
SetupFlexrayController(lifecycleService, flexrayController, callCounts.silKitHandlersFlexray);

timeSyncService->SetSimulationStepHandler(
[this, flexrayController](auto now, const std::chrono::nanoseconds /*duration*/) {
[this, flexrayController](auto now, const std::chrono::nanoseconds duration) {
OnetimeActions(now, flexrayController);
Log() << "Simulation step: " << now.count() << " : " << duration.count();
}, _stepSize);
}
}
Expand All @@ -358,7 +369,7 @@ TEST_F(ITest_NetSimFlexray, basic_networksimulation_flexray)
}
}

auto ok = _simTestHarness->Run(5s);
auto ok = _simTestHarness->Run(500s);
ASSERT_TRUE(ok) << "SimTestHarness should terminate without timeout";

const size_t numSimulatedFlexrayControllers =
Expand Down
2 changes: 2 additions & 0 deletions SilKit/source/config/ParticipantConfiguration.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,8 @@ struct ParticipantConfiguration : public IParticipantConfiguration
Includes includes;
Middleware middleware;
Experimental experimental;
// experimental synchronization points
bool enableSynchronizationPoints{false};
};

bool operator==(const CanController& lhs, const CanController& rhs);
Expand Down
5 changes: 5 additions & 0 deletions SilKit/source/config/ParticipantConfigurationFromXImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ struct ConfigIncludeData
std::map<std::string, SilKit::Config::RpcClient> rpcClientCache;
std::map<std::string, SilKit::Config::TraceSink> traceSinkCache;
std::map<std::string, SilKit::Config::TraceSource> traceSourceCache;
bool enableSynchronizationPoints;
};


Expand Down Expand Up @@ -550,6 +551,8 @@ void MergeExperimentalCache(const ExperimentalCache& cache, Experimental& experi
auto MergeConfigs(ConfigIncludeData& configIncludeData) -> SilKit::Config::ParticipantConfiguration
{
SilKit::Config::ParticipantConfiguration config;
config.enableSynchronizationPoints = configIncludeData.enableSynchronizationPoints;

for (const auto& include : configIncludeData.configBuffer)
{
// Merge all vectors first!
Expand Down Expand Up @@ -666,6 +669,8 @@ auto PaticipantConfigurationWithIncludes(const std::string& text, struct ConfigI
throw SilKit::ConfigurationError{fmt::format("Unknown schema version '{}' found in participant configuration!",
configuration.schemaVersion)};
}
configData.enableSynchronizationPoints = configuration.enableSynchronizationPoints;

configData.configBuffer.push_back(ConfigInclude("root", configuration));

AppendToSearchPaths(configuration, configData);
Expand Down
3 changes: 3 additions & 0 deletions SilKit/source/config/YamlReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,9 @@ void YamlReader::Read(SilKit::Config::ParticipantConfiguration& obj)
OptionalRead(obj.middleware, "Middleware");
OptionalRead(obj.includes, "Includes");
OptionalRead(obj.experimental, "Experimental");

// design proposal
OptionalRead(obj.enableSynchronizationPoints, "EnableSynchronizationPoints");
}

void YamlReader::Read(SilKit::Config::HealthCheck& obj)
Expand Down
3 changes: 3 additions & 0 deletions SilKit/source/config/YamlWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,9 @@ void YamlWriter::Write(const SilKit::Config::ParticipantConfiguration& obj)
NonDefaultWrite(obj.middleware, "Middleware", defaultObj.middleware);
NonDefaultWrite(obj.includes, "Includes", defaultObj.includes);
NonDefaultWrite(obj.experimental, "Experimental", defaultObj.experimental);

//design proposal
NonDefaultWrite(obj.enableSynchronizationPoints, "EnableSynchronizationPoints", defaultObj.enableSynchronizationPoints);
}

void YamlWriter::Write(const SilKit::Config::HealthCheck& obj)
Expand Down
2 changes: 2 additions & 0 deletions SilKit/source/core/internal/IParticipantInternal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,8 @@ class IParticipantInternal : public IParticipant

virtual auto GetMetricsProcessor() -> IMetricsProcessor* = 0;
virtual auto GetMetricsSender() -> IMetricsSender* = 0;

virtual auto GetConfiguration() -> const Config::ParticipantConfiguration& = 0;
};

} // namespace Core
Expand Down
14 changes: 14 additions & 0 deletions SilKit/source/core/internal/OrchestrationDatatypes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,26 @@ namespace SilKit {
namespace Services {
namespace Orchestration {

enum class SynchronizationKind: uint8_t
{
None = 0,
RequestSynchronization = 1,
AcknowledgeSynchronization = 2,
};

struct NextSimTask
{
std::chrono::nanoseconds timePoint{0};
std::chrono::nanoseconds duration{0};
SynchronizationKind synchronizationKind{SynchronizationKind::None};
uint64_t serialNumber{0};
};

inline auto operator==(const NextSimTask& lhs, const NextSimTask& rhs)
{
return lhs.duration == rhs.duration && lhs.timePoint == rhs.timePoint;
}

//! System-wide command for the simulation flow.
struct SystemCommand
{
Expand Down
18 changes: 17 additions & 1 deletion SilKit/source/core/internal/string_utils_sync.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ namespace Services {
namespace Orchestration {

inline std::string to_string(const NextSimTask& nextTask);
inline std::string to_string(SynchronizationKind kind);
inline std::string to_string(SystemCommand::Kind command);
inline std::string to_string(const SystemCommand& command);

Expand All @@ -31,11 +32,26 @@ std::string to_string(const NextSimTask& nextTask)
return outStream.str();
}

std::string to_string(SynchronizationKind kind)
{
switch (kind)
{
case SynchronizationKind::None:
return "None";
case SynchronizationKind::RequestSynchronization:
return "RequestSynchronization";
case SynchronizationKind::AcknowledgeSynchronization:
return "AcknowledgeSynchronization";
default:
return {};
}
}
std::ostream& operator<<(std::ostream& out, const NextSimTask& nextTask)
{
auto tp = std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(nextTask.timePoint);
auto duration = std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(nextTask.duration);
out << "Orchestration::NextSimTask{tp=" << tp.count() << "ms, duration=" << duration.count() << "ms}";
out << "NextSimTask{tp=" << tp.count() << "ms, duration=" << duration.count()
<< "ms, serial=" << nextTask.serialNumber << ", kind=" << to_string(nextTask.synchronizationKind) << "}";
return out;
}

Expand Down
26 changes: 26 additions & 0 deletions SilKit/source/core/internal/traits/SilKitMsgTraits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ namespace Core {
// ==================================================================
// Trait which checks that '.timestamp' works
// ==================================================================
template<class T>
using RemoveCvRef = std::remove_cv_t<std::remove_reference_t<T>>;

template <typename T, typename = void>
struct HasTimestamp : std::false_type
Expand Down Expand Up @@ -58,6 +60,15 @@ struct SilKitMsgTraitForbidSelfDelivery
}
};

template <class MsgT>
struct SilKitMsgTraitIsSynchronizationPoint
{
static constexpr bool IsSynchronizationPoint()
{
return false;
}
};

// The final message traits
template <class MsgT>
struct SilKitMsgTraits
Expand All @@ -67,6 +78,7 @@ struct SilKitMsgTraits
, SilKitMsgTraitVersion<MsgT>
, SilKitMsgTraitSerdesName<MsgT>
, SilKitMsgTraitForbidSelfDelivery<MsgT>
, SilKitMsgTraitIsSynchronizationPoint<MsgT>
{
};

Expand Down Expand Up @@ -110,6 +122,16 @@ struct SilKitMsgTraits
} \
}

#define DefineSilKitMsgTrait_IsSynchronizationPoint(Namespace, MsgName) \
template <> \
struct SilKitMsgTraitIsSynchronizationPoint<Namespace::MsgName> \
{ \
static constexpr bool IsSynchronizationPoint() \
{ \
return true; \
} \
}

DefineSilKitMsgTrait_TypeName(SilKit::Services::Logging, LogMsg);
DefineSilKitMsgTrait_TypeName(VSilKit, MetricsUpdate);
DefineSilKitMsgTrait_TypeName(SilKit::Services::Orchestration, SystemCommand);
Expand Down Expand Up @@ -164,5 +186,9 @@ DefineSilKitMsgTrait_EnforceSelfDelivery(SilKit::Services::Lin, LinSendFrameHead
// Messages with forbidden self delivery
DefineSilKitMsgTrait_ForbidSelfDelivery(SilKit::Services::Orchestration, SystemCommand);

// Messages which are Synchronization Points
DefineSilKitMsgTrait_IsSynchronizationPoint(SilKit::Services::Flexray, FlexrayCycleStartEvent);
DefineSilKitMsgTrait_IsSynchronizationPoint(SilKit::Services::PubSub, WireDataMessageEvent); //for testing

} // namespace Core
} // namespace SilKit
7 changes: 6 additions & 1 deletion SilKit/source/core/mock/participant/MockParticipant.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,14 +242,15 @@ class DummyMetricsManager : public IMetricsManager
std::unordered_map<std::string, DummyAttributeMetric> _attributes;
};

class DummyParticipant : public IParticipantInternal
class DummyParticipant: public IParticipantInternal
{
public:
DummyParticipant()
{
ON_CALL(mockLifecycleService, GetTimeSyncService).WillByDefault(testing::Return(&mockTimeSyncService));
ON_CALL(mockLifecycleService, CreateTimeSyncService).WillByDefault(testing::Return(&mockTimeSyncService));
ON_CALL(logger, GetLogLevel()).WillByDefault(testing::Return(Services::Logging::Level::Debug));
ON_CALL(*this, GetConfiguration()).WillByDefault(testing::ReturnRef(_participantConfiguration));
}

auto CreateCanController(const std::string& /*canonicalName*/,
Expand Down Expand Up @@ -720,6 +721,8 @@ class DummyParticipant : public IParticipantInternal
return nullptr;
}

MOCK_METHOD(const Config::ParticipantConfiguration&, GetConfiguration, (), (override));

const std::string _name = "MockParticipant";
const std::string _registryUri = "silkit://mock.participant.silkit:0";
testing::NiceMock<MockLogger> logger;
Expand All @@ -733,6 +736,8 @@ class DummyParticipant : public IParticipantInternal
MockParticipantReplies mockParticipantReplies;
DummyNetworkSimulator mockNetworkSimulator;
DummyMetricsManager mockMetricsManager;
Config::ParticipantConfiguration _participantConfiguration;

};

// ================================================================================
Expand Down
7 changes: 6 additions & 1 deletion SilKit/source/core/participant/Participant.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ namespace SilKit {
namespace Core {

template <class SilKitConnectionT>
class Participant final : public IParticipantInternal
class Participant final: public IParticipantInternal
{
public:
// ----------------------------------------
Expand Down Expand Up @@ -440,6 +440,11 @@ class Participant final : public IParticipantInternal

auto MakeTimerThread() -> std::unique_ptr<IMetricsTimerThread>;

auto GetConfiguration() -> const Config::ParticipantConfiguration& override;

template<typename MessageT>
void HandleSynchronizationPoint(const IServiceEndpoint* service);

private:
// ----------------------------------------
// private members
Expand Down
Loading
Loading